From 8c1ff478bebcd04319bce051fdb041d90320a2d9 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 20 Jun 2025 15:53:47 +0200 Subject: [PATCH 001/601] Start covariant derivatives --- .../VectorBundle/CovariantDerivative.lean | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean new file mode 100644 index 00000000000000..97c3895ffb77e5 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -0,0 +1,65 @@ +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +import Mathlib.Geometry.Manifold.VectorBundle.Tangent + +open Bundle Filter Function + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + + +section + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 2 M] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] + -- `V` vector bundle + + +def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 := sorry + +variable (x : M) +-- set_option diagnostics true +-- set_option trace.Meta.synthInstance.instances true in +-- #synth AddCommMonoid (V x →L[𝕜] V x) + +structure CovariantDerivative where + toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) + addX : ∀ (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x), + toFun (X + X') σ = toFun X σ + toFun X' σ + smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜), + toFun (f • X) σ = f • toFun X σ + addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x)(x : M), + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x + → MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x + → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x + -- smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), + -- toFun X (a • σ) = a • toFun X σ + leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), + MDifferentiableAt I I.tangent (fun x ↦ (X x : TangentBundle I M)) x + → MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x + → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x + → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜, 𝕜) f x (X x)) • σ x + +end + + + + +section + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +-- def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (fun _ ↦ E') 𝓘(𝕜, E') + +end From f7441eefa3155181bb47817a4dd51c076b3636ce Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 16:09:34 +0200 Subject: [PATCH 002/601] Most of a corollary --- .../VectorBundle/CovariantDerivative.lean | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 97c3895ffb77e5..49be73b0172046 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -50,10 +50,37 @@ structure CovariantDerivative where → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜, 𝕜) f x (X x)) • σ x -end - - +lemma CovariantDerivative.smul_const_σ (cov : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : + cov.toFun X (a • σ) = a • cov.toFun X σ := by + ext x + by_cases hX : MDifferentiableAt I I.tangent (fun x ↦ (X x : TangentBundle I M)) x; swap + · -- missing axiom: if X is not differentiable, the covariant derivative is zero + have hσ₁ : cov.toFun X σ = 0 := sorry + have hσ₂ : cov.toFun X (a • σ) = 0 := sorry + simp [hσ₁, hσ₂] + -- Thus, we know `X` is differentiable. + by_cases hσ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x + · have hσ' : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • σ x)) x := + sorry + have : MDifferentiableAt I 𝓘(𝕜, 𝕜) (fun x ↦ a) x := + (contMDiff_const.mdifferentiable (n := 1) (by norm_num)).mdifferentiableAt + have aux := cov.leibniz X σ (fun _ ↦ a) x hX hσ this + convert aux + trans (a • cov.toFun X σ) x + 0 + · rw [add_zero] + congr + have : mfderiv I 𝓘(𝕜, 𝕜) (fun x ↦ a) x (X x) = 0 := sorry + rw [this] + simp + -- missing axiom: "if σ is not differentiable, the covariant derivative is zero" + have hσ₁ : cov.toFun X σ = 0 := sorry + have hσ' : ¬ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • σ x)) x := + sorry + have hσ₂ : cov.toFun X (a • σ) = 0 := sorry + simp [hσ₁, hσ₂] +end section From 627e18d451bc2f81397a95022a211ae821368abe Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 16:38:28 +0200 Subject: [PATCH 003/601] Progress --- .../VectorBundle/CovariantDerivative.lean | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 49be73b0172046..32a30863ecf225 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -87,6 +87,28 @@ section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] --- def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (fun _ ↦ E') 𝓘(𝕜, E') +instance : ChartedSpace E Unit := sorry + +instance : IsManifold 𝓘(𝕜, E) 2 Unit := sorry + +noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E + (fun (_ : Unit) ↦ E) /-(Bundle.Trivial Unit E')-/ where + toFun v σ := fun _x ↦ fderiv 𝕜 v _x _x + addX X X' σ := by + funext x' + -- seems actually missing: sum of two non-diff functions could be non-differentiable + have hX : DifferentiableAt 𝕜 X x' := sorry + have hX' : DifferentiableAt 𝕜 X' x' := sorry + simp [fderiv_add hX hX'] + smulX X σ c' := by + let c := c' Unit.unit + funext x' + by_cases hX : DifferentiableAt 𝕜 X x'; swap + · have : ¬DifferentiableAt 𝕜 (c' • X) x' := sorry -- lemma: scalar mult. preserves diff. + simp [fderiv_zero_of_not_differentiableAt this, fderiv_zero_of_not_differentiableAt hX] + have : fderiv 𝕜 (c • X) x' = c • fderiv 𝕜 X x' := fderiv_const_smul hX c + sorry -- mismatch c vs c' + addσ X σ σ' hX hσ hσ' := sorry + leibniz := sorry end From e2ce6ced5793ff5d7134b2e63ca6481d0c3277ae Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 17:26:00 +0200 Subject: [PATCH 004/601] Better --- .../VectorBundle/CovariantDerivative.lean | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 32a30863ecf225..94625f0434172d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -87,27 +87,28 @@ section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] -instance : ChartedSpace E Unit := sorry - -instance : IsManifold 𝓘(𝕜, E) 2 Unit := sorry - -noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E - (fun (_ : Unit) ↦ E) /-(Bundle.Trivial Unit E')-/ where - toFun v σ := fun _x ↦ fderiv 𝕜 v _x _x +noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' + (Bundle.Trivial E E') where + toFun v s := by + intro x + let D := fderiv 𝕜 s + let v' := v x + sorry -- apply D v' or so addX X X' σ := by + sorry /- funext x' -- seems actually missing: sum of two non-diff functions could be non-differentiable have hX : DifferentiableAt 𝕜 X x' := sorry have hX' : DifferentiableAt 𝕜 X' x' := sorry - simp [fderiv_add hX hX'] - smulX X σ c' := by - let c := c' Unit.unit + simp [fderiv_add hX hX'] -/ + smulX X σ c' := by sorry + /- let c := c' Unit.unit funext x' by_cases hX : DifferentiableAt 𝕜 X x'; swap · have : ¬DifferentiableAt 𝕜 (c' • X) x' := sorry -- lemma: scalar mult. preserves diff. simp [fderiv_zero_of_not_differentiableAt this, fderiv_zero_of_not_differentiableAt hX] have : fderiv 𝕜 (c • X) x' = c • fderiv 𝕜 X x' := fderiv_const_smul hX c - sorry -- mismatch c vs c' + sorry -- mismatch c vs c' -/ addσ X σ σ' hX hσ hσ' := sorry leibniz := sorry From 47d346898d3eeba3dcb85073cefa43ab35aa102a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 17:30:03 +0200 Subject: [PATCH 005/601] wip --- .../Manifold/VectorBundle/CovariantDerivative.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 94625f0434172d..c2e6f75d1b26c7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -89,11 +89,10 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where - toFun v s := by + toFun X s := by intro x - let D := fderiv 𝕜 s - let v' := v x - sorry -- apply D v' or so + let res := fderiv 𝕜 s (X x) + convert res addX X X' σ := by sorry /- funext x' From 76d3d542a269670c8c4a9e924bf8f0227ea0e5a4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 17:32:07 +0200 Subject: [PATCH 006/601] toFun --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c2e6f75d1b26c7..b7f54541411e00 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -89,10 +89,7 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where - toFun X s := by - intro x - let res := fderiv 𝕜 s (X x) - convert res + toFun X s := fun x ↦ fderiv 𝕜 s (X x) x addX X X' σ := by sorry /- funext x' From 3e6280f8b45da88746ca31b7d733df3fc4f3cf68 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 20 Jun 2025 18:02:37 +0200 Subject: [PATCH 007/601] Progress on trivial covariant derivative --- .../VectorBundle/CovariantDerivative.lean | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index b7f54541411e00..de687d84f1c4ca 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1,5 +1,6 @@ import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.VectorBundle.Tangent +import Mathlib.Geometry.Manifold.MFDeriv.FDeriv open Bundle Filter Function @@ -50,6 +51,8 @@ structure CovariantDerivative where → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜, 𝕜) f x (X x)) • σ x + + lemma CovariantDerivative.smul_const_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : cov.toFun X (a • σ) = a • cov.toFun X σ := by @@ -87,9 +90,14 @@ section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] +theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : + MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ + DifferentiableAt 𝕜 σ e := by + sorry + noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where - toFun X s := fun x ↦ fderiv 𝕜 s (X x) x + toFun X s := fun x ↦ fderiv 𝕜 s x (X x) addX X X' σ := by sorry /- funext x' @@ -97,15 +105,11 @@ noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, have hX : DifferentiableAt 𝕜 X x' := sorry have hX' : DifferentiableAt 𝕜 X' x' := sorry simp [fderiv_add hX hX'] -/ - smulX X σ c' := by sorry - /- let c := c' Unit.unit - funext x' - by_cases hX : DifferentiableAt 𝕜 X x'; swap - · have : ¬DifferentiableAt 𝕜 (c' • X) x' := sorry -- lemma: scalar mult. preserves diff. - simp [fderiv_zero_of_not_differentiableAt this, fderiv_zero_of_not_differentiableAt hX] - have : fderiv 𝕜 (c • X) x' = c • fderiv 𝕜 X x' := fderiv_const_smul hX c - sorry -- mismatch c vs c' -/ - addσ X σ σ' hX hσ hσ' := sorry + smulX X σ c' := by ext ; simp + addσ X σ σ' e hσ hσ' := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' + rw [fderiv_add hσ hσ'] + rfl leibniz := sorry end From 1bb6a363edec3566c8ec2a93c3ae793e95966714 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 17:51:55 +0200 Subject: [PATCH 008/601] Done --- .../Manifold/VectorBundle/CovariantDerivative.lean | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index de687d84f1c4ca..c4ad73bda6696f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -28,6 +28,9 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 := sorry +lemma missing {f : E → 𝕜} {x : E} (Y : TangentSpace 𝓘(𝕜, E) x) : + bar (f x) ((fderiv 𝕜 f x) Y) = (fderiv 𝕜 f x) Y := sorry + variable (x : M) -- set_option diagnostics true -- set_option trace.Meta.synthInstance.instances true in @@ -98,14 +101,8 @@ theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) ( noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where toFun X s := fun x ↦ fderiv 𝕜 s x (X x) - addX X X' σ := by - sorry /- - funext x' - -- seems actually missing: sum of two non-diff functions could be non-differentiable - have hX : DifferentiableAt 𝕜 X x' := sorry - have hX' : DifferentiableAt 𝕜 X' x' := sorry - simp [fderiv_add hX hX'] -/ - smulX X σ c' := by ext ; simp + addX X X' σ := by ext; simp + smulX X σ c' := by ext; simp addσ X σ σ' e hσ hσ' := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' rw [fderiv_add hσ hσ'] From c6a0fa6fd617ddaea4700553986e63af5423fca6 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 20 Jun 2025 18:08:41 +0200 Subject: [PATCH 009/601] Define bar --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c4ad73bda6696f..ebb9ea9f46bd20 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -26,7 +26,11 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `V` vector bundle -def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 := sorry +def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 where + toFun v := v + invFun v := v + map_add' := by simp + map_smul' := by simp lemma missing {f : E → 𝕜} {x : E} (Y : TangentSpace 𝓘(𝕜, E) x) : bar (f x) ((fderiv 𝕜 f x) Y) = (fderiv 𝕜 f x) Y := sorry From df3d4494298a0b08f2e13dd8808b54aa2ae2593b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 18:10:54 +0200 Subject: [PATCH 010/601] Fix bad merge --- .../Manifold/VectorBundle/CovariantDerivative.lean | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ebb9ea9f46bd20..dce0b90589a5bf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -8,7 +8,6 @@ open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - section variable {E : Type*} [NormedAddCommGroup E] @@ -25,7 +24,6 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] -- `V` vector bundle - def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 where toFun v := v invFun v := v @@ -58,8 +56,6 @@ structure CovariantDerivative where → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜, 𝕜) f x (X x)) • σ x - - lemma CovariantDerivative.smul_const_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : cov.toFun X (a • σ) = a • cov.toFun X σ := by @@ -111,6 +107,14 @@ noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' rw [fderiv_add hσ hσ'] rfl - leibniz := sorry + leibniz := by + intro X σ f x hX hσ hf + have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := by + apply fderiv_smul + (by rwa [← mdifferentiableAt_iff_differentiableAt]) + (by rwa [Bundle.Trivial.mdifferentiableAt_iff] at hσ) + simp [this] + rw [← missing] + congr end From ea04b06d10ce72334d204fe5d9d98ece1cfe8856 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 20 Jun 2025 18:34:27 +0200 Subject: [PATCH 011/601] Progress --- .../VectorBundle/CovariantDerivative.lean | 63 +++++++------------ 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index dce0b90589a5bf..1409bd40fb52a6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1,6 +1,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions open Bundle Filter Function @@ -30,13 +31,7 @@ def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 where map_add' := by simp map_smul' := by simp -lemma missing {f : E → 𝕜} {x : E} (Y : TangentSpace 𝓘(𝕜, E) x) : - bar (f x) ((fderiv 𝕜 f x) Y) = (fderiv 𝕜 f x) Y := sorry - variable (x : M) --- set_option diagnostics true --- set_option trace.Meta.synthInstance.instances true in --- #synth AddCommMonoid (V x →L[𝕜] V x) structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) @@ -51,40 +46,25 @@ structure CovariantDerivative where -- smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), -- toFun X (a • σ) = a • toFun X σ leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), - MDifferentiableAt I I.tangent (fun x ↦ (X x : TangentBundle I M)) x - → MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜, 𝕜) f x (X x)) • σ x + do_not_read : ∀ (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M}, + ¬ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → toFun X σ x = 0 + lemma CovariantDerivative.smul_const_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : cov.toFun X (a • σ) = a • cov.toFun X σ := by ext x - by_cases hX : MDifferentiableAt I I.tangent (fun x ↦ (X x : TangentBundle I M)) x; swap - · -- missing axiom: if X is not differentiable, the covariant derivative is zero - have hσ₁ : cov.toFun X σ = 0 := sorry - have hσ₂ : cov.toFun X (a • σ) = 0 := sorry - simp [hσ₁, hσ₂] - -- Thus, we know `X` is differentiable. by_cases hσ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x - · have hσ' : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • σ x)) x := - sorry - have : MDifferentiableAt I 𝓘(𝕜, 𝕜) (fun x ↦ a) x := - (contMDiff_const.mdifferentiable (n := 1) (by norm_num)).mdifferentiableAt - have aux := cov.leibniz X σ (fun _ ↦ a) x hX hσ this - convert aux - trans (a • cov.toFun X σ) x + 0 - · rw [add_zero] - congr - have : mfderiv I 𝓘(𝕜, 𝕜) (fun x ↦ a) x (X x) = 0 := sorry - rw [this] - simp - -- missing axiom: "if σ is not differentiable, the covariant derivative is zero" - have hσ₁ : cov.toFun X σ = 0 := sorry - have hσ' : ¬ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • σ x)) x := + · simpa using cov.leibniz X σ (fun _ ↦ a) x hσ mdifferentiable_const.mdifferentiableAt + have hσ₂ : cov.toFun X (a • σ) x = 0 := by + refine cov.do_not_read X ?_ + contrapose! hσ + simp at hσ sorry - have hσ₂ : cov.toFun X (a • σ) = 0 := sorry - simp [hσ₁, hσ₂] + simp [cov.do_not_read X hσ, hσ₂] end @@ -93,11 +73,14 @@ section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] +@[simp] theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ DifferentiableAt 𝕜 σ e := by sorry +attribute [simp] mdifferentiableAt_iff_differentiableAt + noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where toFun X s := fun x ↦ fderiv 𝕜 s x (X x) @@ -107,14 +90,12 @@ noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' rw [fderiv_add hσ hσ'] rfl - leibniz := by - intro X σ f x hX hσ hf - have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := by - apply fderiv_smul - (by rwa [← mdifferentiableAt_iff_differentiableAt]) - (by rwa [Bundle.Trivial.mdifferentiableAt_iff] at hσ) - simp [this] - rw [← missing] - congr - + leibniz X σ f x hσ hf := by + have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := + fderiv_smul (by simp_all) (by simp_all) + simp [this, bar] + rfl + do_not_read X σ x hσ := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ + simp [fderiv_zero_of_not_differentiableAt hσ] end From e90626d656d3516725b4c7ac44825175a7b488aa Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 18:35:24 +0200 Subject: [PATCH 012/601] Simplify --- Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1409bd40fb52a6..540c203fb58870 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -43,8 +43,6 @@ structure CovariantDerivative where MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x - -- smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), - -- toFun X (a • σ) = a • toFun X σ leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x From 619ec9fd45923d827d25ce413dba260737ed4d90 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 20:27:25 +0200 Subject: [PATCH 013/601] A bit more CovariantDerivarative API --- .../VectorBundle/CovariantDerivative.lean | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 540c203fb58870..41ccb869e959d5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -13,7 +13,7 @@ section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 2 M] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `F` model fiber @@ -50,20 +50,46 @@ structure CovariantDerivative where do_not_read : ∀ (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M}, ¬ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → toFun X σ x = 0 +namespace CovariantDerivative -lemma CovariantDerivative.smul_const_σ (cov : CovariantDerivative I F V) +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +@[simp] +lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov.toFun 0 σ = 0 := by + have := cov.addX (0 : (x : M) → TangentSpace I x) (0 : (x : M) → TangentSpace I x) σ + simpa using this + +@[simp] +lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov.toFun X 0 = 0 := by + ext x + have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (0 : V x)) x := by + sorry + -- apply mdifferentiableAt_const (I := I) (I' := I.prod 𝓘(𝕜, F)) (c := (0 : V x)) (x := x) fails + have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this + simpa using this + +lemma smul_const_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : cov.toFun X (a • σ) = a • cov.toFun X σ := by ext x by_cases hσ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x · simpa using cov.leibniz X σ (fun _ ↦ a) x hσ mdifferentiable_const.mdifferentiableAt have hσ₂ : cov.toFun X (a • σ) x = 0 := by + by_cases ha: a = 0 + · simp [ha] refine cov.do_not_read X ?_ contrapose! hσ simp at hσ - sorry + have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a⁻¹ • a • σ x)) x := by + sorry -- have := hσ.const_smul a⁻¹ --(E' := H × F) fails to unify + apply this.congr_of_eventuallyEq + filter_upwards with x + congr + exact (eq_inv_smul_iff₀ ha).mpr rfl simp [cov.do_not_read X hσ, hσ₂] +end CovariantDerivative + end section From dfa2c5ee386677dafe974b91649488065b097d52 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 20:47:24 +0200 Subject: [PATCH 014/601] feat: convex combination of covariant derivatives --- .../VectorBundle/CovariantDerivative.lean | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 41ccb869e959d5..371e1fa465142a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -39,7 +39,7 @@ structure CovariantDerivative where toFun (X + X') σ = toFun X σ + toFun X' σ smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜), toFun (f • X) σ = f • toFun X σ - addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x)(x : M), + addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x : M), MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x @@ -88,6 +88,21 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) exact (eq_inv_smul_iff₀ ha).mpr rfl simp [cov.do_not_read X hσ, hσ₂] +/-- A convex combination of covariant derivatives is a covariant derivative. -/ +@[simps] +def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : + CovariantDerivative I F V where + toFun X s := (t • (cov.toFun X s)) + (1 - t) • (cov'.toFun X s) + addX X X' σ := by simp only [cov.addX, cov'.addX]; module + smulX X σ f := by simp only [cov.smulX, cov'.smulX]; module + addσ X σ σ' x hσ hσ' := by + simp [cov.addσ X σ σ' x hσ hσ', cov'.addσ X σ σ' x hσ hσ'] + module + leibniz X σ f x hσ hf := by + simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] + module + do_not_read X {σ} {x} hσ := by simp [cov.do_not_read X hσ, cov'.do_not_read X hσ] + end CovariantDerivative end @@ -105,7 +120,8 @@ theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) ( attribute [simp] mdifferentiableAt_iff_differentiableAt -noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, E) E' +@[simps] +noncomputable def CovariantDerivative.trivial : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where toFun X s := fun x ↦ fderiv 𝕜 s x (X x) addX X X' σ := by ext; simp @@ -122,4 +138,5 @@ noncomputable def trivial_covariant_derivative : CovariantDerivative 𝓘(𝕜, do_not_read X σ x hσ := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ simp [fderiv_zero_of_not_differentiableAt hσ] + end From 9248302f844a41801d079535076ec784590e6b6a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 20:50:46 +0200 Subject: [PATCH 015/601] Add a CoeFun instance --- .../VectorBundle/CovariantDerivative.lean | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 371e1fa465142a..bada28b3d097c5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -52,15 +52,22 @@ structure CovariantDerivative where namespace CovariantDerivative +attribute [coe] toFun + +/-- Coercion of a `CovariantDerivative` to function -/ +instance : CoeFun (CovariantDerivative I F V) + fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := + ⟨fun e ↦ e.toFun⟩ + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @[simp] -lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov.toFun 0 σ = 0 := by +lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = 0 := by have := cov.addX (0 : (x : M) → TangentSpace I x) (0 : (x : M) → TangentSpace I x) σ simpa using this @[simp] -lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov.toFun X 0 = 0 := by +lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by ext x have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (0 : V x)) x := by sorry @@ -70,11 +77,11 @@ lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) lemma smul_const_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : - cov.toFun X (a • σ) = a • cov.toFun X σ := by + cov X (a • σ) = a • cov X σ := by ext x by_cases hσ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x · simpa using cov.leibniz X σ (fun _ ↦ a) x hσ mdifferentiable_const.mdifferentiableAt - have hσ₂ : cov.toFun X (a • σ) x = 0 := by + have hσ₂ : cov X (a • σ) x = 0 := by by_cases ha: a = 0 · simp [ha] refine cov.do_not_read X ?_ @@ -92,7 +99,7 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) @[simps] def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : CovariantDerivative I F V where - toFun X s := (t • (cov.toFun X s)) + (1 - t) • (cov'.toFun X s) + toFun X s := (t • (cov X s)) + (1 - t) • (cov' X s) addX X X' σ := by simp only [cov.addX, cov'.addX]; module smulX X σ f := by simp only [cov.smulX, cov'.smulX]; module addσ X σ σ' x hσ hσ' := by From 9ab4bbd6146b40ffe00e00ce0d9e99b0a0dd5b16 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 22:57:13 +0200 Subject: [PATCH 016/601] Further: congruence properties of covariant derivatives --- .../VectorBundle/CovariantDerivative.lean | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index bada28b3d097c5..6bfb54d6d13d3c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -2,6 +2,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.BumpFunction open Bundle Filter Function @@ -95,6 +96,87 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) exact (eq_inv_smul_iff₀ ha).mpr rfl simp [cov.do_not_read X hσ, hσ₂] +-- "should be obvious" +variable {I F V} in +/-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ +lemma congr_σ (cov : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) : + cov X σ x = cov X σ' x := by + sorry + +-- "should be obvious" +variable {I F V x} in +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +if one is differentiable at `x` then so is the other. -/ +lemma _root_.mfderiv_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) + (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ₂ : ∀ x ∈ s, σ x = σ' x) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by + sorry + +variable {I F V x} in +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +one is differentiable at `x` iff the other is. -/ +lemma _root_.mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) + (hσ : ∀ x ∈ s, σ x = σ' x) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x ↔ + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := + ⟨fun h ↦ mfderiv_dependent_congr hs h hσ, + fun h ↦ mfderiv_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ + +section real + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] {x : M} + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul ℝ (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] + -- `V` vector bundle + +lemma congr_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (f : SmoothBumpFunction I x) : + cov X ((f : M → ℝ) • σ) x = cov X σ x := by + rw [cov.leibniz _ _ _ _ hσ] + swap; · apply f.contMDiff.mdifferentiable (by norm_num) + calc _ + _ = cov X σ x + 0 := ?_ + _ = cov X σ x := by rw [add_zero] + simp [f.eq_one]; left + have aux : f =ᶠ[nhds x] (fun _ ↦ 1) := f.eventuallyEq_one + rw [aux.mfderiv_eq, mfderiv_const] + rfl + +lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσσ' : ∀ x ∈ s, σ x = σ' x) : + cov X σ x = cov X σ' x := by + -- Choose a smooth bump function ψ with support around `x` contained in `s`: TODO + let R : ℝ := sorry + let ψ : SmoothBumpFunction I x := sorry + have hψ : support ψ ⊆ s := sorry + -- Observe that `ψ • σ = ψ • σ'` as dependent functions. + have (x : M) : σ x = σ' x := sorry + -- Then, it's a chain of (dependent) equalities. + calc cov X σ x + _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_smoothBumpFunction _ _ _ _ hσ] + _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) + _ = cov X σ' x := by simp [cov.congr_smoothBumpFunction, mfderiv_dependent_congr hs hσ hσσ'] + +-- eventually, prove: cov X σ x depends on σ only via σ(X) and the 1-jet of σ at x + +end real + /-- A convex combination of covariant derivatives is a covariant derivative. -/ @[simps] def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : From ab519380296c7a1141a54b985cda51807391f07c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 23:05:41 +0200 Subject: [PATCH 017/601] Last sorry for tonight --- .../Manifold/VectorBundle/CovariantDerivative.lean | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 6bfb54d6d13d3c..a4bb8e5b3e8e76 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -151,9 +151,9 @@ lemma congr_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [Is calc _ _ = cov X σ x + 0 := ?_ _ = cov X σ x := by rw [add_zero] - simp [f.eq_one]; left - have aux : f =ᶠ[nhds x] (fun _ ↦ 1) := f.eventuallyEq_one - rw [aux.mfderiv_eq, mfderiv_const] + simp [f.eq_one, f.eventuallyEq_one.mfderiv_eq] + rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] + left rfl lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] @@ -166,14 +166,17 @@ lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [Is let ψ : SmoothBumpFunction I x := sorry have hψ : support ψ ⊆ s := sorry -- Observe that `ψ • σ = ψ • σ'` as dependent functions. - have (x : M) : σ x = σ' x := sorry + have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by + by_cases h : x ∈ s + · simp [hσσ' x h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] -- Then, it's a chain of (dependent) equalities. calc cov X σ x _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_smoothBumpFunction _ _ _ _ hσ] _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) _ = cov X σ' x := by simp [cov.congr_smoothBumpFunction, mfderiv_dependent_congr hs hσ hσσ'] --- eventually, prove: cov X σ x depends on σ only via σ(X) and the 1-jet of σ at x +-- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x end real From 75c24beb2cd990d5d1d9a1ebd43adcb7c2159259 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 20 Jun 2025 23:56:22 +0200 Subject: [PATCH 018/601] chore: fix lemma name --- .../Manifold/VectorBundle/CovariantDerivative.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index a4bb8e5b3e8e76..863d7387878f98 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -108,7 +108,7 @@ lemma congr_σ (cov : CovariantDerivative I F V) variable {I F V x} in /-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, if one is differentiable at `x` then so is the other. -/ -lemma _root_.mfderiv_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) +lemma _root_.mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by @@ -121,8 +121,8 @@ lemma _root_.mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (h (hσ : ∀ x ∈ s, σ x = σ' x) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x ↔ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := - ⟨fun h ↦ mfderiv_dependent_congr hs h hσ, - fun h ↦ mfderiv_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ + ⟨fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h hσ, + fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ section real @@ -174,7 +174,7 @@ lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [Is calc cov X σ x _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_smoothBumpFunction _ _ _ _ hσ] _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) - _ = cov X σ' x := by simp [cov.congr_smoothBumpFunction, mfderiv_dependent_congr hs hσ hσσ'] + _ = cov X σ' x := by simp [cov.congr_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x From dd0f5b100450ad78a57022450f13a9d4cb8eea4d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 21 Jun 2025 00:25:03 +0200 Subject: [PATCH 019/601] chore: use simpler notation --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 863d7387878f98..59253601066274 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -26,7 +26,7 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] -- `V` vector bundle -def bar (a : 𝕜) : TangentSpace 𝓘(𝕜, 𝕜) a ≃L[𝕜] 𝕜 where +def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where toFun v := v invFun v := v map_add' := by simp @@ -46,8 +46,8 @@ structure CovariantDerivative where → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x - → MDifferentiableAt I 𝓘(𝕜, 𝕜) f x - → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜, 𝕜) f x (X x)) • σ x + → MDifferentiableAt I 𝓘(𝕜) f x + → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) f x (X x)) • σ x do_not_read : ∀ (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M}, ¬ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → toFun X σ x = 0 From 28cab212c2f1607604004ae530be916bdc4a9aec Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 21 Jun 2025 00:25:20 +0200 Subject: [PATCH 020/601] Further towards horizontal sub-bundles --- .../VectorBundle/CovariantDerivative.lean | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 59253601066274..4e2c0ecc5cfea7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -129,7 +129,7 @@ section real variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] {x : M} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] -- `F` model fiber @@ -141,6 +141,8 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] [FiberBundle F V] [VectorBundle ℝ F V] -- `V` vector bundle +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in lemma congr_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) @@ -174,7 +176,48 @@ lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [Is calc cov X σ x _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_smoothBumpFunction _ _ _ _ hσ] _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) - _ = cov X σ' x := by simp [cov.congr_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] + _ = cov X σ' x := by + simp [cov.congr_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] + +variable {I F V} in +/-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. +Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ +def difference_aux (cov cov' : CovariantDerivative I F V) : + (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := + fun X σ ↦ cov X σ - cov' X σ + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in +lemma difference_aux_smul_eq (cov cov' : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) + (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) + (hf : MDifferentiable I 𝓘(ℝ) f) : + difference_aux cov cov' X ((f : M → ℝ) • σ) = (f : M → ℝ) • (difference_aux cov cov' X σ) := + calc _ + _ = cov X ((f : M → ℝ) • σ) - cov' X ((f : M → ℝ) • σ) := rfl + _ = (f • cov X σ + (fun x ↦ bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ) + - (f • cov' X σ + (fun x ↦ bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ) := by + ext x + simp [cov.leibniz X _ _ _ (hσ x) (hf x), cov'.leibniz X _ _ _ (hσ x) (hf x)] + _ = f • cov X σ - f • cov' X σ := by simp + _ = f • (cov X σ - cov' X σ) := by simp [smul_sub] + _ = _ := rfl + +lemma difference_aux_smul_eq' (cov cov' : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) + (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) + (hf : MDifferentiable I 𝓘(ℝ) f) : + difference_aux cov cov' (f • X) σ = (f : M → ℝ) • difference_aux cov cov' X σ := by + simp [difference_aux] + sorry -- Chris says "it's obvious" + +-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. +lemma foo (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X X' : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x₀ : M) + (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) + (hσ' : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x))) : + difference_aux cov cov' X σ x₀ = difference_aux cov cov' X' σ' x₀ := by + sorry -- use the previous two lemmas -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x From 3d7cb6379042c0ca1b2953bc38b318e366ee53fe Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 13:33:04 +0200 Subject: [PATCH 021/601] Names --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 4e2c0ecc5cfea7..33660e07d8840e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -143,7 +143,7 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in -lemma congr_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (f : SmoothBumpFunction I x) : @@ -174,10 +174,10 @@ lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [Is · simp [notMem_support.mp fun a ↦ h (hψ a)] -- Then, it's a chain of (dependent) equalities. calc cov X σ x - _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_smoothBumpFunction _ _ _ _ hσ] + _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ _ _ _ hσ] _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) _ = cov X σ' x := by - simp [cov.congr_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] + simp [cov.congr_σ_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] variable {I F V} in /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. From d6d924e56ee8e69ea5ef53ba10fa24c84ac770fb Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Jun 2025 13:57:47 +0200 Subject: [PATCH 022/601] Prove congruence lemmas --- .../VectorBundle/CovariantDerivative.lean | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 33660e07d8840e..3555f56ab9d66f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -96,24 +96,34 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) exact (eq_inv_smul_iff₀ ha).mpr rfl simp [cov.do_not_read X hσ, hσ₂] --- "should be obvious" +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in variable {I F V} in /-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ lemma congr_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) : cov X σ x = cov X σ' x := by - sorry + simp [funext hσ] --- "should be obvious" +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [(x : M) → AddCommGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in variable {I F V x} in /-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -if one is differentiable at `x` then so is the other. -/ +if one is differentiable at `x` then so is the other. +Issue: EventuallyEq does not work for dependent functions. -/ lemma _root_.mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by - sorry - + apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ + -- TODO: split off a lemma? + apply Set.EqOn.eventuallyEq_of_mem _ hs + intro x hx + simp [hσ₂, hx] + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [(x : M) → AddCommGroup (V x)] in variable {I F V x} in /-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, one is differentiable at `x` iff the other is. -/ @@ -203,13 +213,12 @@ lemma difference_aux_smul_eq (cov cov' : CovariantDerivative I F V) _ = f • (cov X σ - cov' X σ) := by simp [smul_sub] _ = _ := rfl +omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in lemma difference_aux_smul_eq' (cov cov' : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) - (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) - (hf : MDifferentiable I 𝓘(ℝ) f) : + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) : difference_aux cov cov' (f • X) σ = (f : M → ℝ) • difference_aux cov cov' X σ := by - simp [difference_aux] - sorry -- Chris says "it's obvious" + simp [difference_aux, cov.smulX, cov'.smulX, smul_sub] -- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. lemma foo (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] From b42b3df86fb6c1d05557698973fae9fec5e4bdad Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 14:00:15 +0200 Subject: [PATCH 023/601] Congruence at X --- .../VectorBundle/CovariantDerivative.lean | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 3555f56ab9d66f..79822b58a1bb73 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -168,6 +168,37 @@ lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] left rfl +/-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ +lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσσ' : ∀ x ∈ s, X x = X' x) : + cov X σ x = cov X' σ x := by + sorry + +lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} + --(hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hX : X x = 0) : cov X σ x = 0 := by + -- on (chartAt H x).source, can decompose X = ∑ a_i Xi + -- (where Xi are coordinate vector fields, and ai smooth functions on U) + -- extend each Xi to some smooth vector field on M, using a suitable bump function + -- then we compute + -- cov X σ x = cov X (∑ i, ai Xi) σ x -- using the previous lemma once: X = ∑ ai Xi on U + -- = ∑ i, cov (ai Xi) σ x -- use linearity, inductively ---> new helper lemma + -- = ∑ i, ai(x) cov Xi σ x -- apply smulX + -- = 0 (as each ai(x) = 0) + sorry + +-- XXX: better name? +/-- `cov X σ x` only depends on `X` via `X x` -/ +lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hXX' : X x = X' x) : + cov X σ x = cov X' σ x := by + have : cov X' σ x = cov X σ x + cov (X' - X) σ x := sorry + have h : (X' - X) x = 0 := sorry + simp [this, cov.congr_X_at_aux I _ _ (X' - X) h] + lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) From 750f4522d86efba448153d5c0641d66961b2b379 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Jun 2025 15:28:54 +0200 Subject: [PATCH 024/601] Stub local frames --- .../VectorBundle/CovariantDerivative.lean | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 79822b58a1bb73..7c40de424ff4b4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -4,12 +4,61 @@ import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction -open Bundle Filter Function +open Bundle Filter Function Topology open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] +section local_frame + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] + -- `V` vector bundle + +set_option linter.style.commandStart false + +def Basis.local_frame {ι : Type*} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) : ι → (x : M) → V x := sorry + +def Basis.local_frame_repr {ι : Type*} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) + (s : Π x : M, V x) : + ι → M → 𝕜 := sorry + +lemma Basis.local_frame_repr_spec {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) + (b : Basis ι 𝕜 F) + (s : Π x : M, V x) : + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x' := + sorry + +variable {n} + +lemma Basis.contMDiffAt_local_frame_repr {ι : Type*} {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) + (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) + (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.local_frame_repr e s i) x := sorry +end local_frame + section variable {E : Type*} [NormedAddCommGroup E] From 7fbda7e7a79afb524e6b29630157766ab42b24ec Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Jun 2025 16:13:08 +0200 Subject: [PATCH 025/601] Some trivialities --- .../Manifold/VectorBundle/CovariantDerivative.lean | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 7c40de424ff4b4..43aef239c729fb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -116,12 +116,13 @@ lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = have := cov.addX (0 : (x : M) → TangentSpace I x) (0 : (x : M) → TangentSpace I x) σ simpa using this +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by ext x have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (0 : V x)) x := by - sorry - -- apply mdifferentiableAt_const (I := I) (I' := I.prod 𝓘(𝕜, F)) (c := (0 : V x)) (x := x) fails + exact (contMDiff_zeroSection 𝕜 V).mdifferentiableAt le_rfl have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this simpa using this @@ -138,7 +139,8 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) contrapose! hσ simp at hσ have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a⁻¹ • a • σ x)) x := by - sorry -- have := hσ.const_smul a⁻¹ --(E' := H × F) fails to unify + -- Needs a version of Bundle.contMDiffAt_totalSpace for MDifferentiableAt + sorry apply this.congr_of_eventuallyEq filter_upwards with x congr From d43f69c38c9fbe1156d34494e32e9950a06e55dc Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 16:13:25 +0200 Subject: [PATCH 026/601] Mostly prove congr_at_X --- .../VectorBundle/CovariantDerivative.lean | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 43aef239c729fb..81eac50c1c4f55 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -57,6 +57,7 @@ lemma Basis.contMDiffAt_local_frame_repr {ι : Type*} {x : M} {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.local_frame_repr e s i) x := sorry + end local_frame section @@ -219,27 +220,41 @@ lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] left rfl +variable {I F V} in /-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) (hσσ' : ∀ x ∈ s, X x = X' x) : cov X σ x = cov X' σ x := by + by_cases hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x; swap + · simp [cov.do_not_read X hσ, cov.do_not_read X' hσ] sorry +variable {I F V} in lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} - --(hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (hX : X x = 0) : cov X σ x = 0 := by -- on (chartAt H x).source, can decompose X = ∑ a_i Xi - -- (where Xi are coordinate vector fields, and ai smooth functions on U) - -- extend each Xi to some smooth vector field on M, using a suitable bump function - -- then we compute - -- cov X σ x = cov X (∑ i, ai Xi) σ x -- using the previous lemma once: X = ∑ ai Xi on U - -- = ∑ i, cov (ai Xi) σ x -- use linearity, inductively ---> new helper lemma - -- = ∑ i, ai(x) cov Xi σ x -- apply smulX - -- = 0 (as each ai(x) = 0) - sorry + let n : ℕ := sorry -- finrank of E + -- Choose a basis of TangentSpace I x = E. + let b : Basis (Fin n) ℝ E := sorry + -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. + let e := trivializationAt E (TangentSpace I) x + let Xi (i : Fin n) := b.local_frame e i + -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. + let a := b.local_frame_repr e X + have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.local_frame_repr_spec this X + have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by + refine ⟨_, aux, by simp⟩ + have (i : Fin n) : a i x = 0 := sorry -- "obvious" + calc cov X σ x + _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) + _ = ∑ i, cov (a i • Xi i) σ x := by + sorry -- use linearity and induction --> make a new helper lemma + _ = ∑ i, a i x • cov (Xi i) σ x := by + congr; ext i; simp [cov.smulX (Xi i) σ (a i)] + _ = 0 := by simp [this] -- XXX: better name? /-- `cov X σ x` only depends on `X` via `X x` -/ @@ -248,7 +263,7 @@ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ cov X σ x = cov X' σ x := by have : cov X' σ x = cov X σ x + cov (X' - X) σ x := sorry have h : (X' - X) x = 0 := sorry - simp [this, cov.congr_X_at_aux I _ _ (X' - X) h] + simp [this, cov.congr_X_at_aux (X' - X) h] lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) From edc1bcc9cf034cce82801ca4b7d69bb6c5df6632 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Jun 2025 16:37:51 +0200 Subject: [PATCH 027/601] Fix smooth bump function --- .../Manifold/VectorBundle/CovariantDerivative.lean | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 81eac50c1c4f55..16bfc1fda8ff9a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -265,15 +265,16 @@ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ have h : (X' - X) x = 0 := sorry simp [this, cov.congr_X_at_aux (X' - X) h] -lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +lemma congr_σ_of_eventuallyEq + (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : cov X σ x = cov X σ' x := by - -- Choose a smooth bump function ψ with support around `x` contained in `s`: TODO - let R : ℝ := sorry - let ψ : SmoothBumpFunction I x := sorry - have hψ : support ψ ⊆ s := sorry + -- Choose a smooth bump function ψ with support around `x` contained in `s` + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs -- Observe that `ψ • σ = ψ • σ'` as dependent functions. have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by by_cases h : x ∈ s From d4322506d6644ab95e4174626cef4cbc6871ad27 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 16:35:08 +0200 Subject: [PATCH 028/601] Prove helper lemma --- .../VectorBundle/CovariantDerivative.lean | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 16bfc1fda8ff9a..3fc355b2d3c52a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -190,13 +190,13 @@ section real variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] -- `F` model fiber (n : WithTop ℕ∞) - (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -220,7 +220,16 @@ lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] left rfl -variable {I F V} in +omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in +lemma sum_X (cov : CovariantDerivative I F V) + {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : + cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by + classical + induction s using Finset.induction_on with + | empty => simp + | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] + /-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) @@ -230,15 +239,13 @@ lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsM · simp [cov.do_not_read X hσ, cov.do_not_read X' hσ] sorry -variable {I F V} in lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hX : X x = 0) : cov X σ x = 0 := by - -- on (chartAt H x).source, can decompose X = ∑ a_i Xi - let n : ℕ := sorry -- finrank of E - -- Choose a basis of TangentSpace I x = E. - let b : Basis (Fin n) ℝ E := sorry -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. + -- To do so, choose a basis of TangentSpace I x = E. + let n : ℕ := Module.finrank ℝ E + let b : Basis (Fin n) ℝ E := sorry let e := trivializationAt E (TangentSpace I) x let Xi (i : Fin n) := b.local_frame e i -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. @@ -247,11 +254,10 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.local_frame_repr_spec this X have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by refine ⟨_, aux, by simp⟩ - have (i : Fin n) : a i x = 0 := sorry -- "obvious" + have (i : Fin n) : a i x = 0 := by sorry -- "obvious" calc cov X σ x _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) - _ = ∑ i, cov (a i • Xi i) σ x := by - sorry -- use linearity and induction --> make a new helper lemma + _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp _ = ∑ i, a i x • cov (Xi i) σ x := by congr; ext i; simp [cov.smulX (Xi i) σ (a i)] _ = 0 := by simp [this] @@ -282,12 +288,11 @@ lemma congr_σ_of_eventuallyEq · simp [notMem_support.mp fun a ↦ h (hψ a)] -- Then, it's a chain of (dependent) equalities. calc cov X σ x - _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ _ _ _ hσ] + _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ hσ] _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) _ = cov X σ' x := by simp [cov.congr_σ_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] -variable {I F V} in /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ def difference_aux (cov cov' : CovariantDerivative I F V) : From ecfb3c5c842b7597dc163c1c17a9eaa96e45d4f5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 16:54:07 +0200 Subject: [PATCH 029/601] More easy sorries, and some more spec for local frames; fix linter warnings --- .../VectorBundle/CovariantDerivative.lean | 59 +++++++++++++++---- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 3fc355b2d3c52a..70532ec084d7ef 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -33,6 +33,7 @@ def Basis.local_frame {ι : Type*} [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : ι → (x : M) → V x := sorry +/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.local_frame e i` -/ def Basis.local_frame_repr {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] @@ -48,6 +49,39 @@ lemma Basis.local_frame_repr_spec {ι : Type*} [Fintype ι] {x : M} ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x' := sorry +-- missing: uniqueness of the decomposition; will be used to prove e.g. linearity below + +lemma Basis.local_frame_repr_add {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) + (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) : + b.local_frame_repr e (s + s') i = + (b.local_frame_repr e (s + s') i) + (b.local_frame_repr e (s + s') i) := by + sorry + +-- corollary of this and uniqueness + +-- TODO: better name! +lemma Basis.local_frame_repr_apply_zero_at {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) + (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : + b.local_frame_repr e s i x = 0 := sorry + +-- TODO: better name +lemma Basis.local_frame_repr_apply_zero {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) + (b : Basis ι 𝕜 F) (i : ι) : + b.local_frame_repr e 0 i = 0 := sorry + +/-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ +lemma Basis.local_frame_repr_congr {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) + (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) (hss' : s x = s' x) : + b.local_frame_repr e s i x = b.local_frame_repr e s' i x := sorry + variable {n} lemma Basis.contMDiffAt_local_frame_repr {ι : Type*} {x : M} @@ -170,7 +204,7 @@ lemma _root_.mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ -- TODO: split off a lemma? - apply Set.EqOn.eventuallyEq_of_mem _ hs + apply Set.EqOn.eventuallyEq_of_mem _ hs intro x hx simp [hσ₂, hx] @@ -231,7 +265,7 @@ lemma sum_X (cov : CovariantDerivative I F V) | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] /-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ -lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) (hσσ' : ∀ x ∈ s, X x = X' x) : cov X σ x = cov X' σ x := by @@ -239,22 +273,22 @@ lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsM · simp [cov.do_not_read X hσ, cov.do_not_read X' hσ] sorry -lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +lemma congr_X_at_aux (cov : CovariantDerivative I F V) [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hX : X x = 0) : cov X σ x = 0 := by -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. -- To do so, choose a basis of TangentSpace I x = E. let n : ℕ := Module.finrank ℝ E - let b : Basis (Fin n) ℝ E := sorry + let b : Basis (Fin n) ℝ E := Module.finBasis ℝ E let e := trivializationAt E (TangentSpace I) x let Xi (i : Fin n) := b.local_frame e i -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. let a := b.local_frame_repr e X have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.local_frame_repr_spec this X - have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by - refine ⟨_, aux, by simp⟩ - have (i : Fin n) : a i x = 0 := by sorry -- "obvious" + -- have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by + -- refine ⟨_, aux, by simp⟩ + have (i : Fin n) : a i x = 0 := b.local_frame_repr_apply_zero_at this hX i calc cov X σ x _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp @@ -263,12 +297,17 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I _ = 0 := by simp [this] -- XXX: better name? +-- golfing welcome! /-- `cov X σ x` only depends on `X` via `X x` -/ -lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +lemma congr_X_at (cov : CovariantDerivative I F V) [IsManifold I ∞ M] (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hXX' : X x = X' x) : cov X σ x = cov X' σ x := by - have : cov X' σ x = cov X σ x + cov (X' - X) σ x := sorry - have h : (X' - X) x = 0 := sorry + have : cov X' σ x = cov X σ x + cov (X' - X) σ x := by + have : X' = X + (X' - X) := by simp + nth_rw 1 [this] + rw [cov.addX X (X' - X) σ] + simp + have h : (X' - X) x = 0 := by simp [hXX'] simp [this, cov.congr_X_at_aux (X' - X) h] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] From 4c8fa4ce78d956ae7c5a11807009c27e14766ecd Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Jun 2025 17:36:38 +0200 Subject: [PATCH 030/601] =?UTF-8?q?Ugly=20win=20against=20smul=5Fconst=5F?= =?UTF-8?q?=CF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VectorBundle/CovariantDerivative.lean | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 70532ec084d7ef..ce7b121a9c0d0c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -3,6 +3,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable open Bundle Filter Function Topology @@ -161,6 +162,8 @@ lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this simpa using this +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma smul_const_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : cov X (a • σ) = a • cov X σ := by @@ -174,8 +177,21 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) contrapose! hσ simp at hσ have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a⁻¹ • a • σ x)) x := by - -- Needs a version of Bundle.contMDiffAt_totalSpace for MDifferentiableAt - sorry + rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace] + refine ⟨mdifferentiableAt_id, ?_⟩ + have : (fun x' : M ↦ ((trivializationAt F V x) { proj := x', snd := a⁻¹ • a • σ x'}).2) + =ᶠ[𝓝 x] + fun x' : M ↦ a⁻¹ • ((trivializationAt F V x) { proj := x', snd := a • σ x'}).2 := by + have : ∀ᶠ x' in 𝓝 x, x' ∈ (trivializationAt F V x).baseSet := by + exact (trivializationAt F V x).open_baseSet.eventually_mem + (FiberBundle.mem_baseSet_trivializationAt' x) + apply this.mono + intro x' hx' + apply (trivializationAt F V x).linear (R := 𝕜) (F := F) hx' |>.map_smul + apply MDifferentiableAt.congr_of_eventuallyEq _ this + apply MDifferentiableAt.const_smul + rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace] at hσ + simpa [TotalSpace.mk'] using hσ.2 apply this.congr_of_eventuallyEq filter_upwards with x congr From 314379b70fed4fb4775c5332e4ac0e3bb26f324b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 17:35:19 +0200 Subject: [PATCH 031/601] One last congruence sorry --- .../VectorBundle/CovariantDerivative.lean | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ce7b121a9c0d0c..9a9348826041bd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -280,16 +280,35 @@ lemma sum_X (cov : CovariantDerivative I F V) | empty => simp | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in /-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ -lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) +lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) (hσσ' : ∀ x ∈ s, X x = X' x) : cov X σ x = cov X' σ x := by by_cases hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x; swap · simp [cov.do_not_read X hσ, cov.do_not_read X' hσ] - sorry + -- Choose a smooth bump function ψ with support around `x` contained in `s` + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs + -- Observe that `ψ • X = ψ • X'` as dependent functions. + have (x : M) : ((ψ : M → ℝ) • X) x = ((ψ : M → ℝ) • X') x := by + by_cases h : x ∈ s + · simp [hσσ' x h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] + -- Then, it's a chain of (dependent) equalities. + calc cov X σ x + _ = cov ((ψ : M → ℝ) • X) σ x := by simp [cov.smulX] + _ = cov ((ψ : M → ℝ) • X') σ x := by + -- XXX: should this be a lemma cov.congr_X? + congr 1 + ext x + simp [this] + _ = cov X' σ x := by simp [cov.smulX] -lemma congr_X_at_aux (cov : CovariantDerivative I F V) [IsManifold I ∞ M] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hX : X x = 0) : cov X σ x = 0 := by -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. @@ -314,8 +333,10 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [IsManifold I ∞ M] -- XXX: better name? -- golfing welcome! +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in /-- `cov X σ x` only depends on `X` via `X x` -/ -lemma congr_X_at (cov : CovariantDerivative I F V) [IsManifold I ∞ M] +lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hXX' : X x = X' x) : cov X σ x = cov X' σ x := by have : cov X' σ x = cov X σ x + cov (X' - X) σ x := by @@ -327,7 +348,7 @@ lemma congr_X_at (cov : CovariantDerivative I F V) [IsManifold I ∞ M] simp [this, cov.congr_X_at_aux (X' - X) h] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in + [VectorBundle ℝ F V] in lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) From 853453714ce95daa448e0cba3643261757b86ebc Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 17:38:29 +0200 Subject: [PATCH 032/601] Re-order for cleaner flow --- .../VectorBundle/CovariantDerivative.lean | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 9a9348826041bd..bec9f0393f858d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -236,6 +236,16 @@ lemma _root_.mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (h ⟨fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h hσ, fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +lemma sum_X (cov : CovariantDerivative I F V) + {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : + cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by + classical + induction s using Finset.induction_on with + | empty => simp + | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] + section real variable {E : Type*} [NormedAddCommGroup E] @@ -253,33 +263,6 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] [FiberBundle F V] [VectorBundle ℝ F V] -- `V` vector bundle -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (f : SmoothBumpFunction I x) : - cov X ((f : M → ℝ) • σ) x = cov X σ x := by - rw [cov.leibniz _ _ _ _ hσ] - swap; · apply f.contMDiff.mdifferentiable (by norm_num) - calc _ - _ = cov X σ x + 0 := ?_ - _ = cov X σ x := by rw [add_zero] - simp [f.eq_one, f.eventuallyEq_one.mfderiv_eq] - rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] - left - rfl - -omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in -lemma sum_X (cov : CovariantDerivative I F V) - {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : - cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by - classical - induction s using Finset.induction_on with - | empty => simp - | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] - omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in /-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ @@ -347,6 +330,23 @@ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ have h : (X' - X) x = 0 := by simp [hXX'] simp [this, cov.congr_X_at_aux (X' - X) h] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (f : SmoothBumpFunction I x) : + cov X ((f : M → ℝ) • σ) x = cov X σ x := by + rw [cov.leibniz _ _ _ _ hσ] + swap; · apply f.contMDiff.mdifferentiable (by norm_num) + calc _ + _ = cov X σ x + 0 := ?_ + _ = cov X σ x := by rw [add_zero] + simp [f.eq_one, f.eventuallyEq_one.mfderiv_eq] + rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] + left + rfl + omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in lemma congr_σ_of_eventuallyEq From 13dd73fe300e703a90604c5bb3913879233cb194 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Jun 2025 17:40:23 +0200 Subject: [PATCH 033/601] Final golf for today --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index bec9f0393f858d..f77edda7576bf6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -282,11 +282,7 @@ lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] -- Then, it's a chain of (dependent) equalities. calc cov X σ x _ = cov ((ψ : M → ℝ) • X) σ x := by simp [cov.smulX] - _ = cov ((ψ : M → ℝ) • X') σ x := by - -- XXX: should this be a lemma cov.congr_X? - congr 1 - ext x - simp [this] + _ = cov ((ψ : M → ℝ) • X') σ x := by rw [funext this] _ = cov X' σ x := by simp [cov.smulX] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] From 548ec2f1149b9e5f46a49ec90f947fb3f4489cd1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 16:18:49 +0200 Subject: [PATCH 034/601] Progress on local frames --- .../VectorBundle/CovariantDerivative.lean | 67 +++++++++++++++---- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index f77edda7576bf6..eb5d7dbd69b82b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -29,36 +29,77 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] set_option linter.style.commandStart false -def Basis.local_frame {ι : Type*} +namespace Basis + +noncomputable def local_frame_toBasis_at {ι : Type*} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := + b.map (e.linearEquivAt (R := 𝕜) x hx).symm + +open scoped Classical in +-- If x is outside of `e.baseSet`, this returns the junk value 0. +noncomputable def local_frame {ι : Type*} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) : ι → (x : M) → V x := fun i x ↦ + -- idea: take the vector b i and apply the trivialisation e to it. + if hx : x ∈ e.baseSet then b.local_frame_toBasis_at e hx i else 0 + +lemma local_frame_toBasis_at_coe {ι : Type*} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : + b.local_frame_toBasis_at e hx i = b.local_frame e i x := by + simp [local_frame_toBasis_at, local_frame, hx] + +-- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? +/-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ +def isBasis_local_frame {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) : ι → (x : M) → V x := sorry + (b : Basis ι 𝕜 F) : sorry := by + -- the b i form a basis of F, + -- and the trivialisation e is a linear equivalence (thus preserves bases) + sorry +open scoped Classical in /-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.local_frame e i` -/ -def Basis.local_frame_repr {ι : Type*} +-- If x is outside of `e.baseSet`, this returns the junk value 0. +noncomputable def local_frame_repr {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) - (s : Π x : M, V x) : - ι → M → 𝕜 := sorry + (b : Basis ι 𝕜 F) (s : Π x : M, V x) : ι → M → 𝕜 := + fun i x ↦ if hx : x ∈ e.baseSet then (b.local_frame_toBasis_at e hx).repr (s x) i else 0 -lemma Basis.local_frame_repr_spec {ι : Type*} [Fintype ι] {x : M} +-- uniqueness of the decomposition: will follow from the IsBasis property above + +lemma local_frame_repr_spec {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x' := - sorry - --- missing: uniqueness of the decomposition; will be used to prove e.g. linearity below - + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x' := by + have {x'} (hx : x' ∈ e.baseSet) : + s x' = (∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x') := by + simp [Basis.local_frame_repr, local_frame, local_frame_toBasis_at, hx] + sorry -- some simp'ing and a property of bases + exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ + +-- uniqueness implies this, but it also follows from our definition lemma Basis.local_frame_repr_add {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) : b.local_frame_repr e (s + s') i = (b.local_frame_repr e (s + s') i) + (b.local_frame_repr e (s + s') i) := by - sorry + by_cases hx : x ∈ e.baseSet; swap + · exact False.elim (hx hxe) + simp-- [local_frame_repr] + unfold local_frame_repr + sorry -- need some _apply simp lemmas... simp [hx] + +end Basis -- corollary of this and uniqueness From 2daa419a5f11859d9a67503509764b6755bc8317 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 25 Jun 2025 18:42:16 +0200 Subject: [PATCH 035/601] Some cleanup --- .../VectorBundle/CovariantDerivative.lean | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index eb5d7dbd69b82b..9e91be37c78a34 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -203,6 +203,13 @@ lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this simpa using this +lemma _root_.FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) + [TopologicalSpace B] [TopologicalSpace F] + (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] + [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := + (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) + + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma smul_const_σ (cov : CovariantDerivative I F V) @@ -216,27 +223,17 @@ lemma smul_const_σ (cov : CovariantDerivative I F V) · simp [ha] refine cov.do_not_read X ?_ contrapose! hσ - simp at hσ have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a⁻¹ • a • σ x)) x := by - rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace] + rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace] at * refine ⟨mdifferentiableAt_id, ?_⟩ - have : (fun x' : M ↦ ((trivializationAt F V x) { proj := x', snd := a⁻¹ • a • σ x'}).2) - =ᶠ[𝓝 x] - fun x' : M ↦ a⁻¹ • ((trivializationAt F V x) { proj := x', snd := a • σ x'}).2 := by - have : ∀ᶠ x' in 𝓝 x, x' ∈ (trivializationAt F V x).baseSet := by - exact (trivializationAt F V x).open_baseSet.eventually_mem - (FiberBundle.mem_baseSet_trivializationAt' x) - apply this.mono - intro x' hx' - apply (trivializationAt F V x).linear (R := 𝕜) (F := F) hx' |>.map_smul - apply MDifferentiableAt.congr_of_eventuallyEq _ this - apply MDifferentiableAt.const_smul - rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace] at hσ - simpa [TotalSpace.mk'] using hσ.2 + have : ∀ᶠ x' in 𝓝 x, ((trivializationAt F V x) ⟨x', a⁻¹ • a • σ x'⟩).2 = + a⁻¹ • ((trivializationAt F V x) ⟨x', a • σ x'⟩).2 := by + filter_upwards [FiberBundle.trivializationAt.baseSet_mem_nhds F V x] with x' hx' + exact (trivializationAt F V x).linear 𝕜 hx' |>.map_smul a⁻¹ (a • σ x') + exact MDifferentiableAt.const_smul hσ.2 a⁻¹ |>.congr_of_eventuallyEq this apply this.congr_of_eventuallyEq filter_upwards with x - congr - exact (eq_inv_smul_iff₀ ha).mpr rfl + simp [ha] simp [cov.do_not_read X hσ, hσ₂] omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] From 64ae64dccda6941a1ccc28bdd3da4d9c75d6b76c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 20:48:33 +0200 Subject: [PATCH 036/601] chore: rename local_frame -> localFrame; by rule 4 of the naming convention --- .../VectorBundle/CovariantDerivative.lean | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 9e91be37c78a34..e3db8ee7b26bc0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -11,7 +11,7 @@ open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -section local_frame +section localFrame variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) @@ -31,7 +31,7 @@ set_option linter.style.commandStart false namespace Basis -noncomputable def local_frame_toBasis_at {ι : Type*} +noncomputable def localFrame_toBasis_at {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := @@ -39,23 +39,23 @@ noncomputable def local_frame_toBasis_at {ι : Type*} open scoped Classical in -- If x is outside of `e.baseSet`, this returns the junk value 0. -noncomputable def local_frame {ι : Type*} +noncomputable def localFrame {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : ι → (x : M) → V x := fun i x ↦ -- idea: take the vector b i and apply the trivialisation e to it. - if hx : x ∈ e.baseSet then b.local_frame_toBasis_at e hx i else 0 + if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 -lemma local_frame_toBasis_at_coe {ι : Type*} +lemma localFrame_toBasis_at_coe {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : - b.local_frame_toBasis_at e hx i = b.local_frame e i x := by - simp [local_frame_toBasis_at, local_frame, hx] + b.localFrame_toBasis_at e hx i = b.localFrame e i x := by + simp [localFrame_toBasis_at, localFrame, hx] -- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? /-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ -def isBasis_local_frame {ι : Type*} +def isBasis_localFrame {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : sorry := by @@ -64,39 +64,39 @@ def isBasis_local_frame {ι : Type*} sorry open scoped Classical in -/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.local_frame e i` -/ +/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ -- If x is outside of `e.baseSet`, this returns the junk value 0. -noncomputable def local_frame_repr {ι : Type*} +noncomputable def localFrame_repr {ι : Type*} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (s : Π x : M, V x) : ι → M → 𝕜 := - fun i x ↦ if hx : x ∈ e.baseSet then (b.local_frame_toBasis_at e hx).repr (s x) i else 0 + fun i x ↦ if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 -- uniqueness of the decomposition: will follow from the IsBasis property above -lemma local_frame_repr_spec {ι : Type*} [Fintype ι] {x : M} +lemma localFrame_repr_spec {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x' := by + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x' := by have {x'} (hx : x' ∈ e.baseSet) : - s x' = (∑ i, (b.local_frame_repr e s i x') • b.local_frame e i x') := by - simp [Basis.local_frame_repr, local_frame, local_frame_toBasis_at, hx] + s x' = (∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x') := by + simp [Basis.localFrame_repr, localFrame, localFrame_toBasis_at, hx] sorry -- some simp'ing and a property of bases exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ -- uniqueness implies this, but it also follows from our definition -lemma Basis.local_frame_repr_add {ι : Type*} [Fintype ι] {x : M} +lemma Basis.localFrame_repr_add {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) : - b.local_frame_repr e (s + s') i = - (b.local_frame_repr e (s + s') i) + (b.local_frame_repr e (s + s') i) := by + b.localFrame_repr e (s + s') i = + (b.localFrame_repr e (s + s') i) + (b.localFrame_repr e (s + s') i) := by by_cases hx : x ∈ e.baseSet; swap · exact False.elim (hx hxe) - simp-- [local_frame_repr] - unfold local_frame_repr + simp-- [localFrame_repr] + unfold localFrame_repr sorry -- need some _apply simp lemmas... simp [hx] end Basis @@ -104,37 +104,37 @@ end Basis -- corollary of this and uniqueness -- TODO: better name! -lemma Basis.local_frame_repr_apply_zero_at {ι : Type*} [Fintype ι] {x : M} +lemma Basis.localFrame_repr_apply_zero_at {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.local_frame_repr e s i x = 0 := sorry + b.localFrame_repr e s i x = 0 := sorry -- TODO: better name -lemma Basis.local_frame_repr_apply_zero {ι : Type*} [Fintype ι] {x : M} +lemma Basis.localFrame_repr_apply_zero {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) (i : ι) : - b.local_frame_repr e 0 i = 0 := sorry + b.localFrame_repr e 0 i = 0 := sorry /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma Basis.local_frame_repr_congr {ι : Type*} [Fintype ι] {x : M} +lemma Basis.localFrame_repr_congr {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) (hss' : s x = s' x) : - b.local_frame_repr e s i x = b.local_frame_repr e s' i x := sorry + b.localFrame_repr e s i x = b.localFrame_repr e s' i x := sorry variable {n} -lemma Basis.contMDiffAt_local_frame_repr {ι : Type*} {x : M} +lemma Basis.contMDiffAt_localFrame_repr {ι : Type*} {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.local_frame_repr e s i) x := sorry + (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e s i) x := sorry -end local_frame +end localFrame section @@ -333,14 +333,14 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I let n : ℕ := Module.finrank ℝ E let b : Basis (Fin n) ℝ E := Module.finBasis ℝ E let e := trivializationAt E (TangentSpace I) x - let Xi (i : Fin n) := b.local_frame e i + let Xi (i : Fin n) := b.localFrame e i -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. - let a := b.local_frame_repr e X + let a := b.localFrame_repr e X have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.local_frame_repr_spec this X + have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X -- have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by -- refine ⟨_, aux, by simp⟩ - have (i : Fin n) : a i x = 0 := b.local_frame_repr_apply_zero_at this hX i + have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at this hX i calc cov X σ x _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp From 97b11e8d1c1ed8bd1f17c0fddc503665e755d770 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 20:56:26 +0200 Subject: [PATCH 037/601] chore: more basic API for local frames --- .../VectorBundle/CovariantDerivative.lean | 62 +++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e3db8ee7b26bc0..eaa253fab8fe36 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -31,7 +31,9 @@ set_option linter.style.commandStart false namespace Basis -noncomputable def localFrame_toBasis_at {ι : Type*} +variable {ι : Type*} + +noncomputable def localFrame_toBasis_at (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := @@ -39,23 +41,39 @@ noncomputable def localFrame_toBasis_at {ι : Type*} open scoped Classical in -- If x is outside of `e.baseSet`, this returns the junk value 0. -noncomputable def localFrame {ι : Type*} +noncomputable def localFrame (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : ι → (x : M) → V x := fun i x ↦ -- idea: take the vector b i and apply the trivialisation e to it. if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 -lemma localFrame_toBasis_at_coe {ι : Type*} +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_apply_of_mem_baseSet + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∈ e.baseSet) : + b.localFrame e i x = b.localFrame_toBasis_at e hx i := by + simp [localFrame, hx] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_apply_of_notMem + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∉ e.baseSet) : + b.localFrame e i x = 0 := by + simp [localFrame, hx] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localFrame_toBasis_at_coe (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : - b.localFrame_toBasis_at e hx i = b.localFrame e i x := by - simp [localFrame_toBasis_at, localFrame, hx] + b.localFrame_toBasis_at e hx i = b.localFrame e i x := by simp [hx] -- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? /-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ -def isBasis_localFrame {ι : Type*} +def isBasis_localFrame (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : sorry := by @@ -66,31 +84,39 @@ def isBasis_localFrame {ι : Type*} open scoped Classical in /-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ -- If x is outside of `e.baseSet`, this returns the junk value 0. -noncomputable def localFrame_repr {ι : Type*} +noncomputable def localFrame_repr (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (s : Π x : M, V x) : ι → M → 𝕜 := fun i x ↦ if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 +variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} + +variable (e b) in +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_repr_apply_of_notMem_baseSet {x : M} + (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e s i x = 0 := by + simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim + +#exit -- uniqueness of the decomposition: will follow from the IsBasis property above -lemma localFrame_repr_spec {ι : Type*} [Fintype ι] {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) - (b : Basis ι 𝕜 F) - (s : Π x : M, V x) : + + +variable (b) in +lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x' := by have {x'} (hx : x' ∈ e.baseSet) : s x' = (∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x') := by - simp [Basis.localFrame_repr, localFrame, localFrame_toBasis_at, hx] - sorry -- some simp'ing and a property of bases + simp [Basis.localFrame_repr, hx] + exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ -- uniqueness implies this, but it also follows from our definition -lemma Basis.localFrame_repr_add {ι : Type*} [Fintype ι] {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) - (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) : +lemma Basis.localFrame_repr_add [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) + (s s' : Π x : M, V x) (i : ι) : b.localFrame_repr e (s + s') i = (b.localFrame_repr e (s + s') i) + (b.localFrame_repr e (s + s') i) := by by_cases hx : x ∈ e.baseSet; swap From 3b0abc19f4d33fd3840106631cf5c32bb41b7828 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 21:10:05 +0200 Subject: [PATCH 038/601] Fix a mis-stated lemma and prove it --- .../Manifold/VectorBundle/CovariantDerivative.lean | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index eaa253fab8fe36..778e5729953117 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -100,11 +100,8 @@ lemma localFrame_repr_apply_of_notMem_baseSet {x : M} (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e s i x = 0 := by simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim -#exit -- uniqueness of the decomposition: will follow from the IsBasis property above - - variable (b) in lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x' := by @@ -117,18 +114,15 @@ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π -- uniqueness implies this, but it also follows from our definition lemma Basis.localFrame_repr_add [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s s' : Π x : M, V x) (i : ι) : - b.localFrame_repr e (s + s') i = - (b.localFrame_repr e (s + s') i) + (b.localFrame_repr e (s + s') i) := by + b.localFrame_repr e (s + s') i x = + (b.localFrame_repr e s i x) + (b.localFrame_repr e s' i x) := by by_cases hx : x ∈ e.baseSet; swap · exact False.elim (hx hxe) - simp-- [localFrame_repr] - unfold localFrame_repr - sorry -- need some _apply simp lemmas... simp [hx] + · simp [localFrame_repr, hx] end Basis --- corollary of this and uniqueness - +-- corollary of linearity and uniqueness, or follows directly -- TODO: better name! lemma Basis.localFrame_repr_apply_zero_at {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} From bcc432885eff2bc9d1fca34d338e2c44dc5a426a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 21:19:08 +0200 Subject: [PATCH 039/601] More local frame sorries: everything but smoothness is done now --- .../VectorBundle/CovariantDerivative.lean | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 778e5729953117..78d8dfc6202c49 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -122,34 +122,46 @@ lemma Basis.localFrame_repr_add [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) end Basis +variable {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] + -- corollary of linearity and uniqueness, or follows directly -- TODO: better name! -lemma Basis.localFrame_repr_apply_zero_at {ι : Type*} [Fintype ι] {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) +lemma Basis.localFrame_repr_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.localFrame_repr e s i x = 0 := sorry + b.localFrame_repr e s i x = 0 := by + by_cases hxe : x ∈ e.baseSet; swap + · simp [localFrame_repr, hxe] + have : (e { proj := x, snd := 0 }).2 = 0 := sorry -- use linearity of e? + simp [localFrame_repr, localFrame_toBasis_at, hxe, hs, this] -- TODO: better name -lemma Basis.localFrame_repr_apply_zero {ι : Type*} [Fintype ι] {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) - (b : Basis ι 𝕜 F) (i : ι) : - b.localFrame_repr e 0 i = 0 := sorry +lemma Basis.localFrame_repr_apply_zero (b : Basis ι 𝕜 F) (i : ι) : + b.localFrame_repr e 0 i x = 0 := + b.localFrame_repr_apply_zero_at (s := 0) (by simp) i +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma Basis.localFrame_repr_congr {ι : Type*} [Fintype ι] {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) - (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) (hss' : s x = s' x) : - b.localFrame_repr e s i x = b.localFrame_repr e s' i x := sorry +lemma Basis.localFrame_repr_congr (b : Basis ι 𝕜 F) + (s s' : Π x : M, V x) (i : ι) (hss' : s x = s' x) : + b.localFrame_repr e s i x = b.localFrame_repr e s' i x := by + by_cases hxe : x ∈ e.baseSet + · simp [localFrame_repr, hxe, localFrame_toBasis_at] + congr + · simp [localFrame_repr, hxe] variable {n} -lemma Basis.contMDiffAt_localFrame_repr {ι : Type*} {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] (hxe : x ∈ e.baseSet) - (b : Basis ι 𝕜 F) +lemma Basis.continuous (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) + {s : Π x : M, V x} + (hs : ContinuousAt (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : + ContinuousAt (b.localFrame_repr e s i) x := by + unfold localFrame_repr + -- near x, we always take the positive branch... how to formalise this nicely? + sorry + +lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e s i) x := sorry @@ -360,7 +372,7 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X -- have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by -- refine ⟨_, aux, by simp⟩ - have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at this hX i + have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at hX i calc cov X σ x _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp From b86010d7dbf0a2050ab5156a9239d1edefa17daf Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 21:39:08 +0200 Subject: [PATCH 040/601] reorder; rename difference_aux -> differenceAux; sketch how to get a tensorial map --- .../VectorBundle/CovariantDerivative.lean | 72 ++++++++++++------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 78d8dfc6202c49..6f20db5ecc36fd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -316,6 +316,21 @@ lemma sum_X (cov : CovariantDerivative I F V) | empty => simp | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] +/-- A convex combination of covariant derivatives is a covariant derivative. -/ +@[simps] +def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : + CovariantDerivative I F V where + toFun X s := (t • (cov X s)) + (1 - t) • (cov' X s) + addX X X' σ := by simp only [cov.addX, cov'.addX]; module + smulX X σ f := by simp only [cov.smulX, cov'.smulX]; module + addσ X σ σ' x hσ hσ' := by + simp [cov.addσ X σ σ' x hσ hσ', cov'.addσ X σ σ' x hσ hσ'] + module + leibniz X σ f x hσ hf := by + simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] + module + do_not_read X {σ} {x} hσ := by simp [cov.do_not_read X hσ, cov'.do_not_read X hσ] + section real variable {E : Type*} [NormedAddCommGroup E] @@ -435,19 +450,21 @@ lemma congr_σ_of_eventuallyEq _ = cov X σ' x := by simp [cov.congr_σ_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] +-- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x + /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ -def difference_aux (cov cov' : CovariantDerivative I F V) : +def differenceAux (cov cov' : CovariantDerivative I F V) : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := fun X σ ↦ cov X σ - cov' X σ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in -lemma difference_aux_smul_eq (cov cov' : CovariantDerivative I F V) +lemma differenceAux_smul_eq (cov cov' : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) (hf : MDifferentiable I 𝓘(ℝ) f) : - difference_aux cov cov' X ((f : M → ℝ) • σ) = (f : M → ℝ) • (difference_aux cov cov' X σ) := + differenceAux cov cov' X ((f : M → ℝ) • σ) = (f : M → ℝ) • (differenceAux cov cov' X σ) := calc _ _ = cov X ((f : M → ℝ) • σ) - cov' X ((f : M → ℝ) • σ) := rfl _ = (f • cov X σ + (fun x ↦ bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ) @@ -460,37 +477,42 @@ lemma difference_aux_smul_eq (cov cov' : CovariantDerivative I F V) omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in -lemma difference_aux_smul_eq' (cov cov' : CovariantDerivative I F V) +lemma differenceAux_smul_eq' (cov cov' : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) : - difference_aux cov cov' (f • X) σ = (f : M → ℝ) • difference_aux cov cov' X σ := by - simp [difference_aux, cov.smulX, cov'.smulX, smul_sub] + differenceAux cov cov' (f • X) σ = (f : M → ℝ) • differenceAux cov cov' X σ := by + simp [differenceAux, cov.smulX, cov'.smulX, smul_sub] --- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. +/-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma foo (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X X' : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x₀ : M) (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) (hσ' : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x))) : - difference_aux cov cov' X σ x₀ = difference_aux cov cov' X' σ' x₀ := by - sorry -- use the previous two lemmas + differenceAux cov cov' X σ x₀ = differenceAux cov cov' X' σ' x₀ := by + -- use the previous two lemmas: they prove that differenceAux is tensorial + sorry --- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x +-- TODO: generalise this to any section in a vector bundle -end real +/-- Extend a tangent vector `X₀` at `x₀ ∈ M` to *some* vector field `X` on `M` with `X x = X₀`. -/ +def extend {x : M} (X₀ : TangentSpace I x) : (x : M) → TangentSpace I x := + -- idea: choose a local frame, and choose X to have constant coefficients in that frame + -- cap with a smooth bump function, to make it smooth everywhere + sorry -/-- A convex combination of covariant derivatives is a covariant derivative. -/ -@[simps] -def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : - CovariantDerivative I F V where - toFun X s := (t • (cov X s)) + (1 - t) • (cov' X s) - addX X X' σ := by simp only [cov.addX, cov'.addX]; module - smulX X σ f := by simp only [cov.smulX, cov'.smulX]; module - addσ X σ σ' x hσ hσ' := by - simp [cov.addσ X σ σ' x hσ hσ', cov'.addσ X σ σ' x hσ hσ'] - module - leibniz X σ f x hσ hf := by - simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] - module - do_not_read X {σ} {x} hσ := by simp [cov.do_not_read X hσ, cov'.do_not_read X hσ] +@[simp] +lemma extend_apply {x : M} (X₀ : TangentSpace I x) : (extend X₀) x = X₀ := sorry + +/-lemma-/ def contMDiff_extend {x : M} (X₀ : TangentSpace I x) : + sorry /- ContMDiff I I.tangent 2 (extend X₀) doesn't type-check -/ := sorry + +-- The difference of two covariant derivatives, as a tensorial map +def difference (cov cov' : CovariantDerivative I F V) : + Π x : M, TangentSpace I x → V x → V x := + fun x X₀ σ₀ ↦ + let σ : (x : M) → V x := sorry -- `extend σ₀` once generalized + differenceAux cov cov' (extend X₀) σ x + +end real end CovariantDerivative From 5d1eadfe05ace4c57bf5027d703b9d7102362f5c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Jun 2025 23:38:04 +0200 Subject: [PATCH 041/601] Strategy for proving smoothness: enough for today --- .../VectorBundle/CovariantDerivative.lean | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 6f20db5ecc36fd..8b7417283ddd89 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -48,6 +48,25 @@ noncomputable def localFrame -- idea: take the vector b i and apply the trivialisation e to it. if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 +/-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, +is `C^k` on `e.baseSet`. -/ +lemma contMDiffOn_localFrame_baseSet + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n + (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) e.baseSet := by + -- TODO: add contMDiffOn_section, for a set contained in a single trivialisation domain + intro x hx + refine (contMDiffWithinAt_section (localFrame e b i) e.baseSet x).mpr ?_ + apply (contMDiffWithinAt_const (c := b i)).congr_of_mem ?_ hx + intro y hy + simp [localFrame, hy, localFrame_toBasis_at] + -- TODO: add version of contMDiffFoo_section, with any compatible trivialisation! + -- then apply e there, and this should cancel like so + have almost : (e { proj := y, snd := e.symm y (b i) }).2 = b i := sorry + -- convert almost -- now, that's false + sorry + omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma localFrame_apply_of_mem_baseSet @@ -153,18 +172,25 @@ lemma Basis.localFrame_repr_congr (b : Basis ι 𝕜 F) variable {n} -lemma Basis.continuous (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) - {s : Π x : M, V x} - (hs : ContinuousAt (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : - ContinuousAt (b.localFrame_repr e s i) x := by - unfold localFrame_repr - -- near x, we always take the positive branch... how to formalise this nicely? - sorry - lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e s i) x := sorry + (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e s i) x := by + -- "check this locally, then it's very easy" + -- more precisely: (1) we have the following lemma: + -- suppose e is a compat. trivialisation and x ∈ e.baseSet, then on e.baseSet + -- b.localFrame_repr e s i equals the coefficient of "s x in trivialisation e" ∈ E for b i, + -- the RHS is (b.repr i) (s in trivialisation e).2 + -- (2) s in trivialisation e is contmdiff + -- (3) b.repr is a continuous linear map, so the composition is smooth + sorry + +lemma Basis.contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : + ContMDiffOn I 𝓘(𝕜) n (b.localFrame_repr e s i) t := + fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk + (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt end localFrame From b3509db1d96de12bf4f73953a3991578229b4c39 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 11:15:19 +0200 Subject: [PATCH 042/601] WIP: extra smoothness lemmas for sections --- .../Geometry/Manifold/VectorBundle/Basic.lean | 48 +++++++++++++++++-- .../VectorBundle/CovariantDerivative.lean | 13 ++--- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index dc3ab7e1e8357c..8c443021f48853 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -188,22 +188,62 @@ theorem contMDiffWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M} {x /-- Characterization of `C^n` functions into a vector bundle. -/ theorem contMDiffAt_totalSpace (f : M → TotalSpace F E) (x₀ : M) : ContMDiffAt IM (IB.prod 𝓘(𝕜, F)) n f x₀ ↔ - ContMDiffAt IM IB n (fun x => (f x).proj) x₀ ∧ - ContMDiffAt IM 𝓘(𝕜, F) n (fun x => (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by + ContMDiffAt IM IB n (fun x ↦ (f x).proj) x₀ ∧ + ContMDiffAt IM 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by simp_rw [← contMDiffWithinAt_univ]; exact contMDiffWithinAt_totalSpace f /-- Characterization of `C^n` sections within a set at a point of a vector bundle. -/ theorem contMDiffWithinAt_section (s : ∀ x, E x) (a : Set B) (x₀ : B) : - ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (fun x => TotalSpace.mk' F x (s x)) a x₀ ↔ + ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a x₀ ↔ ContMDiffWithinAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) a x₀ := by simp_rw [contMDiffWithinAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffWithinAt_id +theorem contMDiffWithinAt_section_of_mem_BaseSet (s : ∀ x, E x) (a : Set B) {x₀ : B} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : + ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a x₀ ↔ + ContMDiffWithinAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a x₀ := by + sorry + /-- Characterization of `C^n` sections of a vector bundle. -/ theorem contMDiffAt_section (s : ∀ x, E x) (x₀ : B) : - ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x => TotalSpace.mk' F x (s x)) x₀ ↔ + ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) x₀ := by simp_rw [contMDiffAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffAt_id +-- XXX: naming and doc comment! +/-- Continuity of a `C^n` section at `x` can be shown against any trivialisation whose `baseSet` +contains `x` -/ +theorem contMDiffAt_section_of_mem_baseSet (s : ∀ x, E x) {x₀ : B} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : + ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ + ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by + sorry + +theorem contMDiffOn_section_of_mem_baseSet2 (s : ∀ x, E x) {a : Set B} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : + ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ + ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a := by + -- golfing useful? + constructor + · intro h x hx + have : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x := + (h x hx).contMDiffAt <| ha.mem_nhds hx + exact ((contMDiffAt_section_of_mem_baseSet s e (ha' hx)).mp this).contMDiffWithinAt + · intro h x hx + have : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e { proj := x, snd := s x }).2) x := + (h x hx).contMDiffAt <| ha.mem_nhds hx + exact ((contMDiffAt_section_of_mem_baseSet s e (ha' hx)).mpr this).contMDiffWithinAt + +theorem contMDiffOn_section_of_mem_baseSet (s : ∀ x, E x) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] : + ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := + contMDiffOn_section_of_mem_baseSet2 s e (a := e.baseSet) e.open_baseSet (subset_refl _) + variable (E) theorem contMDiff_proj : ContMDiff (IB.prod 𝓘(𝕜, F)) IB n (π F E) := fun x ↦ by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 8b7417283ddd89..918a33ca861b43 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -55,16 +55,11 @@ lemma contMDiffOn_localFrame_baseSet [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) e.baseSet := by - -- TODO: add contMDiffOn_section, for a set contained in a single trivialisation domain - intro x hx - refine (contMDiffWithinAt_section (localFrame e b i) e.baseSet x).mpr ?_ - apply (contMDiffWithinAt_const (c := b i)).congr_of_mem ?_ hx + rw [contMDiffOn_section_of_mem_baseSet] + apply (contMDiffOn_const (c := b i)).congr intro y hy simp [localFrame, hy, localFrame_toBasis_at] - -- TODO: add version of contMDiffFoo_section, with any compatible trivialisation! - -- then apply e there, and this should cancel like so - have almost : (e { proj := y, snd := e.symm y (b i) }).2 = b i := sorry - -- convert almost -- now, that's false + guard_target = (e { proj := y, snd := e.symm y (b i) }).2 = b i -- should be obvious sorry omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @@ -152,7 +147,7 @@ lemma Basis.localFrame_repr_apply_zero_at b.localFrame_repr e s i x = 0 := by by_cases hxe : x ∈ e.baseSet; swap · simp [localFrame_repr, hxe] - have : (e { proj := x, snd := 0 }).2 = 0 := sorry -- use linearity of e? + have : (e { proj := x, snd := 0 }).2 = 0 := sorry -- same sorry as above simp [localFrame_repr, localFrame_toBasis_at, hxe, hs, this] -- TODO: better name From 4ba5b93f32fd7f040d7683dce43a003e90d75105 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 26 Jun 2025 16:02:42 +0200 Subject: [PATCH 043/601] Remove one sorry --- .../Manifold/VectorBundle/CovariantDerivative.lean | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 918a33ca861b43..9d8ecc4629ba1c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -48,6 +48,12 @@ noncomputable def localFrame -- idea: take the vector b i and apply the trivialisation e to it. if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 +-- TODO: understand why this isn’t already a simp lemma +attribute [simp] Trivialization.apply_mk_symm + +omit [IsManifold I 0 M] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [ContMDiffVectorBundle n F V I] in /-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_localFrame_baseSet @@ -59,8 +65,6 @@ lemma contMDiffOn_localFrame_baseSet apply (contMDiffOn_const (c := b i)).congr intro y hy simp [localFrame, hy, localFrame_toBasis_at] - guard_target = (e { proj := y, snd := e.symm y (b i) }).2 = b i -- should be obvious - sorry omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] From 8e6cbf8b21b3258c901cd70b4c1a1b247635f53f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 11:24:06 +0200 Subject: [PATCH 044/601] Polish --- .../Geometry/Manifold/VectorBundle/Basic.lean | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 8c443021f48853..7e5a9d836a4751 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -211,17 +211,18 @@ theorem contMDiffAt_section (s : ∀ x, E x) (x₀ : B) : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) x₀ := by simp_rw [contMDiffAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffAt_id --- XXX: naming and doc comment! -/-- Continuity of a `C^n` section at `x` can be shown against any trivialisation whose `baseSet` -contains `x` -/ +/-- Continuity of a `C^n` section at `x` can be determined +using any trivialisation whose `baseSet` contains `x`. -/ theorem contMDiffAt_section_of_mem_baseSet (s : ∀ x, E x) {x₀ : B} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by - sorry + sorry -- use the WithinAt version -theorem contMDiffOn_section_of_mem_baseSet2 (s : ∀ x, E x) {a : Set B} +/-- Continuity of a `C^n` section on `s` can be determined +using any trivialisation whose `baseSet` contains `s`. -/ +theorem contMDiffOn_section_of_mem_baseSet (s : ∀ x, E x) {a : Set B} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ @@ -237,12 +238,14 @@ theorem contMDiffOn_section_of_mem_baseSet2 (s : ∀ x, E x) {a : Set B} (h x hx).contMDiffAt <| ha.mem_nhds hx exact ((contMDiffAt_section_of_mem_baseSet s e (ha' hx)).mpr this).contMDiffWithinAt -theorem contMDiffOn_section_of_mem_baseSet (s : ∀ x, E x) +/-- For any trivialization `e`, the continuity of a `C^n` section on `e.baseSet` +can be determined using `e`. -/ +theorem contMDiffOn_section_of_mem_baseSet₀ (s : ∀ x, E x) (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) [MemTrivializationAtlas e] : ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := - contMDiffOn_section_of_mem_baseSet2 s e (a := e.baseSet) e.open_baseSet (subset_refl _) + contMDiffOn_section_of_mem_baseSet s e e.open_baseSet (subset_refl _) variable (E) From 50f5963474033e1a3031e94c05e92bec50142ebd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 16:35:21 +0200 Subject: [PATCH 045/601] One more sorry --- .../Manifold/VectorBundle/CovariantDerivative.lean | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 9d8ecc4629ba1c..e5f6c533b60c54 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -61,7 +61,7 @@ lemma contMDiffOn_localFrame_baseSet [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) e.baseSet := by - rw [contMDiffOn_section_of_mem_baseSet] + rw [contMDiffOn_section_of_mem_baseSet₀] apply (contMDiffOn_const (c := b i)).congr intro y hy simp [localFrame, hy, localFrame_toBasis_at] @@ -151,8 +151,13 @@ lemma Basis.localFrame_repr_apply_zero_at b.localFrame_repr e s i x = 0 := by by_cases hxe : x ∈ e.baseSet; swap · simp [localFrame_repr, hxe] - have : (e { proj := x, snd := 0 }).2 = 0 := sorry -- same sorry as above - simp [localFrame_repr, localFrame_toBasis_at, hxe, hs, this] + simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] + have : e.symm x = 0 := sorry + have : (e { proj := x, snd := 0 }).2 = 0 := by + trans (e { proj := x, snd := e.symm x 0 }).2 + · simp [this] + · simp [e.apply_mk_symm hxe] + simp [this] -- TODO: better name lemma Basis.localFrame_repr_apply_zero (b : Basis ι 𝕜 F) (i : ι) : From 8579e042a2a7532c367691ce7259dab37e602e42 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 17:27:10 +0200 Subject: [PATCH 046/601] refactor: make the coefficients in a local frame a linear map --- .../VectorBundle/CovariantDerivative.lean | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e5f6c533b60c54..26d7a818b960d2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -102,11 +102,19 @@ def isBasis_localFrame open scoped Classical in /-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ -- If x is outside of `e.baseSet`, this returns the junk value 0. +-- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate +-- cases. noncomputable def localFrame_repr (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) (s : Π x : M, V x) : ι → M → 𝕜 := - fun i x ↦ if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 + (b : Basis ι 𝕜 F) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where + toFun s x := if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 + map_add' s s' := by + ext x + by_cases hx : x ∈ e.baseSet <;> simp [hx] + map_smul' c s := by + ext x + by_cases hx : x ∈ e.baseSet <;> simp [hx] variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} @@ -115,29 +123,28 @@ variable (e b) in omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma localFrame_repr_apply_of_notMem_baseSet {x : M} - (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e s i x = 0 := by + (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e i s x = 0 := by simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim --- uniqueness of the decomposition: will follow from the IsBasis property above +variable (e b) in +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_repr_apply_of_mem_baseSet {x : M} + (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : + b.localFrame_repr e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by + simp [localFrame_repr, hx] + +-- uniqueness of the decomposition: follows from the IsBasis property above variable (b) in lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x' := by + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := by have {x'} (hx : x' ∈ e.baseSet) : - s x' = (∑ i, (b.localFrame_repr e s i x') • b.localFrame e i x') := by + s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by simp [Basis.localFrame_repr, hx] exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ --- uniqueness implies this, but it also follows from our definition -lemma Basis.localFrame_repr_add [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) - (s s' : Π x : M, V x) (i : ι) : - b.localFrame_repr e (s + s') i x = - (b.localFrame_repr e s i x) + (b.localFrame_repr e s' i x) := by - by_cases hx : x ∈ e.baseSet; swap - · exact False.elim (hx hxe) - · simp [localFrame_repr, hx] - end Basis variable {ι : Type*} [Fintype ι] {x : M} @@ -148,7 +155,7 @@ variable {ι : Type*} [Fintype ι] {x : M} -- TODO: better name! lemma Basis.localFrame_repr_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.localFrame_repr e s i x = 0 := by + b.localFrame_repr e i s x = 0 := by by_cases hxe : x ∈ e.baseSet; swap · simp [localFrame_repr, hxe] simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] @@ -159,16 +166,11 @@ lemma Basis.localFrame_repr_apply_zero_at · simp [e.apply_mk_symm hxe] simp [this] --- TODO: better name -lemma Basis.localFrame_repr_apply_zero (b : Basis ι 𝕜 F) (i : ι) : - b.localFrame_repr e 0 i x = 0 := - b.localFrame_repr_apply_zero_at (s := 0) (by simp) i - omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma Basis.localFrame_repr_congr (b : Basis ι 𝕜 F) (s s' : Π x : M, V x) (i : ι) (hss' : s x = s' x) : - b.localFrame_repr e s i x = b.localFrame_repr e s' i x := by + b.localFrame_repr e i s x = b.localFrame_repr e i s' x := by by_cases hxe : x ∈ e.baseSet · simp [localFrame_repr, hxe, localFrame_toBasis_at] congr @@ -179,7 +181,7 @@ variable {n} lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e s i) x := by + (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e i s) x := by -- "check this locally, then it's very easy" -- more precisely: (1) we have the following lemma: -- suppose e is a compat. trivialisation and x ∈ e.baseSet, then on e.baseSet @@ -192,7 +194,7 @@ lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι lemma Basis.contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : - ContMDiffOn I 𝓘(𝕜) n (b.localFrame_repr e s i) t := + ContMDiffOn I 𝓘(𝕜) n (b.localFrame_repr e i s) t := fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt @@ -412,7 +414,7 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I let e := trivializationAt E (TangentSpace I) x let Xi (i : Fin n) := b.localFrame e i -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. - let a := b.localFrame_repr e X + let a := fun i ↦ b.localFrame_repr e i X have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X -- have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by From 6b6bc68f0ef9397b6dee2f28a37b73a8d8ed3a94 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 17:31:48 +0200 Subject: [PATCH 047/601] Side-step one sorry with a shorter proof and fix a few trivial warnings --- .../VectorBundle/CovariantDerivative.lean | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 26d7a818b960d2..18a57d75115321 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -136,6 +136,7 @@ lemma localFrame_repr_apply_of_mem_baseSet {x : M} -- uniqueness of the decomposition: follows from the IsBasis property above +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in variable (b) in lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := by @@ -151,31 +152,33 @@ variable {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] --- corollary of linearity and uniqueness, or follows directly --- TODO: better name! -lemma Basis.localFrame_repr_apply_zero_at - (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.localFrame_repr e i s x = 0 := by - by_cases hxe : x ∈ e.baseSet; swap - · simp [localFrame_repr, hxe] - simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] - have : e.symm x = 0 := sorry - have : (e { proj := x, snd := 0 }).2 = 0 := by - trans (e { proj := x, snd := e.symm x 0 }).2 - · simp [this] - · simp [e.apply_mk_symm hxe] - simp [this] - omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma Basis.localFrame_repr_congr (b : Basis ι 𝕜 F) - (s s' : Π x : M, V x) (i : ι) (hss' : s x = s' x) : + {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : b.localFrame_repr e i s x = b.localFrame_repr e i s' x := by by_cases hxe : x ∈ e.baseSet · simp [localFrame_repr, hxe, localFrame_toBasis_at] congr · simp [localFrame_repr, hxe] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in +lemma Basis.localFrame_repr_apply_zero_at + (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : + b.localFrame_repr e i s x = 0 := by + rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] + simp + -- This proof may indicate a missing simp lemma. + -- by_cases hxe : x ∈ e.baseSet; swap + -- · simp [localFrame_repr, hxe] + -- simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] + -- have : e.symm x = 0 := sorry + -- have : (e { proj := x, snd := 0 }).2 = 0 := by + -- trans (e { proj := x, snd := e.symm x 0 }).2 + -- · simp [this] + -- · simp [e.apply_mk_symm hxe] + -- simp [this] + variable {n} lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) @@ -192,7 +195,8 @@ lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι sorry lemma Basis.contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} + (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : ContMDiffOn I 𝓘(𝕜) n (b.localFrame_repr e i s) t := fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk From 88c434d3926c62611952084bc55a831dea80dc1c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 18:02:18 +0200 Subject: [PATCH 048/601] Progress on smoothness proof for frame coefficients --- .../VectorBundle/CovariantDerivative.lean | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 18a57d75115321..e9d5d22d746e8d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -181,15 +181,30 @@ lemma Basis.localFrame_repr_apply_zero_at variable {n} +-- TODO: good name! +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in +/-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. +Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` +equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ +lemma foo (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : + b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by + simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] + lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e i s) x := by -- "check this locally, then it's very easy" - -- more precisely: (1) we have the following lemma: - -- suppose e is a compat. trivialisation and x ∈ e.baseSet, then on e.baseSet - -- b.localFrame_repr e s i equals the coefficient of "s x in trivialisation e" ∈ E for b i, - -- the RHS is (b.repr i) (s in trivialisation e).2 + classical + -- step 1: on e.baseSet, can compute this expression very well + let aux := fun x ↦ b.repr (e (s x)).2 i + -- Since e.baseSet is open, this is sufficient. + suffices ContMDiffAt I 𝓘(𝕜) n aux x by + apply this.congr_of_eventuallyEq_of_mem ?_ trivial + apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) + intro y hy + simp [aux, hy, foo hy] + simp only [aux] -- (2) s in trivialisation e is contmdiff -- (3) b.repr is a continuous linear map, so the composition is smooth sorry From 8b445aff9c8e98c827f237c09042f24e112ff394 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 26 Jun 2025 18:43:00 +0200 Subject: [PATCH 049/601] Extend vectors to sections --- .../VectorBundle/CovariantDerivative.lean | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e9d5d22d746e8d..f7527ce7c8bdff 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -542,26 +542,35 @@ lemma foo (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M -- use the previous two lemmas: they prove that differenceAux is tensorial sorry --- TODO: generalise this to any section in a vector bundle - -/-- Extend a tangent vector `X₀` at `x₀ ∈ M` to *some* vector field `X` on `M` with `X x = X₀`. -/ -def extend {x : M} (X₀ : TangentSpace I x) : (x : M) → TangentSpace I x := - -- idea: choose a local frame, and choose X to have constant coefficients in that frame - -- cap with a smooth bump function, to make it smooth everywhere - sorry - -@[simp] -lemma extend_apply {x : M} (X₀ : TangentSpace I x) : (extend X₀) x = X₀ := sorry +-- TODO: either change `localFrame` to make sure it is everywhere smooth +-- or introduce a cut-off here. First option is probaly better. +variable (F) in +noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) → V x' := + letI b := Basis.ofVectorSpace ℝ F + letI t := trivializationAt F V x + letI bV := b.localFrame_toBasis_at t (FiberBundle.mem_baseSet_trivializationAt F V x) + fun x' ↦ ∑ i, bV.repr v i • b.localFrame t i x' + +-- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : + extend F v x = v := by + letI b := Basis.ofVectorSpace ℝ F + letI t := trivializationAt F V x + have x_mem : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt F V x + letI bV := b.localFrame_toBasis_at t x_mem + change ∑ i, bV.repr v i • b.localFrame t i x = v + conv_rhs => rw [←bV.sum_repr v] + simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] /-lemma-/ def contMDiff_extend {x : M} (X₀ : TangentSpace I x) : sorry /- ContMDiff I I.tangent 2 (extend X₀) doesn't type-check -/ := sorry -- The difference of two covariant derivatives, as a tensorial map -def difference (cov cov' : CovariantDerivative I F V) : +noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] + (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := - fun x X₀ σ₀ ↦ - let σ : (x : M) → V x := sorry -- `extend σ₀` once generalized - differenceAux cov cov' (extend X₀) σ x + fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x end real From 37f0d5b6592fe71013d984dc6f3edcd0089acb56 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 26 Jun 2025 19:02:57 +0200 Subject: [PATCH 050/601] Further progress, and mild clean-up --- .../VectorBundle/CovariantDerivative.lean | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index f7527ce7c8bdff..fbd3cf59bcde91 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -146,15 +146,13 @@ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ -end Basis - variable {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma Basis.localFrame_repr_congr (b : Basis ι 𝕜 F) +lemma localFrame_repr_congr (b : Basis ι 𝕜 F) {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : b.localFrame_repr e i s x = b.localFrame_repr e i s' x := by by_cases hxe : x ∈ e.baseSet @@ -163,7 +161,7 @@ lemma Basis.localFrame_repr_congr (b : Basis ι 𝕜 F) · simp [localFrame_repr, hxe] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in -lemma Basis.localFrame_repr_apply_zero_at +lemma localFrame_repr_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : b.localFrame_repr e i s x = 0 := by rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] @@ -181,42 +179,55 @@ lemma Basis.localFrame_repr_apply_zero_at variable {n} --- TODO: good name! omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ -lemma foo (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : +lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] -lemma Basis.contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) +lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : ContMDiffAt I 𝓘(𝕜) n (b.localFrame_repr e i s) x := by - -- "check this locally, then it's very easy" + (i : ι) : ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x := by + -- This boils down to computing the frame coefficients in a local trivialisation. classical - -- step 1: on e.baseSet, can compute this expression very well + -- step 1: on e.baseSet, can compute the coefficient very well let aux := fun x ↦ b.repr (e (s x)).2 i -- Since e.baseSet is open, this is sufficient. - suffices ContMDiffAt I 𝓘(𝕜) n aux x by + suffices ContMDiffAt I 𝓘(𝕜) k aux x by apply this.congr_of_eventuallyEq_of_mem ?_ trivial apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, hy, foo hy] + simp [aux, hy, Basis.localFrame_repr_eq_repr hy] simp only [aux] - -- (2) s in trivialisation e is contmdiff - -- (3) b.repr is a continuous linear map, so the composition is smooth - sorry -lemma Basis.contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) + -- step 2: `s` read in trivialization `e` is `C^k` + have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by + -- XXX: make e and s implicit! + rw [contMDiffAt_section_of_mem_baseSet _ _ hxe] at hs + exact hs + -- step 3: `b.repr` is a linear map, so the composition is smooth + let bas := fun v ↦ b.repr v i + have : IsLinearMap 𝕜 bas := sorry + have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k bas (e (s x)).2 := by + -- exact? should do it now + sorry + exact hbas.comp x h₁ + +-- XXX: upgrade the above proof to contMDiffOn, and deduce contMDiffAt from it? + +lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : - ContMDiffOn I 𝓘(𝕜) n (b.localFrame_repr e i s) t := + ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt +end Basis + end localFrame section From 83cee9f49870edf9155f531026aa14d51e00e6fd Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Jun 2025 13:42:25 +0200 Subject: [PATCH 051/601] Remove one sorry --- .../Manifold/VectorBundle/CovariantDerivative.lean | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index fbd3cf59bcde91..4ac389d7cb438b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -594,11 +594,16 @@ section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] +-- TODO: cleanup @[simp] theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ DifferentiableAt 𝕜 σ e := by - sorry + rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace, + mdifferentiableWithinAt_univ, mdifferentiableWithinAt_univ] + change MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E) id e ∧ MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') σ e ↔ + DifferentiableAt 𝕜 σ e + simp [mdifferentiableAt_id, mdifferentiableAt_iff_differentiableAt] attribute [simp] mdifferentiableAt_iff_differentiableAt From 5fcb493b143a86ad5f6988fed4884ab5a30be8d6 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Jun 2025 14:39:22 +0200 Subject: [PATCH 052/601] General covariant derivative in local case --- .../VectorBundle/CovariantDerivative.lean | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 4ac389d7cb438b..7fd5bd635a90fe 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -626,4 +626,31 @@ noncomputable def CovariantDerivative.trivial : CovariantDerivative 𝓘(𝕜, E rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ simp [fderiv_zero_of_not_differentiableAt hσ] +open Classical in +@[simps] +noncomputable def CovariantDerivative.of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : + CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where + toFun X σ := fun x ↦ if DifferentiableAt 𝕜 σ x then fderiv 𝕜 σ x (X x) + A x (X x) (σ x) else 0 + addX X X' σ := by + ext x + by_cases h : DifferentiableAt 𝕜 σ x + · simp [h, map_add]; abel + · simp [h] + smulX X σ c' := by ext; simp + addσ X σ σ' e hσ hσ' := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' + rw [fderiv_add hσ hσ'] + simp [hσ, hσ'] + abel + leibniz X σ f x hσ hf := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ + rw [mdifferentiableAt_iff_differentiableAt] at hf + have h : DifferentiableAt 𝕜 (f • σ) x := hf.smul hσ + have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := + fderiv_smul (by simp_all) (by simp_all) + simp [this, bar, hσ, h] + module + do_not_read X σ x hσ := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ + simp [hσ] end From d29bf2af7c52e70c6e3bfbb1576139f5b812dc1b Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Jun 2025 14:57:56 +0200 Subject: [PATCH 053/601] State contMDiff_extend --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 7fd5bd635a90fe..026c05ffed7265 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -574,8 +574,9 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ conv_rhs => rw [←bV.sum_repr v] simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] -/-lemma-/ def contMDiff_extend {x : M} (X₀ : TangentSpace I x) : - sorry /- ContMDiff I I.tangent 2 (extend X₀) doesn't type-check -/ := sorry +lemma contMDiff_extend [FiniteDimensional ℝ F] {x : M} (σ₀ : V x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend F σ₀ x)) := by + sorry -- The difference of two covariant derivatives, as a tensorial map noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] From 6e2ca546b1beb7f98f6c51bf84548822a3276752 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 15:09:23 +0200 Subject: [PATCH 054/601] feat/WIP: add diffgeo cheat sheet --- Mathlib/Geometry/Manifold/CheatSheet.md | 80 +++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Mathlib/Geometry/Manifold/CheatSheet.md diff --git a/Mathlib/Geometry/Manifold/CheatSheet.md b/Mathlib/Geometry/Manifold/CheatSheet.md new file mode 100644 index 00000000000000..881259a7c17545 --- /dev/null +++ b/Mathlib/Geometry/Manifold/CheatSheet.md @@ -0,0 +1,80 @@ +## Differential geometry cheat sheet + +How do I say certain basic things in Lean? +For each of them, include a variable block. Can verso do this already? + + +Let M be a C^k manifold. +``` +variable {𝕜 E M H : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] + [NormedSpace 𝕜 E] [TopologicalSpace H] [TopologicalSpace M] {k : ℕ} -- more general: take k : WithTop ℕ∞, allows smooth and analytic; remove WithTop to exclude analyticity + {I : ModelWithCorners 𝕜 E H} [ChartedSpace H M] [IsManifold I k M] +``` + +Let M be a smooth manifold +``` +variable {𝕜 E M H : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] + [NormedSpace 𝕜 E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners 𝕜 E H} [ChartedSpace H M] [IsManifold I ∞ M] +``` + +Let M be a smooth real manifold. +``` +variable {E M H : Type*} [NormedAddCommGroup E] + [NormedSpace ℝ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners ℝ E H} [ChartedSpace H M] [IsManifold I ∞ M] -- test, needs open scoped Manifold?? +``` + +Let M be an analytic manifold +``` +open scoped Manifold -- test, necessary? + +variable {𝕜 E M H : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] + [NormedSpace 𝕜 E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners 𝕜 E H} [ChartedSpace H M] [IsManifold I ω M] +``` + +Let f : M \to N be smooth. +Let f : M \to E (a normed space) be smooth. + +Consider the product manifold M \times N. + + +Let \phi be the preferred chart at x\in M. + +Let \phi be any (compatible) chart on M. + +-------- + +Let E\to M be a topological vector bundle. + +Let E\to M be a smooth vector bundle. + +Let s be a section of E. +Let s be a C^k section of E. / The section s of E is C^k. + + +Let \phi be the preferred local trivialisation at x\in E. +Let \phi be any compatible trivialisation on M. + +Consider the tangent bundle TM of M. + +Let X be a C^k vector field on M. + + +explain TotalSpace.mk' somewhere in here... + + + +**Basic API lemmas** +- testing smoothness of a map in charts: the standard charts; any charts + +- testing smoothness of a section in trivialisations: the standard charts; any charts + + +**constructions** +- product manifold (tricky!) +- disjoint union + +- product bundle (how difficult?) +- Lie bracket of vector fields From 41fa685a6317ec74ef39db793af0d92a72db1888 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 15:33:25 +0200 Subject: [PATCH 055/601] feat: better version of fderiv_const_smul --- Mathlib/Analysis/Calculus/FDeriv/Add.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/Analysis/Calculus/FDeriv/Add.lean b/Mathlib/Analysis/Calculus/FDeriv/Add.lean index 791139c7a4147f..b669779d7db8bb 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Add.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Add.lean @@ -5,6 +5,7 @@ Authors: Jeremy Avigad, Sébastien Gouëzel, Yury Kudryashov -/ import Mathlib.Analysis.Calculus.FDeriv.Linear import Mathlib.Analysis.Calculus.FDeriv.Comp +import Mathlib.Analysis.Calculus.FDeriv.Const /-! # Additive operations on derivatives @@ -136,6 +137,22 @@ theorem fderiv_const_smul (h : DifferentiableAt 𝕜 f x) (c : R) : fderiv 𝕜 (c • f) x = c • fderiv 𝕜 f x := (h.hasFDerivAt.const_smul c).fderiv +/-- A version of `fderiv_const_smul` without differentiability hypothesis: in return, the constant +`c` must be invertible, i.e. if `R` is a field. -/ +theorem fderiv_const_smul'' (c : R) [Invertible c] : + fderiv 𝕜 (c • f) x = c • fderiv 𝕜 f x := by + by_cases h : DifferentiableAt 𝕜 f x + · exact (h.hasFDerivAt.const_smul c).fderiv + · obtain (rfl | hc) := eq_or_ne c 0 + · simp [fderiv_zero] + -- make a separate lemma: f is differentiable at x iff c • f is? + have : ¬DifferentiableAt 𝕜 (c • f) x := by + contrapose! h + apply (h.const_smul ⅟ c).congr_of_eventuallyEq + filter_upwards with x + simp + simp [fderiv_zero_of_not_differentiableAt h, fderiv_zero_of_not_differentiableAt this] + @[deprecated (since := "2025-06-14")] alias fderiv_const_smul' := fderiv_const_smul end ConstSMul From 0f0d76a074aa9e9719cfcd783927f74b57628b9b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 15:55:26 +0200 Subject: [PATCH 056/601] refactor: replace do_not_read axiom by smul_const_sigma - The do_not_read axiom was basically only used for smul_const_sigma. - It would complicate the definition of CovariantDerivative.of_endomorphism, as for non-differentiable sigma, the naive formula would yield A sigma and not 0. Luckily, we don't need that particular relation at all. - The new proofs are mathematically very same to the old ones, just extracted into a different lemma. --- .../VectorBundle/CovariantDerivative.lean | 62 ++++++------------- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 026c05ffed7265..eaa72376e99168 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -268,8 +268,8 @@ structure CovariantDerivative where MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → MDifferentiableAt I 𝓘(𝕜) f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) f x (X x)) • σ x - do_not_read : ∀ (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M}, - ¬ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → toFun X σ x = 0 + smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), + toFun X (a • σ) = a • toFun X σ namespace CovariantDerivative @@ -303,33 +303,6 @@ lemma _root_.FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma smul_const_σ (cov : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) : - cov X (a • σ) = a • cov X σ := by - ext x - by_cases hσ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x - · simpa using cov.leibniz X σ (fun _ ↦ a) x hσ mdifferentiable_const.mdifferentiableAt - have hσ₂ : cov X (a • σ) x = 0 := by - by_cases ha: a = 0 - · simp [ha] - refine cov.do_not_read X ?_ - contrapose! hσ - have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a⁻¹ • a • σ x)) x := by - rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace] at * - refine ⟨mdifferentiableAt_id, ?_⟩ - have : ∀ᶠ x' in 𝓝 x, ((trivializationAt F V x) ⟨x', a⁻¹ • a • σ x'⟩).2 = - a⁻¹ • ((trivializationAt F V x) ⟨x', a • σ x'⟩).2 := by - filter_upwards [FiberBundle.trivializationAt.baseSet_mem_nhds F V x] with x' hx' - exact (trivializationAt F V x).linear 𝕜 hx' |>.map_smul a⁻¹ (a • σ x') - exact MDifferentiableAt.const_smul hσ.2 a⁻¹ |>.congr_of_eventuallyEq this - apply this.congr_of_eventuallyEq - filter_upwards with x - simp [ha] - simp [cov.do_not_read X hσ, hσ₂] - omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in variable {I F V} in @@ -388,10 +361,12 @@ def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : addσ X σ σ' x hσ hσ' := by simp [cov.addσ X σ σ' x hσ hσ', cov'.addσ X σ σ' x hσ hσ'] module + smul_const_σ X {σ x} /-hσ-/ := by + simp [cov.smul_const_σ, cov'.smul_const_σ] + module leibniz X σ f x hσ hf := by simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] module - do_not_read X {σ} {x} hσ := by simp [cov.do_not_read X hσ, cov'.do_not_read X hσ] section real @@ -417,8 +392,6 @@ lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) (hσσ' : ∀ x ∈ s, X x = X' x) : cov X σ x = cov X' σ x := by - by_cases hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x; swap - · simp [cov.do_not_read X hσ, cov.do_not_read X' hσ] -- Choose a smooth bump function ψ with support around `x` contained in `s` obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs -- Observe that `ψ • X = ψ • X'` as dependent functions. @@ -447,8 +420,6 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I let a := fun i ↦ b.localFrame_repr e i X have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X - -- have realAux : ∃ s : Set M, (s ∈ nhds x ∧ ∀ x' ∈ s, X x' = ∑ i, a i x' • Xi i x') := by - -- refine ⟨_, aux, by simp⟩ have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at hX i calc cov X σ x _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) @@ -608,6 +579,16 @@ theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) ( attribute [simp] mdifferentiableAt_iff_differentiableAt +-- XXX: make a better version of fderiv_const_smul'', with field coefficients instead! +theorem _root_.fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField 𝕜] + [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + (σ : (x : E) → Trivial E E' x) (a : 𝕜) (x : E) : + fderiv 𝕜 (a • σ) x = a • fderiv 𝕜 σ x := by + obtain (rfl | ha) := eq_or_ne a 0 + · simp + · have : Invertible a := invertibleOfNonzero ha + exact fderiv_const_smul'' .. + @[simps] noncomputable def CovariantDerivative.trivial : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where @@ -618,31 +599,30 @@ noncomputable def CovariantDerivative.trivial : CovariantDerivative 𝓘(𝕜, E rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' rw [fderiv_add hσ hσ'] rfl + smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] leibniz X σ f x hσ hf := by have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := fderiv_smul (by simp_all) (by simp_all) simp [this, bar] rfl - do_not_read X σ x hσ := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ - simp [fderiv_zero_of_not_differentiableAt hσ] open Classical in @[simps] noncomputable def CovariantDerivative.of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where - toFun X σ := fun x ↦ if DifferentiableAt 𝕜 σ x then fderiv 𝕜 σ x (X x) + A x (X x) (σ x) else 0 + toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) addX X X' σ := by ext x by_cases h : DifferentiableAt 𝕜 σ x · simp [h, map_add]; abel - · simp [h] + · simp [fderiv_zero_of_not_differentiableAt h] smulX X σ c' := by ext; simp addσ X σ σ' e hσ hσ' := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' rw [fderiv_add hσ hσ'] simp [hσ, hσ'] abel + smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] leibniz X σ f x hσ hf := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ rw [mdifferentiableAt_iff_differentiableAt] at hf @@ -651,7 +631,5 @@ noncomputable def CovariantDerivative.of_endomorphism (A : E → E →L[𝕜] E' fderiv_smul (by simp_all) (by simp_all) simp [this, bar, hσ, h] module - do_not_read X σ x hσ := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ - simp [hσ] + end From 9a2295b14a16bec9fc58c19bb20a06a3b87c0fa9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 16:39:15 +0200 Subject: [PATCH 057/601] refactor: move local frames material to a new file --- Mathlib.lean | 2 + .../VectorBundle/CovariantDerivative.lean | 232 +----------------- .../Manifold/VectorBundle/LocalFrame.lean | 230 +++++++++++++++++ 3 files changed, 245 insertions(+), 219 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean diff --git a/Mathlib.lean b/Mathlib.lean index a11f4d168ff07b..106b40f56b36b5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3701,8 +3701,10 @@ import Mathlib.Geometry.Manifold.Sheaf.Basic import Mathlib.Geometry.Manifold.Sheaf.LocallyRingedSpace import Mathlib.Geometry.Manifold.Sheaf.Smooth import Mathlib.Geometry.Manifold.VectorBundle.Basic +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear import Mathlib.Geometry.Manifold.VectorBundle.Hom +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.Pullback import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index eaa72376e99168..2755c24641743a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1,234 +1,28 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -open Bundle Filter Function Topology - -open scoped Bundle Manifold ContDiff - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - -section localFrame - -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] - -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -- `F` model fiber - (n : WithTop ℕ∞) - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul 𝕜 (V x)] - [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] - -- `V` vector bundle +/-! +# Covariant derivatives -set_option linter.style.commandStart false - -namespace Basis - -variable {ι : Type*} - -noncomputable def localFrame_toBasis_at - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := - b.map (e.linearEquivAt (R := 𝕜) x hx).symm - -open scoped Classical in --- If x is outside of `e.baseSet`, this returns the junk value 0. -noncomputable def localFrame - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) : ι → (x : M) → V x := fun i x ↦ - -- idea: take the vector b i and apply the trivialisation e to it. - if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 - --- TODO: understand why this isn’t already a simp lemma -attribute [simp] Trivialization.apply_mk_symm - -omit [IsManifold I 0 M] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle n F V I] in -/-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, -is `C^k` on `e.baseSet`. -/ -lemma contMDiffOn_localFrame_baseSet - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n - (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) e.baseSet := by - rw [contMDiffOn_section_of_mem_baseSet₀] - apply (contMDiffOn_const (c := b i)).congr - intro y hy - simp [localFrame, hy, localFrame_toBasis_at] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -@[simp] -lemma localFrame_apply_of_mem_baseSet - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∈ e.baseSet) : - b.localFrame e i x = b.localFrame_toBasis_at e hx i := by - simp [localFrame, hx] +TODO: add a more complete doc-string -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -@[simp] -lemma localFrame_apply_of_notMem - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∉ e.baseSet) : - b.localFrame e i x = 0 := by - simp [localFrame, hx] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma localFrame_toBasis_at_coe - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : - b.localFrame_toBasis_at e hx i = b.localFrame e i x := by simp [hx] - --- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? -/-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ -def isBasis_localFrame - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) : sorry := by - -- the b i form a basis of F, - -- and the trivialisation e is a linear equivalence (thus preserves bases) - sorry +-/ -open scoped Classical in -/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ --- If x is outside of `e.baseSet`, this returns the junk value 0. --- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate --- cases. -noncomputable def localFrame_repr - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where - toFun s x := if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 - map_add' s s' := by - ext x - by_cases hx : x ∈ e.baseSet <;> simp [hx] - map_smul' c s := by - ext x - by_cases hx : x ∈ e.baseSet <;> simp [hx] - -variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} +open Bundle Filter Function Topology -variable (e b) in -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -@[simp] -lemma localFrame_repr_apply_of_notMem_baseSet {x : M} - (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e i s x = 0 := by - simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim +open scoped Bundle Manifold ContDiff -variable (e b) in -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -@[simp] -lemma localFrame_repr_apply_of_mem_baseSet {x : M} - (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : - b.localFrame_repr e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by - simp [localFrame_repr, hx] - --- uniqueness of the decomposition: follows from the IsBasis property above - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -variable (b) in -lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := by - have {x'} (hx : x' ∈ e.baseSet) : - s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by - simp [Basis.localFrame_repr, hx] - exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm - exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ - -variable {ι : Type*} [Fintype ι] {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in -/-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma localFrame_repr_congr (b : Basis ι 𝕜 F) - {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : - b.localFrame_repr e i s x = b.localFrame_repr e i s' x := by - by_cases hxe : x ∈ e.baseSet - · simp [localFrame_repr, hxe, localFrame_toBasis_at] - congr - · simp [localFrame_repr, hxe] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in -lemma localFrame_repr_apply_zero_at - (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.localFrame_repr e i s x = 0 := by - rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] - simp - -- This proof may indicate a missing simp lemma. - -- by_cases hxe : x ∈ e.baseSet; swap - -- · simp [localFrame_repr, hxe] - -- simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] - -- have : e.symm x = 0 := sorry - -- have : (e { proj := x, snd := 0 }).2 = 0 := by - -- trans (e { proj := x, snd := e.symm x 0 }).2 - -- · simp [this] - -- · simp [e.apply_mk_symm hxe] - -- simp [this] - -variable {n} - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in -/-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. -Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` -equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ -lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : - b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by - simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] - -lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x := by - -- This boils down to computing the frame coefficients in a local trivialisation. - classical - -- step 1: on e.baseSet, can compute the coefficient very well - let aux := fun x ↦ b.repr (e (s x)).2 i - -- Since e.baseSet is open, this is sufficient. - suffices ContMDiffAt I 𝓘(𝕜) k aux x by - apply this.congr_of_eventuallyEq_of_mem ?_ trivial - apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) - intro y hy - simp [aux, hy, Basis.localFrame_repr_eq_repr hy] - simp only [aux] - - -- step 2: `s` read in trivialization `e` is `C^k` - have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by - -- XXX: make e and s implicit! - rw [contMDiffAt_section_of_mem_baseSet _ _ hxe] at hs - exact hs - -- step 3: `b.repr` is a linear map, so the composition is smooth - let bas := fun v ↦ b.repr v i - have : IsLinearMap 𝕜 bas := sorry - have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k bas (e (s x)).2 := by - -- exact? should do it now - sorry - exact hbas.comp x h₁ - --- XXX: upgrade the above proof to contMDiffOn, and deduce contMDiffAt from it? - -lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} - (ht : IsOpen t) (ht' : t ⊆ e.baseSet) - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : - ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := - fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk - (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt - -end Basis - -end localFrame +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean new file mode 100644 index 00000000000000..c268825ca1d42d --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -0,0 +1,230 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.VectorBundle.Basic + +/-! +# Local frames in a vector bundle + +TODO add a more complete doc-string! + +-/ +open Bundle Filter Function Topology + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] + -- `V` vector bundle + +namespace Basis + +variable {ι : Type*} + +noncomputable def localFrame_toBasis_at + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := + b.map (e.linearEquivAt (R := 𝕜) x hx).symm + +open scoped Classical in +-- If x is outside of `e.baseSet`, this returns the junk value 0. +noncomputable def localFrame + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) : ι → (x : M) → V x := fun i x ↦ + -- idea: take the vector b i and apply the trivialisation e to it. + if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 + +-- TODO: understand why this isn’t already a simp lemma +attribute [simp] Trivialization.apply_mk_symm + +omit [IsManifold I 0 M] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [ContMDiffVectorBundle n F V I] in +/-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, +is `C^k` on `e.baseSet`. -/ +lemma contMDiffOn_localFrame_baseSet + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n + (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) e.baseSet := by + rw [contMDiffOn_section_of_mem_baseSet₀] + apply (contMDiffOn_const (c := b i)).congr + intro y hy + simp [localFrame, hy, localFrame_toBasis_at] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_apply_of_mem_baseSet + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∈ e.baseSet) : + b.localFrame e i x = b.localFrame_toBasis_at e hx i := by + simp [localFrame, hx] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_apply_of_notMem + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∉ e.baseSet) : + b.localFrame e i x = 0 := by + simp [localFrame, hx] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localFrame_toBasis_at_coe + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : + b.localFrame_toBasis_at e hx i = b.localFrame e i x := by simp [hx] + +-- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? +/-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ +def isBasis_localFrame + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) : sorry := by + -- the b i form a basis of F, + -- and the trivialisation e is a linear equivalence (thus preserves bases) + sorry + +open scoped Classical in +/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ +-- If x is outside of `e.baseSet`, this returns the junk value 0. +-- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate +-- cases. +noncomputable def localFrame_repr + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where + toFun s x := if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 + map_add' s s' := by + ext x + by_cases hx : x ∈ e.baseSet <;> simp [hx] + map_smul' c s := by + ext x + by_cases hx : x ∈ e.baseSet <;> simp [hx] + +variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} + +variable (e b) in +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_repr_apply_of_notMem_baseSet {x : M} + (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e i s x = 0 := by + simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim + +variable (e b) in +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +@[simp] +lemma localFrame_repr_apply_of_mem_baseSet {x : M} + (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : + b.localFrame_repr e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by + simp [localFrame_repr, hx] + +-- uniqueness of the decomposition: follows from the IsBasis property above + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +variable (b) in +lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := by + have {x'} (hx : x' ∈ e.baseSet) : + s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by + simp [Basis.localFrame_repr, hx] + exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm + exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ + +variable {ι : Type*} [Fintype ι] {x : M} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in +/-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ +lemma localFrame_repr_congr (b : Basis ι 𝕜 F) + {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : + b.localFrame_repr e i s x = b.localFrame_repr e i s' x := by + by_cases hxe : x ∈ e.baseSet + · simp [localFrame_repr, hxe, localFrame_toBasis_at] + congr + · simp [localFrame_repr, hxe] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in +lemma localFrame_repr_apply_zero_at + (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : + b.localFrame_repr e i s x = 0 := by + rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] + simp + -- This proof may indicate a missing simp lemma. + -- by_cases hxe : x ∈ e.baseSet; swap + -- · simp [localFrame_repr, hxe] + -- simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] + -- have : e.symm x = 0 := sorry + -- have : (e { proj := x, snd := 0 }).2 = 0 := by + -- trans (e { proj := x, snd := e.symm x 0 }).2 + -- · simp [this] + -- · simp [e.apply_mk_symm hxe] + -- simp [this] + +variable {n} + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in +/-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. +Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` +equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ +lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : + b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by + simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] + +lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) + (i : ι) : ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x := by + -- This boils down to computing the frame coefficients in a local trivialisation. + classical + -- step 1: on e.baseSet, can compute the coefficient very well + let aux := fun x ↦ b.repr (e (s x)).2 i + -- Since e.baseSet is open, this is sufficient. + suffices ContMDiffAt I 𝓘(𝕜) k aux x by + apply this.congr_of_eventuallyEq_of_mem ?_ trivial + apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) + intro y hy + simp [aux, hy, Basis.localFrame_repr_eq_repr hy] + simp only [aux] + + -- step 2: `s` read in trivialization `e` is `C^k` + have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by + -- XXX: make e and s implicit! + rw [contMDiffAt_section_of_mem_baseSet _ _ hxe] at hs + exact hs + -- step 3: `b.repr` is a linear map, so the composition is smooth + let bas := fun v ↦ b.repr v i + have : IsLinearMap 𝕜 bas := sorry + have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k bas (e (s x)).2 := by + -- exact? should do it now + sorry + exact hbas.comp x h₁ + +-- XXX: upgrade the above proof to contMDiffOn, and deduce contMDiffAt from it? + +lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} + (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : + ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := + fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk + (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt + +end Basis From ec6a40a668e9b300fdd75092ffe074769e4f8b1b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 16:43:26 +0200 Subject: [PATCH 058/601] chore: move prerequisites up a bit --- .../VectorBundle/CovariantDerivative.lean | 67 ++++++++++--------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 2755c24641743a..d64495fa2b5ed9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -40,12 +40,42 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] -- `V` vector bundle +section prerequisites + def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where toFun v := v invFun v := v map_add' := by simp map_smul' := by simp +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +-- TODO: cleanup +@[simp] +theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : + MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ + DifferentiableAt 𝕜 σ e := by + rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace, + mdifferentiableWithinAt_univ, mdifferentiableWithinAt_univ] + change MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E) id e ∧ MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') σ e ↔ + DifferentiableAt 𝕜 σ e + simp [mdifferentiableAt_id, mdifferentiableAt_iff_differentiableAt] + +attribute [simp] mdifferentiableAt_iff_differentiableAt + +-- XXX: make a better version of fderiv_const_smul'', with field coefficients instead! +theorem _root_.fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField 𝕜] + [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + (σ : (x : E) → Trivial E E' x) (a : 𝕜) (x : E) : + fderiv 𝕜 (a • σ) x = a • fderiv 𝕜 σ x := by + obtain (rfl | ha) := eq_or_ne a 0 + · simp + · have : Invertible a := invertibleOfNonzero ha + exact fderiv_const_smul'' .. + +end prerequisites + variable (x : M) structure CovariantDerivative where @@ -351,40 +381,11 @@ noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] end real -end CovariantDerivative - -end - -section - variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] --- TODO: cleanup -@[simp] -theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : - MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ - DifferentiableAt 𝕜 σ e := by - rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace, - mdifferentiableWithinAt_univ, mdifferentiableWithinAt_univ] - change MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E) id e ∧ MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') σ e ↔ - DifferentiableAt 𝕜 σ e - simp [mdifferentiableAt_id, mdifferentiableAt_iff_differentiableAt] - -attribute [simp] mdifferentiableAt_iff_differentiableAt - --- XXX: make a better version of fderiv_const_smul'', with field coefficients instead! -theorem _root_.fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField 𝕜] - [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - (σ : (x : E) → Trivial E E' x) (a : 𝕜) (x : E) : - fderiv 𝕜 (a • σ) x = a • fderiv 𝕜 σ x := by - obtain (rfl | ha) := eq_or_ne a 0 - · simp - · have : Invertible a := invertibleOfNonzero ha - exact fderiv_const_smul'' .. - @[simps] -noncomputable def CovariantDerivative.trivial : CovariantDerivative 𝓘(𝕜, E) E' +noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where toFun X s := fun x ↦ fderiv 𝕜 s x (X x) addX X X' σ := by ext; simp @@ -400,9 +401,9 @@ noncomputable def CovariantDerivative.trivial : CovariantDerivative 𝓘(𝕜, E simp [this, bar] rfl -open Classical in +open scoped Classical in @[simps] -noncomputable def CovariantDerivative.of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : +noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) addX X X' σ := by @@ -426,4 +427,6 @@ noncomputable def CovariantDerivative.of_endomorphism (A : E → E →L[𝕜] E' simp [this, bar, hσ, h] module +end CovariantDerivative + end From d001e2304acb718da61d13924e24f27d2dd487de Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 16:59:32 +0200 Subject: [PATCH 059/601] Fix smoothness sorry for local frames --- .../Manifold/VectorBundle/LocalFrame.lean | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index c268825ca1d42d..9a9a11c900b442 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -206,20 +206,25 @@ lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) -- step 2: `s` read in trivialization `e` is `C^k` have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by - -- XXX: make e and s implicit! rw [contMDiffAt_section_of_mem_baseSet _ _ hxe] at hs exact hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i - have : IsLinearMap 𝕜 bas := sorry - have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k bas (e (s x)).2 := by - -- exact? should do it now - sorry + let basl : F →ₗ[𝕜] 𝕜 := { + toFun := bas + map_add' m m' := by simp [bas] + map_smul' m x := by simp [bas] + } + let basL : F →L[𝕜] 𝕜 := { + toLinearMap := basl + cont := sorry -- F is finite-dimensional... + } + have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k basL (e (s x)).2 := + contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt exact hbas.comp x h₁ --- XXX: upgrade the above proof to contMDiffOn, and deduce contMDiffAt from it? - -lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) +variable {I} in +lemma contMDiffOn_localFrame_repr (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : @@ -227,4 +232,11 @@ lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt +variable {I} in +lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : + ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := + contMDiffOn_localFrame_repr b hk e.open_baseSet (subset_refl _) hs _ + end Basis From 46adbf16f9d3e7f024001f0f4092fccef91c7e39 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 17:16:32 +0200 Subject: [PATCH 060/601] chore: make I implicit --- Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 9a9a11c900b442..89ffc881fcc678 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -17,7 +17,7 @@ open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] @@ -223,16 +223,14 @@ lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt exact hbas.comp x h₁ -variable {I} in lemma contMDiffOn_localFrame_repr (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := - fun _ hx ↦ (b.contMDiffAt_localFrame_repr I (ht' hx) hk + fun _ hx ↦ (b.contMDiffAt_localFrame_repr (ht' hx) hk (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -variable {I} in lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : From 98012b57945624e565a0da8d59ecb3a6c90a9faa Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 17:35:33 +0200 Subject: [PATCH 061/601] Smoothness of local frames sorry-free --- .../Manifold/VectorBundle/LocalFrame.lean | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 89ffc881fcc678..ca474fa7aa5bac 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -188,8 +188,11 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] -lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [ContMDiffVectorBundle n F V I] [Fintype ι] in +lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. @@ -217,24 +220,28 @@ lemma contMDiffAt_localFrame_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) } let basL : F →L[𝕜] 𝕜 := { toLinearMap := basl - cont := sorry -- F is finite-dimensional... + cont := basl.continuous_of_finiteDimensional } have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k basL (e (s x)).2 := contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt exact hbas.comp x h₁ -lemma contMDiffOn_localFrame_repr (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) {t : Set M} +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [ContMDiffVectorBundle n F V I] [Fintype ι] in +lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := - fun _ hx ↦ (b.contMDiffAt_localFrame_repr (ht' hx) hk + fun _ hx ↦ (b.contMDiffAt_localFrame_repr (ht' hx) (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -lemma contMDiffOn_baseSet_localFrame_repr (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} (hk : k ≤ n) +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [ContMDiffVectorBundle n F V I] [Fintype ι] in +lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := - contMDiffOn_localFrame_repr b hk e.open_baseSet (subset_refl _) hs _ + contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ end Basis From 566bf039643d134428ea239f31f9e0c108562ae5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 17:38:50 +0200 Subject: [PATCH 062/601] chore: make e and s implicit in contMDiff{At,On}_section_{of_mem_baseSet} --- .../Geometry/Manifold/VectorBundle/Basic.lean | 20 +++++++++---------- .../Manifold/VectorBundle/LocalFrame.lean | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 7e5a9d836a4751..63e9fbe329175e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -206,15 +206,15 @@ theorem contMDiffWithinAt_section_of_mem_BaseSet (s : ∀ x, E x) (a : Set B) {x sorry /-- Characterization of `C^n` sections of a vector bundle. -/ -theorem contMDiffAt_section (s : ∀ x, E x) (x₀ : B) : +theorem contMDiffAt_section {s : ∀ x, E x} (x₀ : B) : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) x₀ := by simp_rw [contMDiffAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffAt_id /-- Continuity of a `C^n` section at `x` can be determined using any trivialisation whose `baseSet` contains `x`. -/ -theorem contMDiffAt_section_of_mem_baseSet (s : ∀ x, E x) {x₀ : B} - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) +theorem contMDiffAt_section_of_mem_baseSet {s : ∀ x, E x} {x₀ : B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by @@ -222,8 +222,8 @@ theorem contMDiffAt_section_of_mem_baseSet (s : ∀ x, E x) {x₀ : B} /-- Continuity of a `C^n` section on `s` can be determined using any trivialisation whose `baseSet` contains `s`. -/ -theorem contMDiffOn_section_of_mem_baseSet (s : ∀ x, E x) {a : Set B} - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) +theorem contMDiffOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a := by @@ -232,20 +232,20 @@ theorem contMDiffOn_section_of_mem_baseSet (s : ∀ x, E x) {a : Set B} · intro h x hx have : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x := (h x hx).contMDiffAt <| ha.mem_nhds hx - exact ((contMDiffAt_section_of_mem_baseSet s e (ha' hx)).mp this).contMDiffWithinAt + exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mp this).contMDiffWithinAt · intro h x hx have : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e { proj := x, snd := s x }).2) x := (h x hx).contMDiffAt <| ha.mem_nhds hx - exact ((contMDiffAt_section_of_mem_baseSet s e (ha' hx)).mpr this).contMDiffWithinAt + exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mpr this).contMDiffWithinAt /-- For any trivialization `e`, the continuity of a `C^n` section on `e.baseSet` can be determined using `e`. -/ -theorem contMDiffOn_section_of_mem_baseSet₀ (s : ∀ x, E x) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) +theorem contMDiffOn_section_of_mem_baseSet₀ {s : ∀ x, E x} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} [MemTrivializationAtlas e] : ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := - contMDiffOn_section_of_mem_baseSet s e e.open_baseSet (subset_refl _) + contMDiffOn_section_of_mem_baseSet e.open_baseSet (subset_refl _) variable (E) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index ca474fa7aa5bac..4275d47505d144 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -209,7 +209,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 -- step 2: `s` read in trivialization `e` is `C^k` have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by - rw [contMDiffAt_section_of_mem_baseSet _ _ hxe] at hs + rw [contMDiffAt_section_of_mem_baseSet hxe] at hs exact hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i From 65f6211ad86b5c33da287ac81a1c1c6feaaa057d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 18:45:27 +0200 Subject: [PATCH 063/601] Progress: towards the classification of covariant derivatives over the trivial bundle --- .../VectorBundle/CovariantDerivative.lean | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index d64495fa2b5ed9..efe29e551b63eb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -357,6 +357,19 @@ noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) letI bV := b.localFrame_toBasis_at t (FiberBundle.mem_baseSet_trivializationAt F V x) fun x' ↦ ∑ i, bV.repr v i • b.localFrame t i x' +-- FIXME: these two lemmas only hold for *very particular* choices of extensions of v +-- (but there exist such choices, and our definition makes these ?! TODO check!!) +-- so, one may argue this is mathematically wrong, but it encodes the "choice some extension +-- with this and that property" nicely +-- a different proof would be to argue only the value at a point matters for cov +@[simp] +lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : + extend F (v + v') = extend F v + extend F v' := sorry + +@[simp] +lemma extend_smul_apply [FiniteDimensional ℝ F] {a : ℝ} (v : V x) : + extend F (a • v) = a • extend F v := sorry + -- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : @@ -373,17 +386,25 @@ lemma contMDiff_extend [FiniteDimensional ℝ F] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend F σ₀ x)) := by sorry --- The difference of two covariant derivatives, as a tensorial map +/-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +@[simp] +lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] + (cov cov' : CovariantDerivative I F V) (x : M) (X₀ : TangentSpace I x) (σ₀ : V x) : + difference cov cov' x X₀ σ₀ = + cov (extend E X₀) (extend F σ₀) x - cov' (extend E X₀) (extend F σ₀) x := rfl + end real variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] +variable (E E') in @[simps] noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where @@ -427,6 +448,43 @@ noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : simp [this, bar, hσ, h] module +section real + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] + +@[simps] +noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] + (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x X : E) : E' →ₗ[ℝ] E' where + toFun := difference cov (CovariantDerivative.trivial E E') x X + map_add' y y' := by + -- follows from the (not yet proven) smoothness + have A : fderiv ℝ ((extend E' y (x := x)) + extend E' y' (x := x)) x = + fderiv ℝ (extend E' y (x := x)) x + fderiv ℝ (extend E' y' (x := x)) x := sorry + have B : cov (extend E X (x := x)) (extend E' y (x := x) + extend E' y' (x := x)) x = + cov (extend E X (x := x)) (extend E' y (x := x)) x + + cov (extend E X (x := x)) (extend E' y' (x := x)) x := sorry + simp [A, B] + module + map_smul' a v := by + simp [fderiv_section_smul, cov.smul_const_σ] + module + +@[simps!] +noncomputable def endomorph_of_trivial_aux' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] + (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x X : E) : E' →L[ℝ] E' where + toLinearMap := cov.endomorph_of_trivial_aux x X + cont := LinearMap.continuous_of_finiteDimensional _ + +/-- Classification of covariant derivatives over a trivial vector bundle: every connection +is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term +-/ +lemma exists_endomorph (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : + ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), cov = .of_endomorphism A := by + sorry + +end real + end CovariantDerivative end From c762ddbf4a3c022a5ce9de96e55b8a37a97ddb53 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 19:29:59 +0200 Subject: [PATCH 064/601] Progress --- .../VectorBundle/CovariantDerivative.lean | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index efe29e551b63eb..ef017ed4d2f360 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -104,6 +104,11 @@ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := ⟨fun e ↦ e.toFun⟩ +-- TODO: prove this via a DFunLike instance +lemma myext (cov cov' : CovariantDerivative I F V) + (h : ∀ X : (Π x : M, TangentSpace I x), ∀ (σ : Π x : M, V x), ∀ (x : M), cov X σ x = cov' X σ x) : + cov = cov' := sorry + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @[simp] @@ -476,12 +481,46 @@ noncomputable def endomorph_of_trivial_aux' [FiniteDimensional ℝ E] [FiniteDim toLinearMap := cov.endomorph_of_trivial_aux x X cont := LinearMap.continuous_of_finiteDimensional _ +@[simps] +noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] + (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x : E) : E →ₗ[ℝ] E' →L[ℝ] E' where + toFun X := cov.endomorph_of_trivial_aux' x X + map_add' X Y := by + ext Z + simp [cov.addX (extend E X (x := x)) (extend E Y (x := x)) (extend E' Z (x := x))] + module + map_smul' t X := by + ext Z + simp + --expose_names + --have A : cov (t • extend E X (x := x)) (extend E' Z) x = t • cov (extend E X (x := x)) (extend E' Z) x := sorry + --simp [A] + --have aux := cov.smulX (extend E X (x := x)) (extend E' Z (x := x)) (f := fun _ ↦ t) --t + --simp [aux] + --module + sorry + +@[simps!] +noncomputable def endomorph_of_trivial_aux''' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] + (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x : E) : E →L[ℝ] E' →L[ℝ] E' where + toLinearMap := cov.endomorph_of_trivial_aux'' x + cont := LinearMap.continuous_of_finiteDimensional _ + /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term -/ -lemma exists_endomorph (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : +lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] + (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), cov = .of_endomorphism A := by - sorry + use cov.endomorph_of_trivial_aux''' + apply CovariantDerivative.myext + intro X σ x + -- These two statements are unfolding a bit too far: the first sorry holds, + -- but the second one does not. + -- However, the difference of these is true again. + have A : cov (extend E (X x)) (extend E' (σ x)) x = cov X σ x := sorry + have B : fderiv ℝ (extend E' (σ x) (x := x)) x (X x) = fderiv ℝ σ x (X x) := sorry + simp [A, B] end real From c9dada25eb3d270036256204a95e008fb2bcf079 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 19:42:41 +0200 Subject: [PATCH 065/601] Tiny progress towards extend sorries. --- .../VectorBundle/CovariantDerivative.lean | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ef017ed4d2f360..6b0cf6946dd6df 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -356,6 +356,11 @@ lemma foo (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M -- TODO: either change `localFrame` to make sure it is everywhere smooth -- or introduce a cut-off here. First option is probaly better. variable (F) in +/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) → V x' := letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x @@ -369,12 +374,28 @@ noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) -- a different proof would be to argue only the value at a point matters for cov @[simp] lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : - extend F (v + v') = extend F v + extend F v' := sorry + extend F (v + v') = extend F v + extend F v' := by + ext x + simp [extend] + expose_names + set b := Basis.ofVectorSpace ℝ F + set t := trivializationAt F V x + --have : x_1 ∈ (trivializationAt F V x_1).baseSet + have (i) : + let hi := FiberBundle.mem_baseSet_trivializationAt F V x_1; + (((b.localFrame_toBasis_at t sorry).repr v) i + + ((b.localFrame_toBasis_at t sorry).repr v') i) • b.localFrame t i x = + ((b.localFrame_toBasis_at t sorry).repr v) i • b.localFrame t i x + + ((b.localFrame_toBasis_at t sorry).repr v') i • b.localFrame t i x := by + sorry + sorry @[simp] lemma extend_smul_apply [FiniteDimensional ℝ F] {a : ℝ} (v : V x) : extend F (a • v) = a • extend F v := sorry +#exit + -- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : From d45dbf135ddbf49e29c5252b349bb6b67f3377d0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 27 Jun 2025 21:00:21 +0200 Subject: [PATCH 066/601] Further progress: main argument done, a few sorries remain --- .../VectorBundle/CovariantDerivative.lean | 82 +++++++++++++------ 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 6b0cf6946dd6df..eb9ffaa378b045 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -78,6 +78,7 @@ end prerequisites variable (x : M) +@[ext] structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) addX : ∀ (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x), @@ -104,11 +105,6 @@ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := ⟨fun e ↦ e.toFun⟩ --- TODO: prove this via a DFunLike instance -lemma myext (cov cov' : CovariantDerivative I F V) - (h : ∀ X : (Π x : M, TangentSpace I x), ∀ (σ : Π x : M, V x), ∀ (x : M), cov X σ x = cov' X σ x) : - cov = cov' := sorry - omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @[simp] @@ -320,6 +316,13 @@ def differenceAux (cov cov' : CovariantDerivative I F V) : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := fun X σ ↦ cov X σ - cov' X σ +omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in +@[simp] +lemma differenceAux_apply (cov cov' : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) : + differenceAux cov cov' X σ = cov X σ - cov' X σ := rfl + omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in lemma differenceAux_smul_eq (cov cov' : CovariantDerivative I F V) @@ -394,8 +397,6 @@ lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : lemma extend_smul_apply [FiniteDimensional ℝ F] {a : ℝ} (v : V x) : extend F (a • v) = a • extend F v := sorry -#exit - -- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : @@ -418,6 +419,17 @@ noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] Π x : M, TangentSpace I x → V x → V x := fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x +-- -- Note: we conciously register this lemma in unapplied form, +-- -- but differenceAux_apply: this means the applied form should simplify down all the way, +-- -- but hopefully a mere term difference not. +-- omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +-- @[simp] +-- lemma difference_toFun [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] +-- (cov cov' : CovariantDerivative I F V) : +-- cov.difference cov' = fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x := rfl + +-- show? the map differenceAux to difference is injective + omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] @@ -486,10 +498,16 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime map_add' y y' := by -- follows from the (not yet proven) smoothness have A : fderiv ℝ ((extend E' y (x := x)) + extend E' y' (x := x)) x = - fderiv ℝ (extend E' y (x := x)) x + fderiv ℝ (extend E' y' (x := x)) x := sorry + fderiv ℝ (extend E' y (x := x)) x + fderiv ℝ (extend E' y' (x := x)) x := by + rw [fderiv_add] + · sorry -- apply (contMDiff_extend _ _).contMDiffAt.DifferentiableAt + · sorry -- similar have B : cov (extend E X (x := x)) (extend E' y (x := x) + extend E' y' (x := x)) x = cov (extend E X (x := x)) (extend E' y (x := x)) x + - cov (extend E X (x := x)) (extend E' y' (x := x)) x := sorry + cov (extend E X (x := x)) (extend E' y' (x := x)) x := by + apply cov.addσ + · exact (contMDiff_extend _ _).mdifferentiableAt (n := 1) (hn := by norm_num) + · apply (contMDiff_extend _ _).mdifferentiableAt (n := 1) (hn := by norm_num) simp [A, B] module map_smul' a v := by @@ -502,7 +520,7 @@ noncomputable def endomorph_of_trivial_aux' [FiniteDimensional ℝ E] [FiniteDim toLinearMap := cov.endomorph_of_trivial_aux x X cont := LinearMap.continuous_of_finiteDimensional _ -@[simps] +-- Not marked simp, as unfolding this is not always desirable. noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x : E) : E →ₗ[ℝ] E' →L[ℝ] E' where toFun X := cov.endomorph_of_trivial_aux' x X @@ -513,12 +531,14 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi map_smul' t X := by ext Z simp - --expose_names - --have A : cov (t • extend E X (x := x)) (extend E' Z) x = t • cov (extend E X (x := x)) (extend E' Z) x := sorry - --simp [A] - --have aux := cov.smulX (extend E X (x := x)) (extend E' Z (x := x)) (f := fun _ ↦ t) --t - --simp [aux] - --module + + -- The following lines should ideally mold into the simp call above. + trans t • (cov (extend E X (x := x)) (extend E' Z (x := x)) x) + - t • (fderiv ℝ (extend E' Z (x := x)) x) X + swap; · module + congr + -- TODO: this is almost the item we want, but not quite! not sure where the mismatch comes from + let asdf := cov.smulX (extend E X (x := x)) (extend E' Z (x := x)) (fun x ↦ t) sorry @[simps!] @@ -534,14 +554,28 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), cov = .of_endomorphism A := by use cov.endomorph_of_trivial_aux''' - apply CovariantDerivative.myext - intro X σ x - -- These two statements are unfolding a bit too far: the first sorry holds, - -- but the second one does not. - -- However, the difference of these is true again. - have A : cov (extend E (X x)) (extend E' (σ x)) x = cov X σ x := sorry - have B : fderiv ℝ (extend E' (σ x) (x := x)) x (X x) = fderiv ℝ σ x (X x) := sorry - simp [A, B] + ext X σ x + -- TODO: this is unfolding too much; need to fix this manually below... + -- think about a better design that actually works... + simp only [of_endomorphism_toFun, endomorph_of_trivial_aux'''_apply_apply] + + -- TODO: this case has a gap; if hσ is false, currently hσ' is still true... + have hσ : MDifferentiable 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) + fun x ↦ TotalSpace.mk' E' x (σ x) := sorry + have hσ' : MDifferentiable 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) + fun x' ↦ TotalSpace.mk' E' x' ((extend E' (σ x)) x') := sorry + + rw [← CovariantDerivative.trivial_toFun] + have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by + -- Do not unfold differenceAux: we use the tensoriality of differenceAux. + rw [difference] + -- TODO: should σ and σ' be implicit? + apply foo _ _ _ _ _ _ _ hσ hσ' + have h₂ : cov.difference (trivial E E') x (X x) (σ x) = + cov (extend E (X x)) (extend E' (σ x)) x - (fderiv ℝ (extend E' (σ x) (x := x)) x) (X x) := by + simp + rw [← h₂, ← h₁] + module end real From 86a35d28aa1c7ea713f3f92824ac1b480e86041c Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Sat, 28 Jun 2025 12:45:18 +0200 Subject: [PATCH 067/601] Add Tensoriality file --- Mathlib.lean | 1 + .../VectorBundle/CovariantDerivative.lean | 76 ++++--- .../Manifold/VectorBundle/Tensoriality.lean | 211 ++++++++++++++++++ 3 files changed, 258 insertions(+), 30 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean diff --git a/Mathlib.lean b/Mathlib.lean index 106b40f56b36b5..44e82b2014c01c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3709,6 +3709,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.Pullback import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.VectorBundle.Tangent +import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.VectorField.Pullback import Mathlib.Geometry.Manifold.WhitneyEmbedding diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index eb9ffaa378b045..689d8a2cf7dccb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -8,8 +8,8 @@ import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality /-! # Covariant derivatives @@ -253,21 +253,17 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I congr; ext i; simp [cov.smulX (Xi i) σ (a i)] _ = 0 := by simp [this] --- XXX: better name? --- golfing welcome! -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in /-- `cov X σ x` only depends on `X` via `X x` -/ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hXX' : X x = X' x) : cov X σ x = cov X' σ x := by - have : cov X' σ x = cov X σ x + cov (X' - X) σ x := by - have : X' = X + (X' - X) := by simp - nth_rw 1 [this] - rw [cov.addX X (X' - X) σ] - simp - have h : (X' - X) x = 0 := by simp [hXX'] - simp [this, cov.congr_X_at_aux (X' - X) h] + apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' + · intro f X + rw [cov.smulX] + rfl + · intro X X' + rw [cov.addX] + rfl omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in @@ -326,35 +322,55 @@ lemma differenceAux_apply (cov cov' : CovariantDerivative I F V) omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in lemma differenceAux_smul_eq (cov cov' : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) - (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) - (hf : MDifferentiable I 𝓘(ℝ) f) : - differenceAux cov cov' X ((f : M → ℝ) • σ) = (f : M → ℝ) • (differenceAux cov cov' X σ) := + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hf : MDifferentiableAt I 𝓘(ℝ) f x) : + differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= calc _ - _ = cov X ((f : M → ℝ) • σ) - cov' X ((f : M → ℝ) • σ) := rfl - _ = (f • cov X σ + (fun x ↦ bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ) - - (f • cov' X σ + (fun x ↦ bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ) := by - ext x - simp [cov.leibniz X _ _ _ (hσ x) (hf x), cov'.leibniz X _ _ _ (hσ x) (hf x)] - _ = f • cov X σ - f • cov' X σ := by simp - _ = f • (cov X σ - cov' X σ) := by simp [smul_sub] + _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl + _ = (f x • cov X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) + - (f x • cov' X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by + simp [cov.leibniz X _ _ _ hσ hf, cov'.leibniz X _ _ _ hσ hf] + _ = f x • cov X σ x - f x • cov' X σ x := by simp + _ = f x • (cov X σ x - cov' X σ x) := by simp [smul_sub] _ = _ := rfl omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in lemma differenceAux_smul_eq' (cov cov' : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) : - differenceAux cov cov' (f • X) σ = (f : M → ℝ) • differenceAux cov cov' X σ := by + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) (x : M) : + differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by simp [differenceAux, cov.smulX, cov'.smulX, smul_sub] /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ -lemma foo (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] (X X' : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x₀ : M) - (hσ : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x))) - (hσ' : MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x))) : + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x₀) + (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x₀) + (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) : differenceAux cov cov' X σ x₀ = differenceAux cov cov' X' σ' x₀ := by - -- use the previous two lemmas: they prove that differenceAux is tensorial - sorry + trans cov.differenceAux cov' X' σ x₀ + · let φ : (Π x : M, TangentSpace I x) → (Π x, V x) := fun X ↦ cov.differenceAux cov' X σ + change φ X x₀ = φ X' x₀ + apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' + · intro f X + apply differenceAux_smul_eq' + · intro X X' + unfold φ CovariantDerivative.differenceAux + rw [cov.addX, cov'.addX] + simp + abel + · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ cov.differenceAux cov' X' σ + change φ σ x₀ = φ σ' x₀ + apply tensoriality_criterion (E := E) (I := I) F V F V hσ hσ' hσσ' + · intro f σ x hf + exact differenceAux_smul_eq cov cov' X' σ f hf x + · intro σ σ' hσ hσ' + unfold φ CovariantDerivative.differenceAux + simp + rw [cov.addσ, cov'.addσ] <;> try assumption + abel -- TODO: either change `localFrame` to make sure it is everywhere smooth -- or introduce a cut-off here. First option is probaly better. diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean new file mode 100644 index 00000000000000..9e537103c80ca0 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -0,0 +1,211 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.MFDeriv.Defs +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +import Mathlib.Geometry.Manifold.MFDeriv.Basic + +/-! +# The tensoriality criterion + +-/ +open Bundle Filter Function Topology + +open scoped Bundle Manifold ContDiff + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul ℝ (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] + -- `V` vector bundle + +variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] + (m : WithTop ℕ∞) + (V' : M → Type*) [TopologicalSpace (TotalSpace F' V')] + [∀ x, AddCommGroup (V' x)] [∀ x, Module ℝ (V' x)] + [∀ x : M, TopologicalSpace (V' x)] [∀ x, IsTopologicalAddGroup (V' x)] + [∀ x, ContinuousSMul ℝ (V' x)] + +lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] + [IsManifold I ∞ M] + {φ : (Π x : M, V x) → (Π x, V' x)} {x} + {σ σ' : Π x : M, V x} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (hσσ' : σ x = σ' x) + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDifferentiableAt I 𝓘(ℝ) f x → + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x → + φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by + have locality {σ σ'} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : φ σ x = φ σ' x := by + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' + have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by + by_cases h : σ x = σ' x + · rw [Pi.smul_apply', Pi.smul_apply', h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] + have hψ' : MDifferentiableAt I 𝓘(ℝ) ψ x := + ψ.contMDiffAt.mdifferentiableAt ENat.LEInfty.out + calc φ σ x + _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul _ _ hψ' hσ] + _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] + _ = φ σ' x := by simp [φ_smul _ _ hψ' hσ'] + let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F + classical + have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) + (hσ : ∀ i, MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ i x)) x): + φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + have h₁ : MDifferentiableAt I 𝓘(ℝ) (fun x' : M ↦ (0 : ℝ)) x := by + exact contMDiffAt_const.mdifferentiableAt le_rfl + rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl] + rw [φ_smul] + simp + exact h₁ + apply (contMDiff_zeroSection _ _).mdifferentiableAt ENat.LEInfty.out + | insert a s ha h => + change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ + simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h] + erw [φ_add] + apply hσ a + sorry + have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) + let b := Basis.ofVectorSpace ℝ F + let t := trivializationAt F V x + let s := b.localFrame (trivializationAt F V x) + let c := Basis.localFrame_repr t b + rw [locality _ _ (b.localFrame_repr_spec x_mem σ), locality _ _ (b.localFrame_repr_spec x_mem σ'), + sum_phi, sum_phi] + · change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x + congr + ext i + rw [φ_smul, φ_smul] + · congr + apply b.localFrame_repr_congr + assumption + all_goals sorry + all_goals sorry + +include I in +omit [IsManifold I 1 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul ℝ (V x)] [FiberBundle F V] [VectorBundle ℝ F V] + [∀ (x : M), IsTopologicalAddGroup (V' x)] [∀ (x : M), ContinuousSMul ℝ (V' x)] in +lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] + {φ : (Π x : M, V x) → (Π x, V' x)} {x} + {σ σ' : Π x : M, V x} + (hσσ' : σ x = σ' x) + (φ_smul : ∀ f : M → ℝ, ∀ σ, φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by + have locality {σ σ'} (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : + φ σ x = φ σ' x := by + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' + have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by + by_cases h : σ x = σ' x + · rw [Pi.smul_apply', Pi.smul_apply', h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] + calc φ σ x + _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul] + _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] + _ = φ σ' x := by simp [φ_smul] + let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F + classical + have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) : + φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl, φ_smul] + simp + | insert a s ha h => + change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ + simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h] + erw [φ_add] + have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) + let b := Basis.ofVectorSpace ℝ F + let t := trivializationAt F V x + let s := b.localFrame (trivializationAt F V x) + let c := Basis.localFrame_repr t b + rw [locality (b.localFrame_repr_spec x_mem σ), locality (b.localFrame_repr_spec x_mem σ'), + sum_phi, sum_phi] + change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x + congr + ext i + rw [φ_smul, φ_smul] + congr + apply b.localFrame_repr_congr + assumption + +/- include I in +lemma tensoriality_criterion'' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] + {φ : (Π x : M, V x) → (Π x, V' x)} {x} + {σ σ' : Π x : M, V x} + {Pσ : (Π x : M, V x) → Prop} + {Pσ_loc : ∀ σ σ', (∀ᶠ x' in 𝓝 x, σ x' = σ' x') → Pσ σ → Pσ σ'} + (hσ : Pσ σ) + (hσ' : Pσ σ') + {Pf : (M → ℝ) → Prop} + {Pf_loc : ∀ f f', (∀ᶠ x' in 𝓝 x, f x' = f' x') → Pf f → Pf f'} + (Pf_smooth : ∀ f, MDifferentiableAt I 𝓘(ℝ) f x → Pf f) + (hσσ' : σ x = σ' x) + (φ_smul : ∀ f : M → ℝ, ∀ σ, Pf f → Pσ σ → φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', Pσ σ → Pσ σ → φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by + have locality {σ σ'} (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : + φ σ x = φ σ' x := by + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' + have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by + by_cases h : σ x = σ' x + · rw [Pi.smul_apply', Pi.smul_apply', h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] + calc φ σ x + _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul] + _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] + _ = φ σ' x := by simp [φ_smul] + let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F + classical + have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) : + φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl, φ_smul] + simp + | insert a s ha h => + change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ + simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h] + erw [φ_add] + have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) + let b := Basis.ofVectorSpace ℝ F + let t := trivializationAt F V x + let s := b.localFrame (trivializationAt F V x) + let c := Basis.localFrame_repr t b + rw [locality (b.localFrame_repr_spec x_mem σ), locality (b.localFrame_repr_spec x_mem σ'), + sum_phi, sum_phi] + change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x + congr + ext i + rw [φ_smul, φ_smul] + congr + apply b.localFrame_repr_congr + assumption + -/ From f919b344f2a3f4a242116abc7a6446336a92f045 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 28 Jun 2025 08:44:24 +0200 Subject: [PATCH 068/601] chore: move code to more logical places - move defs which hold in general up a little - move a few more prerequisites to their section --- .../VectorBundle/CovariantDerivative.lean | 172 +++++++++--------- 1 file changed, 87 insertions(+), 85 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 689d8a2cf7dccb..6c6aabd57a4e8e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -30,6 +30,8 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `F` model fiber (n : WithTop ℕ∞) @@ -74,6 +76,41 @@ theorem _root_.fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField · have : Invertible a := invertibleOfNonzero ha exact fderiv_const_smul'' .. +lemma _root_.FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) + [TopologicalSpace B] [TopologicalSpace F] + (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] + [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := + (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [(x : M) → AddCommGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in +variable {I F V x} in +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +if one is differentiable at `x` then so is the other. +Issue: EventuallyEq does not work for dependent functions. -/ +lemma _root_.mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) + (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ₂ : ∀ x ∈ s, σ x = σ' x) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by + apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ + -- TODO: split off a lemma? + apply Set.EqOn.eventuallyEq_of_mem _ hs + intro x hx + simp [hσ₂, hx] + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [(x : M) → AddCommGroup (V x)] in +variable {I F V x} in +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +one is differentiable at `x` iff the other is. -/ +lemma _root_.mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) + (hσ : ∀ x ∈ s, σ x = σ' x) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x ↔ + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := + ⟨fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h hσ, + fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ + end prerequisites variable (x : M) @@ -122,12 +159,6 @@ lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this simpa using this -lemma _root_.FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) - [TopologicalSpace B] [TopologicalSpace F] - (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] - [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := - (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) - omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in variable {I F V} in @@ -137,35 +168,6 @@ lemma congr_σ (cov : CovariantDerivative I F V) cov X σ x = cov X σ' x := by simp [funext hσ] -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] - [(x : M) → AddCommGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -variable {I F V x} in -/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -if one is differentiable at `x` then so is the other. -Issue: EventuallyEq does not work for dependent functions. -/ -lemma _root_.mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hσ₂ : ∀ x ∈ s, σ x = σ' x) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by - apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ - -- TODO: split off a lemma? - apply Set.EqOn.eventuallyEq_of_mem _ hs - intro x hx - simp [hσ₂, hx] - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [(x : M) → AddCommGroup (V x)] in -variable {I F V x} in -/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -one is differentiable at `x` iff the other is. -/ -lemma _root_.mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ : ∀ x ∈ s, σ x = σ' x) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x ↔ - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := - ⟨fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h hσ, - fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ - omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in lemma sum_X (cov : CovariantDerivative I F V) @@ -193,6 +195,52 @@ def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] module +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +variable (E E') in +@[simps] +noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' + (Bundle.Trivial E E') where + toFun X s := fun x ↦ fderiv 𝕜 s x (X x) + addX X X' σ := by ext; simp + smulX X σ c' := by ext; simp + addσ X σ σ' e hσ hσ' := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' + rw [fderiv_add hσ hσ'] + rfl + smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] + leibniz X σ f x hσ hf := by + have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := + fderiv_smul (by simp_all) (by simp_all) + simp [this, bar] + rfl + +open scoped Classical in +@[simps] +noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : + CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where + toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) + addX X X' σ := by + ext x + by_cases h : DifferentiableAt 𝕜 σ x + · simp [h, map_add]; abel + · simp [fderiv_zero_of_not_differentiableAt h] + smulX X σ c' := by ext; simp + addσ X σ σ' e hσ hσ' := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' + rw [fderiv_add hσ hσ'] + simp [hσ, hσ'] + abel + smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] + leibniz X σ f x hσ hf := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ + rw [mdifferentiableAt_iff_differentiableAt] at hf + have h : DifferentiableAt 𝕜 (f • σ) x := hf.smul hσ + have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := + fderiv_smul (by simp_all) (by simp_all) + simp [this, bar, hσ, h] + module + section real variable {E : Type*} [NormedAddCommGroup E] @@ -453,56 +501,8 @@ lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] difference cov cov' x X₀ σ₀ = cov (extend E X₀) (extend F σ₀) x - cov' (extend E X₀) (extend F σ₀) x := rfl -end real - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -variable (E E') in -@[simps] -noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' - (Bundle.Trivial E E') where - toFun X s := fun x ↦ fderiv 𝕜 s x (X x) - addX X X' σ := by ext; simp - smulX X σ c' := by ext; simp - addσ X σ σ' e hσ hσ' := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' - rw [fderiv_add hσ hσ'] - rfl - smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] - leibniz X σ f x hσ hf := by - have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := - fderiv_smul (by simp_all) (by simp_all) - simp [this, bar] - rfl - -open scoped Classical in -@[simps] -noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : - CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where - toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) - addX X X' σ := by - ext x - by_cases h : DifferentiableAt 𝕜 σ x - · simp [h, map_add]; abel - · simp [fderiv_zero_of_not_differentiableAt h] - smulX X σ c' := by ext; simp - addσ X σ σ' e hσ hσ' := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' - rw [fderiv_add hσ hσ'] - simp [hσ, hσ'] - abel - smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] - leibniz X σ f x hσ hf := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ - rw [mdifferentiableAt_iff_differentiableAt] at hf - have h : DifferentiableAt 𝕜 (f • σ) x := hf.smul hσ - have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := - fderiv_smul (by simp_all) (by simp_all) - simp [this, bar, hσ, h] - module - -section real +-- The classification of real connections over a trivial bundle +section classification variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] @@ -593,6 +593,8 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] rw [← h₂, ← h₁] module +end classification + end real end CovariantDerivative From 5eb546ed0269bd6feadbfc90cbaff33a68727cad Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 28 Jun 2025 21:01:17 +0200 Subject: [PATCH 069/601] Clean up prerequisites slightly --- .../Manifold/VectorBundle/CovariantDerivative.lean | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 6c6aabd57a4e8e..e580d8409ddb1f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -67,7 +67,7 @@ theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) ( attribute [simp] mdifferentiableAt_iff_differentiableAt -- XXX: make a better version of fderiv_const_smul'', with field coefficients instead! -theorem _root_.fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField 𝕜] +theorem fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] (σ : (x : E) → Trivial E E' x) (a : 𝕜) (x : E) : fderiv 𝕜 (a • σ) x = a • fderiv 𝕜 σ x := by @@ -76,7 +76,7 @@ theorem _root_.fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField · have : Invertible a := invertibleOfNonzero ha exact fderiv_const_smul'' .. -lemma _root_.FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) +lemma FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) [TopologicalSpace B] [TopologicalSpace F] (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := @@ -89,7 +89,7 @@ variable {I F V x} in /-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, if one is differentiable at `x` then so is the other. Issue: EventuallyEq does not work for dependent functions. -/ -lemma _root_.mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) +lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by @@ -104,12 +104,12 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → variable {I F V x} in /-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, one is differentiable at `x` iff the other is. -/ -lemma _root_.mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) +lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ : ∀ x ∈ s, σ x = σ' x) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x ↔ MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := - ⟨fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h hσ, - fun h ↦ _root_.mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ + ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, + fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ end prerequisites @@ -350,7 +350,7 @@ lemma congr_σ_of_eventuallyEq _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ hσ] _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) _ = cov X σ' x := by - simp [cov.congr_σ_smoothBumpFunction, _root_.mdifferentiableAt_dependent_congr hs hσ hσσ'] + simp [cov.congr_σ_smoothBumpFunction, mdifferentiableAt_dependent_congr hs hσ hσσ'] -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x From 8fa7a5f8044655986a04f179296bc1579aa99f67 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 28 Jun 2025 21:06:30 +0200 Subject: [PATCH 070/601] WIP: better plan for extension of vector fields Introduce a definition localExtensionOn, yielding a local extension on e.baseSet which behaves well on that set (and is zero elsewhere). Needs some more polish, mostly in documentation and comments. --- .../VectorBundle/CovariantDerivative.lean | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e580d8409ddb1f..8477f08ef3bb59 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -113,6 +113,84 @@ lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s end prerequisites +-- local extension of a vector field in a trivialisation's base set +section extendLocally + +variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {x : M} + +open scoped Classical in +-- TODO: add longer docs! +-- a starting point (not fully updated any more) is this: +/- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ + +-- comment: need not be smooth (outside of e.baseSet), but this is a useful building block for +-- global smooth extensions of vector fields +-- the latter caps this with a smooth bump function, which need not exist if k=C +-- In contrast, this definition makes sense over any field +-- (for example, *locally* holomorphic sections always exist), + +-- extendLocally: takes trivialisation e as parameter, and a basis b of F +variable {V F} (b e) in +noncomputable def localExtensionOn (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (x : M) (v : V x) : (x' : M) → V x' := + fun x' ↦ if hx : x ∈ e.baseSet then + letI bV := b.localFrame_toBasis_at e hx; ∑ i, bV.repr v i • b.localFrame e i x' + else 0 + +-- in the trivialisation e, the localExtensionOn is constant on e.baseSet +lemma localExtensionOn_apply_of_mem_baseSet (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) : + ∀ x' ∈ e.baseSet, (e ((localExtensionOn b e x v) x')).2 = (e v).2 := by + intro x' hx' + simp [localExtensionOn, hx] + -- main result should be v equals its representation in the local frame; is this always true? + sorry + +-- By construction, localExtensionOn is a linear map. + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +variable {V F} (b e) in +lemma localExtensionOn_add (v v' : V x) : + localExtensionOn b e x (v + v') = localExtensionOn b e x v + localExtensionOn b e x v' := by + ext x' + by_cases hx: x ∈ e.baseSet; swap + · simp [hx, localExtensionOn] + · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +variable {V F} (b e) in +lemma localExtensionOn_smul (a : 𝕜) (v : V x) : + localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by + ext x' + by_cases hx: x ∈ e.baseSet; swap + · simp [hx, localExtensionOn] + · simp [hx, localExtensionOn] + set B := Basis.localFrame_toBasis_at e b hx + have (x') : (a * (B.repr v) x') = a • (B.repr v) x' := by rw [smul_eq_mul] + simp_rw [this, IsScalarTower.smul_assoc a, Finset.smul_sum] + +-- `hx` might not be strictly required; I'm including it for robustness: +-- for other x, this extension is not mathematically meaningful +omit [IsManifold I 0 M] in +lemma contMDiffOn_localExtensionOn {x : M} (hx : x ∈ e.baseSet) (v : V x) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) 1 + (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by + -- idea: in the trivialisation e, everything looks constant (like the vector v transported to F) + rw [contMDiffOn_section_of_mem_baseSet₀] + apply (contMDiffOn_const (c := (e v).2)).congr + intro y hy + rw [localExtensionOn_apply_of_mem_baseSet _ _ _ _ hx _ _ hy] + +end extendLocally + variable (x : M) @[ext] @@ -258,6 +336,8 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] [FiberBundle F V] [VectorBundle ℝ F V] -- `V` vector bundle +/- the following lemmas are subsubmed by tensoriality_criterion + XXX should they be extracted as separate lemmas (stated twice)? omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in /-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ @@ -299,7 +379,7 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp _ = ∑ i, a i x • cov (Xi i) σ x := by congr; ext i; simp [cov.smulX (Xi i) σ (a i)] - _ = 0 := by simp [this] + _ = 0 := by simp [this] -/ /-- `cov X σ x` only depends on `X` via `X x` -/ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] @@ -313,6 +393,8 @@ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ rw [cov.addX] rfl +/- TODO: are these lemmas still useful after the general tensoriality lemma? +are they worth extracting separately? omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] @@ -351,6 +433,7 @@ lemma congr_σ_of_eventuallyEq _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) _ = cov X σ' x := by simp [cov.congr_σ_smoothBumpFunction, mdifferentiableAt_dependent_congr hs hσ hσσ'] +-/ -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x @@ -422,6 +505,8 @@ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] -- TODO: either change `localFrame` to make sure it is everywhere smooth -- or introduce a cut-off here. First option is probaly better. +-- TODO: comment why we chose the second option in the end, and adapt the definition accordingly +-- new definition: smooth a bump function, then smul with localExtensionOn variable (F) in /-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. The details of the extension are mostly unspecified: for covariant derivatives, the value of @@ -475,6 +560,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ lemma contMDiff_extend [FiniteDimensional ℝ F] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend F σ₀ x)) := by + -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function sorry /-- The difference of two covariant derivatives, as a tensorial map -/ From 5bc80fe2298ed4f206bca7c5d0668aa0f4753f76 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 09:59:08 +0200 Subject: [PATCH 071/601] Small clean-up and small progress: one Lean statement is the wrong one --- .../VectorBundle/CovariantDerivative.lean | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 8477f08ef3bb59..4ae7b1a876637d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -120,6 +120,8 @@ variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {x : M} +variable {F V} + open scoped Classical in -- TODO: add longer docs! -- a starting point (not fully updated any more) is this: @@ -136,7 +138,7 @@ Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v -- (for example, *locally* holomorphic sections always exist), -- extendLocally: takes trivialisation e as parameter, and a basis b of F -variable {V F} (b e) in +variable (b e) in noncomputable def localExtensionOn (b : Basis ι 𝕜 F) (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (x : M) (v : V x) : (x' : M) → V x' := @@ -144,20 +146,46 @@ noncomputable def localExtensionOn (b : Basis ι 𝕜 F) letI bV := b.localFrame_toBasis_at e hx; ∑ i, bV.repr v i • b.localFrame e i x' else 0 +-- TODO: clean up this proof, by adding further API as necessary +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localExtensionOn_apply_self (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : + ((localExtensionOn b e x v) x) = v := by + unfold localExtensionOn + simp [hx] + letI bV := b.localFrame_toBasis_at e hx + show ∑ i, bV.repr v i • (b.localFrame_toBasis_at e hx) i = v + conv_rhs => rw [← bV.sum_repr v] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localExtensionOn_apply_self' (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : + (e ((localExtensionOn b e x v) x)).2 = (e v).2 := by + rw [localExtensionOn_apply_self _ _ hx] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -- in the trivialisation e, the localExtensionOn is constant on e.baseSet -lemma localExtensionOn_apply_of_mem_baseSet (b : Basis ι 𝕜 F) +lemma localExtensionOn_apply_of_mem_baseSet (b : Basis ι 𝕜 F) [Fintype ι] (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) : ∀ x' ∈ e.baseSet, (e ((localExtensionOn b e x v) x')).2 = (e v).2 := by intro x' hx' + rw [← localExtensionOn_apply_self' b e hx v] simp [localExtensionOn, hx] - -- main result should be v equals its representation in the local frame; is this always true? + letI bV := b.localFrame_toBasis_at e hx + -- TODO: missing simp lemmas! + simp [Basis.localFrame, hx'] + -- TODO: this Lean statement is false (the sections s^i do depend on the base point x); + -- want I want is the *coefficients* being equals (which is true) + -- -> need to fix the statement first! sorry -- By construction, localExtensionOn is a linear map. omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -variable {V F} (b e) in +variable (b e) in lemma localExtensionOn_add (v v' : V x) : localExtensionOn b e x (v + v') = localExtensionOn b e x v + localExtensionOn b e x v' := by ext x' @@ -166,7 +194,7 @@ lemma localExtensionOn_add (v v' : V x) : · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -variable {V F} (b e) in +variable (b e) in lemma localExtensionOn_smul (a : 𝕜) (v : V x) : localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by ext x' @@ -179,7 +207,8 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : -- `hx` might not be strictly required; I'm including it for robustness: -- for other x, this extension is not mathematically meaningful -omit [IsManifold I 0 M] in +omit [IsManifold I 0 M] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma contMDiffOn_localExtensionOn {x : M} (hx : x ∈ e.baseSet) (v : V x) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) 1 (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by @@ -187,7 +216,7 @@ lemma contMDiffOn_localExtensionOn {x : M} (hx : x ∈ e.baseSet) (v : V x) : rw [contMDiffOn_section_of_mem_baseSet₀] apply (contMDiffOn_const (c := (e v).2)).congr intro y hy - rw [localExtensionOn_apply_of_mem_baseSet _ _ _ _ hx _ _ hy] + rw [localExtensionOn_apply_of_mem_baseSet _ _ hx _ _ hy] end extendLocally From 0799bcc757e0c3786b99b43c79e9c90dfafe22cb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 10:17:08 +0200 Subject: [PATCH 072/601] Fix error; minor clean-up --- .../VectorBundle/CovariantDerivative.lean | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 4ae7b1a876637d..475f12fd3b502f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -410,6 +410,7 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I congr; ext i; simp [cov.smulX (Xi i) σ (a i)] _ = 0 := by simp [this] -/ +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- `cov X σ x` only depends on `X` via `X x` -/ lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hXX' : X x = X' x) : @@ -504,7 +505,7 @@ lemma differenceAux_smul_eq' (cov cov' : CovariantDerivative I F V) /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [FiniteDimensional ℝ F] (X X' : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x₀ : M) (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x₀) (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x₀) @@ -691,17 +692,18 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] simp only [of_endomorphism_toFun, endomorph_of_trivial_aux'''_apply_apply] -- TODO: this case has a gap; if hσ is false, currently hσ' is still true... - have hσ : MDifferentiable 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) - fun x ↦ TotalSpace.mk' E' x (σ x) := sorry - have hσ' : MDifferentiable 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) - fun x' ↦ TotalSpace.mk' E' x' ((extend E' (σ x)) x') := sorry + have hσ : MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) + (fun x' ↦ TotalSpace.mk' E' x' (σ x')) x := sorry + have hσ' : MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) + (fun x' ↦ TotalSpace.mk' E' x' ((extend E' (σ x)) x')) x := sorry rw [← CovariantDerivative.trivial_toFun] have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by -- Do not unfold differenceAux: we use the tensoriality of differenceAux. rw [difference] - -- TODO: should σ and σ' be implicit? - apply foo _ _ _ _ _ _ _ hσ hσ' + -- Should x be implicit? Or X, X', σ, σ' perhaps? + exact differenceAux_tensorial cov (trivial E E') _ _ _ _ _ hσ hσ' + (extend_apply_self (X x)).symm (extend_apply_self (σ x)).symm have h₂ : cov.difference (trivial E E') x (X x) (σ x) = cov (extend E (X x)) (extend E' (σ x)) x - (fderiv ℝ (extend E' (σ x) (x := x)) x) (X x) := by simp From 38f44c46b3631062b9e94249beb1a633de8d2232 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 11:42:25 +0200 Subject: [PATCH 073/601] doc: add more documentation for local frames --- .../Manifold/VectorBundle/LocalFrame.lean | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 4275d47505d144..74a39760d28f42 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -8,8 +8,39 @@ import Mathlib.Geometry.Manifold.VectorBundle.Basic /-! # Local frames in a vector bundle +Let `V → M` be a finite rank smooth vector bundle with standard fiber `F`. +Given a basis `b` for `F` and a local trivialisation `e` for `V`, +we construct a **smooth local frame** on `V` w.r.t. `e` and `b`, +i.e. a collection of sections `s_i` of `V` which is smooth on `e.baseSet` such that `{s_i x}` is a +basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquely written as +`s = ∑ i, f^i s_i` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. + +## Main definitions and results +* `Basis.localFrame e b`: the local frame on `V` w.r.t. a local trivialisation `e` of `V` and a + basis `b` of `F`. Use `b.localFrame e i` to access the i-th section in that frame. +* `b.contMDiffOn_localFrame_baseSet`: each section `b.localFrame e i` is smooth on `e.baseSet` +* `b.localFrame_toBasis_at e`: for each `x ∈ e.baseSet`, the vectors `b.localFrame e i x` form + a basis of `F` +* `Basis.localFrame_repr e b i` describes the coefficient of sections of `V` w.r.t.`b.localFrame e`: + `b.localFrame e i` is a linear map from sections of `V` to functions `M → 𝕜`. +* `b.localFrame_repr_spec e`: near `x`, we have + `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` +* `b.localFrame_repr_congr e`: the coefficient `b.localFrame_repr e b i` of `s` in the local frame + induced by `e` and `b` at `x` only depends on `s` at `x`. +* `b.contMDiffOn_localFrame_repr`: if `s` is a `C^k` section, each coefficient + `b.localFrame_repr e i s` is `C^k` on `e.baseSet` +* TODO: the converse, can test smoothness via local frames + TODO add a more complete doc-string! +## Implementation notes +* local frames use the junk value pattern: they are defined on all of `M`, but their value is + only meaningful inside `e.baseSet` +* anything else I want to add? + +## Tags +vector bundle, local frame, smoothness + -/ open Bundle Filter Function Topology @@ -139,6 +170,8 @@ lemma localFrame_repr_apply_of_mem_baseSet {x : M} omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in variable (b) in +/-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` + of `V` around `x`, we have `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` -/ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := by have {x'} (hx : x' ∈ e.baseSet) : @@ -190,6 +223,8 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle n F V I] [Fintype ι] in +/-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame +near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} @@ -228,6 +263,8 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle n F V I] [Fintype ι] in +/-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` +in the local frame induced by `e` -/ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) @@ -238,6 +275,8 @@ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle n F V I] [Fintype ι] in +/-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame +induced by `e` -/ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : From 8166bc74880f2e072f5bbcf2884b29ab483ff733 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 12:10:26 +0200 Subject: [PATCH 074/601] feat/WIP: testing smoothness of a section in local frames Exposes some more contMDiffOn API which seems to be missing --- .../Manifold/VectorBundle/LocalFrame.lean | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 74a39760d28f42..27d1aeecf478d1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -29,7 +29,10 @@ basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquel induced by `e` and `b` at `x` only depends on `s` at `x`. * `b.contMDiffOn_localFrame_repr`: if `s` is a `C^k` section, each coefficient `b.localFrame_repr e i s` is `C^k` on `e.baseSet` -* TODO: the converse, can test smoothness via local frames +* `b.contMDiffAt_iff_localFrame_repr e`: a section `s` is `C^k` at `x ∈ e.baseSet` + iff all of its frame coefficients are +* `b.contMDiffOn_iff_localFrame_repr e`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` + iff all of its frame coefficients are TODO add a more complete doc-string! @@ -168,17 +171,20 @@ lemma localFrame_repr_apply_of_mem_baseSet {x : M} -- uniqueness of the decomposition: follows from the IsBasis property above +-- TODO: better name? +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localFrame_repr_sum_eq [Fintype ι] (s : Π x : M, V x) {x'} (hx : x' ∈ e.baseSet) : + s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by + simp [Basis.localFrame_repr, hx] + exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm + omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in variable (b) in /-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` of `V` around `x`, we have `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` -/ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := by - have {x'} (hx : x' ∈ e.baseSet) : - s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by - simp [Basis.localFrame_repr, hx] - exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm - exact eventually_nhds_iff.mpr ⟨e.baseSet, fun y a ↦ this a, e.open_baseSet, hxe⟩ + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := + eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_repr_sum_eq s h, e.open_baseSet, hxe⟩ variable {ι : Type*} [Fintype ι] {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} @@ -283,4 +289,47 @@ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSp ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ +/-- A section `s` of `V` is `C^k` at `x ∈ e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma contMDiffAt_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} {x' : M} (hx : x' ∈ e.baseSet) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ + ∀ i, ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x' := by + refine ⟨fun h i ↦ b.contMDiffAt_localFrame_repr hx h i, fun i ↦ ?_⟩ + -- needs two missing API lemmas, see below + sorry + +/-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma contMDiffOn_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} + (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ + ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := by + refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun i ↦ ?_⟩ + + have inner (i) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ + TotalSpace.mk' F x ((localFrame_repr e b i) s x • localFrame e b i x)) t := by + -- lemma localFrame_repr is smooth, localFrame is smooth => scalar product is + -- does this already exist? if not, missing API! + sorry + let rhs := fun x' ↦ ∑ i, (localFrame_repr e b i) s x' • localFrame e b i x' + have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k + (fun x ↦ TotalSpace.mk' F x (rhs x)) t := by + unfold rhs + -- lemma: apply contMDiffOn_finsum, proven by induction, to `inner` + sorry + apply almost.congr + intro y hy + congr + exact localFrame_repr_sum_eq s (ht' hy) + +/-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma contMDiffOn_baseSet_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by + rw [b.contMDiffOn_iff_localFrame_repr e.open_baseSet (subset_refl _)] + end Basis From 6414c4301f5483a1e6fedfcd7270913e6d6065be Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 12:16:25 +0200 Subject: [PATCH 075/601] Prove local extensions are smooth on their base set --- .../VectorBundle/CovariantDerivative.lean | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 475f12fd3b502f..225dcb195a7b72 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -167,20 +167,14 @@ lemma localExtensionOn_apply_self' (b : Basis ι 𝕜 F) omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -- in the trivialisation e, the localExtensionOn is constant on e.baseSet -lemma localExtensionOn_apply_of_mem_baseSet (b : Basis ι 𝕜 F) [Fintype ι] - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) : - ∀ x' ∈ e.baseSet, (e ((localExtensionOn b e x v) x')).2 = (e v).2 := by - intro x' hx' - rw [← localExtensionOn_apply_self' b e hx v] - simp [localExtensionOn, hx] - letI bV := b.localFrame_toBasis_at e hx - -- TODO: missing simp lemmas! - simp [Basis.localFrame, hx'] - -- TODO: this Lean statement is false (the sections s^i do depend on the base point x); - -- want I want is the *coefficients* being equals (which is true) - -- -> need to fix the statement first! - sorry +lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) (i : ι) + {x' : M} (hx' : x' ∈ e.baseSet): + b.localFrame_repr e i (localExtensionOn b e x v) x' = + b.localFrame_repr e i (localExtensionOn b e x v) x := by + -- TODO: missing simp lemmas/ ensure the API is fine here! + simp [Basis.localFrame, hx', localExtensionOn, hx] -- By construction, localExtensionOn is a linear map. @@ -205,18 +199,18 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : have (x') : (a * (B.repr v) x') = a • (B.repr v) x' := by rw [smul_eq_mul] simp_rw [this, IsScalarTower.smul_assoc a, Finset.smul_sum] --- `hx` might not be strictly required; I'm including it for robustness: --- for other x, this extension is not mathematically meaningful -omit [IsManifold I 0 M] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffOn_localExtensionOn {x : M} (hx : x ∈ e.baseSet) (v : V x) : +omit [IsManifold I 0 M] in +lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + {x : M} (hx : x ∈ e.baseSet) (v : V x) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) 1 (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by - -- idea: in the trivialisation e, everything looks constant (like the vector v transported to F) - rw [contMDiffOn_section_of_mem_baseSet₀] - apply (contMDiffOn_const (c := (e v).2)).congr + -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are + -- constant, hence smoothness follows. + rw [b.contMDiffOn_baseSet_iff_localFrame_repr] + intro i + apply (contMDiffOn_const (c := (b.localFrame_repr e i) (localExtensionOn b e x v) x)).congr intro y hy - rw [localExtensionOn_apply_of_mem_baseSet _ _ hx _ _ hy] + rw [localExtensionOn_localFrame_repr b hx v i hy] end extendLocally From 7793f6ca62515817793fa94d25bfb2b846399863 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 12:59:37 +0200 Subject: [PATCH 076/601] chore: move local extension material to LocalFrame.lean also --- .../VectorBundle/CovariantDerivative.lean | 105 +---------------- .../Manifold/VectorBundle/LocalFrame.lean | 106 +++++++++++++++++- 2 files changed, 106 insertions(+), 105 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 225dcb195a7b72..c2edd1f58711e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -113,109 +113,6 @@ lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s end prerequisites --- local extension of a vector field in a trivialisation's base set -section extendLocally - -variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {x : M} - -variable {F V} - -open scoped Classical in --- TODO: add longer docs! --- a starting point (not fully updated any more) is this: -/- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. -The details of the extension are mostly unspecified: for covariant derivatives, the value of -`s` at points other than `x` will not matter (except for shorter proofs). -Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. --/ - --- comment: need not be smooth (outside of e.baseSet), but this is a useful building block for --- global smooth extensions of vector fields --- the latter caps this with a smooth bump function, which need not exist if k=C --- In contrast, this definition makes sense over any field --- (for example, *locally* holomorphic sections always exist), - --- extendLocally: takes trivialisation e as parameter, and a basis b of F -variable (b e) in -noncomputable def localExtensionOn (b : Basis ι 𝕜 F) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (x : M) (v : V x) : (x' : M) → V x' := - fun x' ↦ if hx : x ∈ e.baseSet then - letI bV := b.localFrame_toBasis_at e hx; ∑ i, bV.repr v i • b.localFrame e i x' - else 0 - --- TODO: clean up this proof, by adding further API as necessary -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma localExtensionOn_apply_self (b : Basis ι 𝕜 F) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : - ((localExtensionOn b e x v) x) = v := by - unfold localExtensionOn - simp [hx] - letI bV := b.localFrame_toBasis_at e hx - show ∑ i, bV.repr v i • (b.localFrame_toBasis_at e hx) i = v - conv_rhs => rw [← bV.sum_repr v] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma localExtensionOn_apply_self' (b : Basis ι 𝕜 F) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : - (e ((localExtensionOn b e x v) x)).2 = (e v).2 := by - rw [localExtensionOn_apply_self _ _ hx] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in --- in the trivialisation e, the localExtensionOn is constant on e.baseSet -lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) (i : ι) - {x' : M} (hx' : x' ∈ e.baseSet): - b.localFrame_repr e i (localExtensionOn b e x v) x' = - b.localFrame_repr e i (localExtensionOn b e x v) x := by - -- TODO: missing simp lemmas/ ensure the API is fine here! - simp [Basis.localFrame, hx', localExtensionOn, hx] - --- By construction, localExtensionOn is a linear map. - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -variable (b e) in -lemma localExtensionOn_add (v v' : V x) : - localExtensionOn b e x (v + v') = localExtensionOn b e x v + localExtensionOn b e x v' := by - ext x' - by_cases hx: x ∈ e.baseSet; swap - · simp [hx, localExtensionOn] - · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -variable (b e) in -lemma localExtensionOn_smul (a : 𝕜) (v : V x) : - localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by - ext x' - by_cases hx: x ∈ e.baseSet; swap - · simp [hx, localExtensionOn] - · simp [hx, localExtensionOn] - set B := Basis.localFrame_toBasis_at e b hx - have (x') : (a * (B.repr v) x') = a • (B.repr v) x' := by rw [smul_eq_mul] - simp_rw [this, IsScalarTower.smul_assoc a, Finset.smul_sum] - -omit [IsManifold I 0 M] in -lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - {x : M} (hx : x ∈ e.baseSet) (v : V x) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) 1 - (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by - -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are - -- constant, hence smoothness follows. - rw [b.contMDiffOn_baseSet_iff_localFrame_repr] - intro i - apply (contMDiffOn_const (c := (b.localFrame_repr e i) (localExtensionOn b e x v) x)).congr - intro y hy - rw [localExtensionOn_localFrame_repr b hx v i hy] - -end extendLocally - -variable (x : M) - @[ext] structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) @@ -265,7 +162,7 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] variable {I F V} in /-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ lemma congr_σ (cov : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) : + (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) (x : M) : cov X σ x = cov X σ' x := by simp [funext hσ] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 27d1aeecf478d1..743120a813713b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -15,6 +15,9 @@ i.e. a collection of sections `s_i` of `V` which is smooth on `e.baseSet` such t basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquely written as `s = ∑ i, f^i s_i` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. +We use this to construction local extensions of a vector to a section which is smooth on the +trivialisation domain. + ## Main definitions and results * `Basis.localFrame e b`: the local frame on `V` w.r.t. a local trivialisation `e` of `V` and a basis `b` of `F`. Use `b.localFrame e i` to access the i-th section in that frame. @@ -34,12 +37,14 @@ basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquel * `b.contMDiffOn_iff_localFrame_repr e`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` iff all of its frame coefficients are +* TODO: mention all the localExtensionOn definitions and results + TODO add a more complete doc-string! ## Implementation notes * local frames use the junk value pattern: they are defined on all of `M`, but their value is only meaningful inside `e.baseSet` -* anything else I want to add? +* something about local extensions (and different fields) ## Tags vector bundle, local frame, smoothness @@ -333,3 +338,102 @@ lemma contMDiffOn_baseSet_iff_localFrame_repr [FiniteDimensional 𝕜 F] [Comple rw [b.contMDiffOn_iff_localFrame_repr e.open_baseSet (subset_refl _)] end Basis + +-- local extension of a vector field in a trivialisation's base set +section extendLocally + +variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {x : M} + +open scoped Classical in +-- TODO: add longer docs! +-- a starting point (not fully updated any more) is this: +/- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ + +-- comment: need not be smooth (outside of e.baseSet), but this is a useful building block for +-- global smooth extensions of vector fields +-- the latter caps this with a smooth bump function, which need not exist if k=C +-- In contrast, this definition makes sense over any field +-- (for example, *locally* holomorphic sections always exist), + +-- extendLocally: takes trivialisation e as parameter, and a basis b of F +variable (b e) in +noncomputable def localExtensionOn (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (x : M) (v : V x) : (x' : M) → V x' := + fun x' ↦ if hx : x ∈ e.baseSet then + letI bV := b.localFrame_toBasis_at e hx; ∑ i, bV.repr v i • b.localFrame e i x' + else 0 + +-- TODO: clean up this proof, by adding further API as necessary +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localExtensionOn_apply_self (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : + ((localExtensionOn b e x v) x) = v := by + unfold localExtensionOn + simp [hx] + letI bV := b.localFrame_toBasis_at e hx + show ∑ i, bV.repr v i • (b.localFrame_toBasis_at e hx) i = v + conv_rhs => rw [← bV.sum_repr v] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma localExtensionOn_apply_self' (b : Basis ι 𝕜 F) + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : + (e ((localExtensionOn b e x v) x)).2 = (e v).2 := by + rw [localExtensionOn_apply_self _ _ hx] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +-- in the trivialisation e, the localExtensionOn is constant on e.baseSet +lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) (i : ι) + {x' : M} (hx' : x' ∈ e.baseSet): + b.localFrame_repr e i (localExtensionOn b e x v) x' = + b.localFrame_repr e i (localExtensionOn b e x v) x := by + -- TODO: missing simp lemmas/ ensure the API is fine here! + simp [Basis.localFrame, hx', localExtensionOn, hx] + +-- By construction, localExtensionOn is a linear map. + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +variable (b e) in +lemma localExtensionOn_add (v v' : V x) : + localExtensionOn b e x (v + v') = localExtensionOn b e x v + localExtensionOn b e x v' := by + ext x' + by_cases hx: x ∈ e.baseSet; swap + · simp [hx, localExtensionOn] + · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +variable (b e) in +lemma localExtensionOn_smul (a : 𝕜) (v : V x) : + localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by + ext x' + by_cases hx: x ∈ e.baseSet; swap + · simp [hx, localExtensionOn] + · simp [hx, localExtensionOn] + set B := Basis.localFrame_toBasis_at e b hx + have (x') : (a * (B.repr v) x') = a • (B.repr v) x' := by rw [smul_eq_mul] + simp_rw [this, IsScalarTower.smul_assoc a, Finset.smul_sum] + +omit [IsManifold I 0 M] in +lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + {x : M} (hx : x ∈ e.baseSet) (v : V x) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) 1 + (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by + -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are + -- constant, hence smoothness follows. + rw [b.contMDiffOn_baseSet_iff_localFrame_repr] + intro i + apply (contMDiffOn_const (c := (b.localFrame_repr e i) (localExtensionOn b e x v) x)).congr + intro y hy + rw [localExtensionOn_localFrame_repr b hx v i hy] + +end extendLocally From 90f26a99c328c1765d3b9ac6e582902289829346 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 13:08:58 +0200 Subject: [PATCH 077/601] WIP: improve construction of extend; typeclasses fail to be found --- .../VectorBundle/CovariantDerivative.lean | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c2edd1f58711e1..1021d297bbbebd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -434,19 +434,24 @@ The details of the extension are mostly unspecified: for covariant derivatives, `s` at points other than `x` will not matter (except for shorter proofs). Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. -/ -noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) → V x' := +noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + (x' : M) → V x' := by letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x - letI bV := b.localFrame_toBasis_at t (FiberBundle.mem_baseSet_trivializationAt F V x) - fun x' ↦ ∑ i, bV.repr v i • b.localFrame t i x' - --- FIXME: these two lemmas only hold for *very particular* choices of extensions of v --- (but there exist such choices, and our definition makes these ?! TODO check!!) + letI V₀ := localExtensionOn b t x v + -- Choose a smooth bump function ψ near `x`, supported without t.baseSet + -- and return ψ • V₀ instead + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + choose ψ _ hψ using (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + exact ψ.toFun • localExtensionOn b t x v + +-- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for +-- *well-chosen* extensions (such as ours). -- so, one may argue this is mathematically wrong, but it encodes the "choice some extension -- with this and that property" nicely -- a different proof would be to argue only the value at a point matters for cov @[simp] -lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : +lemma extend_add_apply [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : extend F (v + v') = extend F v + extend F v' := by ext x simp [extend] @@ -464,28 +469,29 @@ lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : sorry @[simp] -lemma extend_smul_apply [FiniteDimensional ℝ F] {a : ℝ} (v : V x) : +lemma extend_smul_apply [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} (v : V x) : extend F (a • v) = a • extend F v := sorry -- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : extend F v x = v := by letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x have x_mem : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt F V x letI bV := b.localFrame_toBasis_at t x_mem - change ∑ i, bV.repr v i • b.localFrame t i x = v - conv_rhs => rw [←bV.sum_repr v] - simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] + sorry + -- change ∑ i, bV.repr v i • b.localFrame t i x = v + -- conv_rhs => rw [←bV.sum_repr v] + -- simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] -lemma contMDiff_extend [FiniteDimensional ℝ F] {x : M} (σ₀ : V x) : +lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend F σ₀ x)) := by -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function sorry /-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] +noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x @@ -503,7 +509,7 @@ noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] -lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] +lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] [T2Space M] (cov cov' : CovariantDerivative I F V) (x : M) (X₀ : TangentSpace I x) (σ₀ : V x) : difference cov cov' x X₀ σ₀ = cov (extend E X₀) (extend F σ₀) x - cov' (extend E X₀) (extend F σ₀) x := rfl From f3e554e798eb91db58aa21fa6a7edac522df0fad Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 13:09:01 +0200 Subject: [PATCH 078/601] Revert "WIP: improve construction of extend; typeclasses fail to be found" This reverts commit 6eef1526a7bba6ffb597c296bd38bcc10111e435. --- .../VectorBundle/CovariantDerivative.lean | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1021d297bbbebd..c2edd1f58711e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -434,24 +434,19 @@ The details of the extension are mostly unspecified: for covariant derivatives, `s` at points other than `x` will not matter (except for shorter proofs). Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. -/ -noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - (x' : M) → V x' := by +noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) → V x' := letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x - letI V₀ := localExtensionOn b t x v - -- Choose a smooth bump function ψ near `x`, supported without t.baseSet - -- and return ψ • V₀ instead - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - choose ψ _ hψ using (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - exact ψ.toFun • localExtensionOn b t x v - --- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for --- *well-chosen* extensions (such as ours). + letI bV := b.localFrame_toBasis_at t (FiberBundle.mem_baseSet_trivializationAt F V x) + fun x' ↦ ∑ i, bV.repr v i • b.localFrame t i x' + +-- FIXME: these two lemmas only hold for *very particular* choices of extensions of v +-- (but there exist such choices, and our definition makes these ?! TODO check!!) -- so, one may argue this is mathematically wrong, but it encodes the "choice some extension -- with this and that property" nicely -- a different proof would be to argue only the value at a point matters for cov @[simp] -lemma extend_add_apply [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : +lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : extend F (v + v') = extend F v + extend F v' := by ext x simp [extend] @@ -469,29 +464,28 @@ lemma extend_add_apply [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x sorry @[simp] -lemma extend_smul_apply [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} (v : V x) : +lemma extend_smul_apply [FiniteDimensional ℝ F] {a : ℝ} (v : V x) : extend F (a • v) = a • extend F v := sorry -- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : extend F v x = v := by letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x have x_mem : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt F V x letI bV := b.localFrame_toBasis_at t x_mem - sorry - -- change ∑ i, bV.repr v i • b.localFrame t i x = v - -- conv_rhs => rw [←bV.sum_repr v] - -- simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] + change ∑ i, bV.repr v i • b.localFrame t i x = v + conv_rhs => rw [←bV.sum_repr v] + simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] -lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : +lemma contMDiff_extend [FiniteDimensional ℝ F] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend F σ₀ x)) := by -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function sorry /-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] +noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x @@ -509,7 +503,7 @@ noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimens omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] -lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] [T2Space M] +lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) (x : M) (X₀ : TangentSpace I x) (σ₀ : V x) : difference cov cov' x X₀ σ₀ = cov (extend E X₀) (extend F σ₀) x - cov' (extend E X₀) (extend F σ₀) x := rfl From b7261a115645370dd7ce6a37859b65707366e61b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 13:45:53 +0200 Subject: [PATCH 079/601] Tweaks --- Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 9 ++++++--- Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean | 3 +-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 743120a813713b..e518458900841b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.VectorBundle.Basic +import Mathlib.Geometry.Manifold.Algebra.Monoid /-! # Local frames in a vector bundle @@ -15,7 +16,7 @@ i.e. a collection of sections `s_i` of `V` which is smooth on `e.baseSet` such t basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquely written as `s = ∑ i, f^i s_i` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. -We use this to construction local extensions of a vector to a section which is smooth on the +We use this to construct local extensions of a vector to a section which is smooth on the trivialisation domain. ## Main definitions and results @@ -318,11 +319,13 @@ lemma contMDiffOn_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace -- lemma localFrame_repr is smooth, localFrame is smooth => scalar product is -- does this already exist? if not, missing API! sorry - let rhs := fun x' ↦ ∑ i, (localFrame_repr e b i) s x' • localFrame e b i x' + let rhs₀ (i) := fun x' ↦ (localFrame_repr e b i) s x' • localFrame e b i x' + let rhs := fun x' ↦ ∑ i, rhs₀ i x' have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := by unfold rhs - -- lemma: apply contMDiffOn_finsum, proven by induction, to `inner` + -- TODO: add a dependent function version of contMDiffOn_finsum, for sections of a vector bundle + -- have aux := contMDiffOn_finsum (I' := I) (I := I.prod 𝓘(𝕜, F)) (f := fun i x ↦ rhs₀ i x) sorry apply almost.congr intro y hy diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 9e537103c80ca0..16c7d6b301a775 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -4,9 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.MFDeriv.Defs -import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.MFDeriv.Basic +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame /-! # The tensoriality criterion From b3fc4104837ecfabd12a090a6b3e496b68960545 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 19:24:25 +0200 Subject: [PATCH 080/601] chore: better variable management --- .../Manifold/VectorBundle/LocalFrame.lean | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index e518458900841b..49cc9cfaffbf59 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -65,8 +65,9 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] (n : WithTop ℕ∞) {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] + -- not needed in this file + -- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] -- `V` vector bundle @@ -80,6 +81,7 @@ noncomputable def localFrame_toBasis_at (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := b.map (e.linearEquivAt (R := 𝕜) x hx).symm + open scoped Classical in -- If x is outside of `e.baseSet`, this returns the junk value 0. noncomputable def localFrame @@ -92,9 +94,7 @@ noncomputable def localFrame -- TODO: understand why this isn’t already a simp lemma attribute [simp] Trivialization.apply_mk_symm -omit [IsManifold I 0 M] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_localFrame_baseSet @@ -107,7 +107,6 @@ lemma contMDiffOn_localFrame_baseSet intro y hy simp [localFrame, hy, localFrame_toBasis_at] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma localFrame_apply_of_mem_baseSet (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) @@ -115,7 +114,6 @@ lemma localFrame_apply_of_mem_baseSet b.localFrame e i x = b.localFrame_toBasis_at e hx i := by simp [localFrame, hx] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma localFrame_apply_of_notMem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) @@ -123,7 +121,7 @@ lemma localFrame_apply_of_notMem b.localFrame e i x = 0 := by simp [localFrame, hx] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in + lemma localFrame_toBasis_at_coe (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] @@ -161,14 +159,12 @@ variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} variable (e b) in -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma localFrame_repr_apply_of_notMem_baseSet {x : M} (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e i s x = 0 := by simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim variable (e b) in -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] lemma localFrame_repr_apply_of_mem_baseSet {x : M} (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : @@ -178,13 +174,11 @@ lemma localFrame_repr_apply_of_mem_baseSet {x : M} -- uniqueness of the decomposition: follows from the IsBasis property above -- TODO: better name? -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma localFrame_repr_sum_eq [Fintype ι] (s : Π x : M, V x) {x'} (hx : x' ∈ e.baseSet) : s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by simp [Basis.localFrame_repr, hx] exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in variable (b) in /-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` of `V` around `x`, we have `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` -/ @@ -192,11 +186,10 @@ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_repr_sum_eq s h, e.open_baseSet, hxe⟩ -variable {ι : Type*} [Fintype ι] {x : M} +variable {ι : Type*} {x : M} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma localFrame_repr_congr (b : Basis ι 𝕜 F) {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : @@ -206,7 +199,6 @@ lemma localFrame_repr_congr (b : Basis ι 𝕜 F) congr · simp [localFrame_repr, hxe] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in lemma localFrame_repr_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : b.localFrame_repr e i s x = 0 := by @@ -225,7 +217,6 @@ lemma localFrame_repr_apply_zero_at variable {n} -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [Fintype ι] in /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ @@ -233,8 +224,7 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle n F V I] [Fintype ι] in +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -273,8 +263,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt exact hbas.comp x h₁ -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle n F V I] [Fintype ι] in +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) @@ -285,8 +274,7 @@ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 fun _ hx ↦ (b.contMDiffAt_localFrame_repr (ht' hx) (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle n F V I] [Fintype ι] in +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -307,8 +295,8 @@ lemma contMDiffAt_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma contMDiffOn_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} +lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := by @@ -334,7 +322,7 @@ lemma contMDiffOn_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma contMDiffOn_baseSet_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by @@ -366,6 +354,7 @@ Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v -- extendLocally: takes trivialisation e as parameter, and a basis b of F variable (b e) in + noncomputable def localExtensionOn (b : Basis ι 𝕜 F) (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (x : M) (v : V x) : (x' : M) → V x' := @@ -374,7 +363,6 @@ noncomputable def localExtensionOn (b : Basis ι 𝕜 F) else 0 -- TODO: clean up this proof, by adding further API as necessary -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma localExtensionOn_apply_self (b : Basis ι 𝕜 F) (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : @@ -385,14 +373,12 @@ lemma localExtensionOn_apply_self (b : Basis ι 𝕜 F) show ∑ i, bV.repr v i • (b.localFrame_toBasis_at e hx) i = v conv_rhs => rw [← bV.sum_repr v] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma localExtensionOn_apply_self' (b : Basis ι 𝕜 F) (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : (e ((localExtensionOn b e x v) x)).2 = (e v).2 := by rw [localExtensionOn_apply_self _ _ hx] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -- in the trivialisation e, the localExtensionOn is constant on e.baseSet lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} @@ -405,7 +391,6 @@ lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) -- By construction, localExtensionOn is a linear map. -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in variable (b e) in lemma localExtensionOn_add (v v' : V x) : localExtensionOn b e x (v + v') = localExtensionOn b e x v + localExtensionOn b e x v' := by @@ -414,7 +399,6 @@ lemma localExtensionOn_add (v v' : V x) : · simp [hx, localExtensionOn] · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in variable (b e) in lemma localExtensionOn_smul (a : 𝕜) (v : V x) : localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by From be92f90fc245a06a0db13169fc9332eaa84e4144 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 30 Jun 2025 19:02:14 +0200 Subject: [PATCH 081/601] Some more suffering --- .../VectorBundle/MDifferentiable.lean | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 98bf9f91818e6e..210ec5454fdeae 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -32,6 +32,7 @@ variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup F] [NormedSpace 𝕜 variable [TopologicalSpace B] [ChartedSpace HB B] [FiberBundle F E] + /-- Characterization of differentiable functions into a vector bundle. -/ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ @@ -54,6 +55,65 @@ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M exact hx · simp only [mfld_simps] +lemma MDifferentiableWithinAt.coordChange {𝕜 : Type*} + {B : Type*} {F : Type*} {M : Type*} {E : B → Type*} [NontriviallyNormedField 𝕜] + [TopologicalSpace (TotalSpace F E)] [(x : B) → TopologicalSpace (E x)] {EB : Type*} + [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {HB : Type*} [TopologicalSpace HB] + (IB : ModelWithCorners 𝕜 EB HB) {EM : Type*} [NormedAddCommGroup EM] [NormedSpace 𝕜 EM] + {HM : Type*} [TopologicalSpace HM] {IM : ModelWithCorners 𝕜 EM HM} [TopologicalSpace M] + [ChartedSpace HM M] [TopologicalSpace B] [ChartedSpace HB B] + [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [NormedAddCommGroup F] + [NormedSpace 𝕜 F] [FiberBundle F E] [VectorBundle 𝕜 F E] + [ContMDiffVectorBundle 1 F E IB] {e : Trivialization F TotalSpace.proj} + (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] + {f : M → TotalSpace F E} {s : Set M} {x₀ : M} + (hf : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀) : + MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ := by + have : ∀ᶠ x in 𝓝[s] x₀, (e (f x)).2 = e'.coordChangeL 𝕜 e (f x).proj (e' (f x)).2 := by + apply eventually_nhdsWithin_of_eventually_nhds + have mem : ∀ᶠ x in 𝓝 x₀, (f x).proj ∈ e'.baseSet ∩ e.baseSet := sorry + filter_upwards [mem] with x hx + rw [e'.coordChangeL_apply e hx, e'.symm_proj_apply (f x) hx.1] + have x₀_mem : (f x₀).proj ∈ e'.baseSet ∩ e.baseSet := sorry + apply Filter.EventuallyEq.mdifferentiableWithinAt_iff this ?_ |>.1 + · have := contMDiffAt_coordChangeL (n := 1) (IB := IB) x₀_mem.1 x₀_mem.2 + have := this.mdifferentiableAt le_rfl + -- have foo : MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (e' b).2) (f x₀) := sorry + -- have := this.clm_apply foo + sorry + rw [e'.coordChangeL_apply e x₀_mem, e'.symm_proj_apply (f x₀) x₀_mem.1] + +theorem mdifferentiableWithinAt_coordChange {𝕜 : Type*} + {B : Type*} {F : Type*} {M : Type*} {E : B → Type*} [NontriviallyNormedField 𝕜] + [TopologicalSpace (TotalSpace F E)] [(x : B) → TopologicalSpace (E x)] {EB : Type*} + [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {HB : Type*} [TopologicalSpace HB] + (IB : ModelWithCorners 𝕜 EB HB) {EM : Type*} [NormedAddCommGroup EM] [NormedSpace 𝕜 EM] + {HM : Type*} [TopologicalSpace HM] {IM : ModelWithCorners 𝕜 EM HM} [TopologicalSpace M] + [ChartedSpace HM M] [TopologicalSpace B] [ChartedSpace HB B] + [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [NormedAddCommGroup F] + [NormedSpace 𝕜 F] [FiberBundle F E] [VectorBundle 𝕜 F E] + [ContMDiffVectorBundle 1 F E IB] + (e e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] + (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : + MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ ↔ + MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := + ⟨fun h ↦ h.coordChange IB e, fun h ↦ h.coordChange IB e'⟩ + +/-- Characterization of differentiable functions into a vector bundle in terms +of any trivialization. -/ +theorem mdifferentiableWithinAt_totalSpace' + [∀ x, AddCommMonoid (E x)] [∀ x, Module 𝕜 (E x)] [NormedAddCommGroup F] + [NormedSpace 𝕜 F] [FiberBundle F E] + [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] + (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] + (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : + MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ + MDifferentiableWithinAt IM IB (fun x => (f x).proj) s x₀ ∧ + MDifferentiableWithinAt IM 𝓘(𝕜, F) + (fun x ↦ (e (f x)).2) s x₀ := by + rw [mdifferentiableWithinAt_totalSpace, + mdifferentiableWithinAt_coordChange IB e (trivializationAt F E (f x₀).proj)] + theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ From ed8f52fc4e3a27e850baaece74030499e883d534 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 29 Jun 2025 13:08:58 +0200 Subject: [PATCH 082/601] chore: improve construction of extend Make it globally smooth, by combining with a smooth cut-off function. Proving the smoothness of the result needs further API for smooth functions, which will come in the next commit. --- .../VectorBundle/CovariantDerivative.lean | 68 ++++++++----------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c2edd1f58711e1..e456b66ecb4697 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -428,64 +428,54 @@ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] -- or introduce a cut-off here. First option is probaly better. -- TODO: comment why we chose the second option in the end, and adapt the definition accordingly -- new definition: smooth a bump function, then smul with localExtensionOn -variable (F) in +variable (I F) in /-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. The details of the extension are mostly unspecified: for covariant derivatives, the value of `s` at points other than `x` will not matter (except for shorter proofs). Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. -/ -noncomputable def extend [FiniteDimensional ℝ F] {x : M} (v : V x) : (x' : M) → V x' := +noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + (x' : M) → V x' := letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x - letI bV := b.localFrame_toBasis_at t (FiberBundle.mem_baseSet_trivializationAt F V x) - fun x' ↦ ∑ i, bV.repr v i • b.localFrame t i x' + letI V₀ := localExtensionOn b t x v + -- Choose a smooth bump function ψ near `x`, supported within t.baseSet + -- and return ψ • V₀ instead. + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + ψ.toFun • localExtensionOn b t x v --- FIXME: these two lemmas only hold for *very particular* choices of extensions of v --- (but there exist such choices, and our definition makes these ?! TODO check!!) +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +-- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for +-- *well-chosen* extensions (such as ours). -- so, one may argue this is mathematically wrong, but it encodes the "choice some extension -- with this and that property" nicely -- a different proof would be to argue only the value at a point matters for cov @[simp] -lemma extend_add_apply [FiniteDimensional ℝ F] {x : M} (v v' : V x) : - extend F (v + v') = extend F v + extend F v' := by - ext x - simp [extend] - expose_names - set b := Basis.ofVectorSpace ℝ F - set t := trivializationAt F V x - --have : x_1 ∈ (trivializationAt F V x_1).baseSet - have (i) : - let hi := FiberBundle.mem_baseSet_trivializationAt F V x_1; - (((b.localFrame_toBasis_at t sorry).repr v) i + - ((b.localFrame_toBasis_at t sorry).repr v') i) • b.localFrame t i x = - ((b.localFrame_toBasis_at t sorry).repr v) i • b.localFrame t i x + - ((b.localFrame_toBasis_at t sorry).repr v') i • b.localFrame t i x := by - sorry - sorry +lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : + extend I F (v + v') = extend I F v + extend I F v' := by + simp [extend, localExtensionOn_add] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] -lemma extend_smul_apply [FiniteDimensional ℝ F] {a : ℝ} (v : V x) : - extend F (a • v) = a • extend F v := sorry +lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} (v : V x) : + extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module --- TODO: cleanup this proof by adding simp lemmas to the localFrame stuff omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] {x : M} (v : V x) : - extend F v x = v := by - letI b := Basis.ofVectorSpace ℝ F - letI t := trivializationAt F V x - have x_mem : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt F V x - letI bV := b.localFrame_toBasis_at t x_mem - change ∑ i, bV.repr v i • b.localFrame t i x = v - conv_rhs => rw [←bV.sum_repr v] - simp [bV, Basis.localFrame_toBasis_at, Basis.localFrame, x_mem] - -lemma contMDiff_extend [FiniteDimensional ℝ F] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend F σ₀ x)) := by +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + extend I F v x = v := by + simpa [extend] using + localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v + +lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function sorry +#exit + /-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] +noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x @@ -503,7 +493,7 @@ noncomputable def difference [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] -lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] +lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] [T2Space M] (cov cov' : CovariantDerivative I F V) (x : M) (X₀ : TangentSpace I x) (σ₀ : V x) : difference cov cov' x X₀ σ₀ = cov (extend E X₀) (extend F σ₀) x - cov' (extend E X₀) (extend F σ₀) x := rfl From 1c9ce353b9eff48d0e71bc39feb4fa02fbfb350d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 30 Jun 2025 18:24:20 +0200 Subject: [PATCH 083/601] chore: tweak localExtensionOn documentation and API --- .../Manifold/VectorBundle/LocalFrame.lean | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 49cc9cfaffbf59..505a068d1b72fe 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -352,42 +352,36 @@ Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v -- In contrast, this definition makes sense over any field -- (for example, *locally* holomorphic sections always exist), --- extendLocally: takes trivialisation e as parameter, and a basis b of F -variable (b e) in +/-- +Extend a vector `v ∈ V x` to a local section of `V`, w.r.t. a chosen local trivialisation. +This construction uses a choice of local frame near `x`, w.r.t. to a basis `b` of `F` and a +compatible local trivialisation `e` of `V` near `x`: the resulting extension has constant +coefficients on `e.baseSet` w.r.t. this trivialisation (and is zero otherwise). +In particular, our construction is smooth on `e.baseSet`, and linear in the input vector `v`. +-/ noncomputable def localExtensionOn (b : Basis ι 𝕜 F) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (x : M) (v : V x) : (x' : M) → V x' := + (e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)) [MemTrivializationAtlas e] + (x : M) (v : V x) : (x' : M) → V x' := fun x' ↦ if hx : x ∈ e.baseSet then letI bV := b.localFrame_toBasis_at e hx; ∑ i, bV.repr v i • b.localFrame e i x' else 0 --- TODO: clean up this proof, by adding further API as necessary -lemma localExtensionOn_apply_self (b : Basis ι 𝕜 F) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : +variable (b e) in +@[simp] +lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : ((localExtensionOn b e x v) x) = v := by - unfold localExtensionOn - simp [hx] - letI bV := b.localFrame_toBasis_at e hx - show ∑ i, bV.repr v i • (b.localFrame_toBasis_at e hx) i = v - conv_rhs => rw [← bV.sum_repr v] - -lemma localExtensionOn_apply_self' (b : Basis ι 𝕜 F) - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (hx : x ∈ e.baseSet) (v : V x) : - (e ((localExtensionOn b e x v) x)).2 = (e v).2 := by - rw [localExtensionOn_apply_self _ _ hx] + simp [localExtensionOn, hx] + nth_rw 2 [← (b.localFrame_toBasis_at e hx).sum_repr v] --- in the trivialisation e, the localExtensionOn is constant on e.baseSet +/-- A local extension has constant frame coefficients within its defining trivialisation. -/ lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) (i : ι) {x' : M} (hx' : x' ∈ e.baseSet): b.localFrame_repr e i (localExtensionOn b e x v) x' = b.localFrame_repr e i (localExtensionOn b e x v) x := by - -- TODO: missing simp lemmas/ ensure the API is fine here! - simp [Basis.localFrame, hx', localExtensionOn, hx] + simp [localExtensionOn, hx, hx'] -- By construction, localExtensionOn is a linear map. From 5382ab680768bf4cbb4451be42361a59b24d2d24 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 30 Jun 2025 18:43:07 +0200 Subject: [PATCH 084/601] feat: prerequisite lemmas, about smoothness of multiplying with a smooth cutoff --- .../VectorBundle/CovariantDerivative.lean | 84 +++++++++++++++++++ .../Manifold/VectorBundle/LocalFrame.lean | 1 + 2 files changed, 85 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e456b66ecb4697..1b61b327547ad5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -113,6 +113,90 @@ lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s end prerequisites +-- prerequisite: smoothness from smoothness on an open cover, +-- and smoothness of pairing with a bump function +section contMDiff_union + +open Set + +-- M be a smooth manifold modeled on (E, H) +variable {𝕜 E E' M M' H H' : Type*} [NontriviallyNormedField 𝕜] + [NormedAddCommGroup E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E] [NormedSpace 𝕜 E'] + [TopologicalSpace H] [TopologicalSpace M] [TopologicalSpace H'] [TopologicalSpace M'] + {n : WithTop ℕ∞} {I : ModelWithCorners 𝕜 E H} {I' : ModelWithCorners 𝕜 E' H'} + [ChartedSpace H M] /-[IsManifold I n M]-/ [ChartedSpace H' M'] -- [IsManifold I' n M'] + {f : M → M'} {s t : Set M} + +-- TODO: add ContMDiffWithinAt, perhaps ContmDiffAt versions! + +/-- If a function is `C^k` on two open sets, it is also `C^n` on their union. -/ +lemma ContMDiffOn.union_of_isOpen (hf : ContMDiffOn I I' n f s) (hf' : ContMDiffOn I I' n f t) + (hs : IsOpen s) (ht : IsOpen t) : + ContMDiffOn I I' n f (s ∪ t) := by + intro x hx + obtain (hx | hx) := hx + · exact (hf x hx).contMDiffAt (hs.mem_nhds hx) |>.contMDiffWithinAt + · exact (hf' x hx).contMDiffAt (ht.mem_nhds hx) |>.contMDiffWithinAt + +/-- A function is `C^k` on two open sets iff it is `C^k` on their union. -/ +lemma contMDiffOn_union_iff_of_isOpen (hs : IsOpen s) (ht : IsOpen t) : + ContMDiffOn I I' n f (s ∪ t) ↔ ContMDiffOn I I' n f s ∧ ContMDiffOn I I' n f t := + ⟨fun h ↦ ⟨h.mono subset_union_left, h.mono subset_union_right⟩, + fun ⟨hfs, hft⟩ ↦ ContMDiffOn.union_of_isOpen hfs hft hs ht⟩ + +lemma contMDiff_of_contMDiffOn_union_of_isOpen (hf : ContMDiffOn I I' n f s) + (hf' : ContMDiffOn I I' n f t) (hst : s ∪ t = univ) (hs : IsOpen s) (ht : IsOpen t) : + ContMDiff I I' n f := by + rw [← contMDiffOn_univ, ← hst] + exact hf.union_of_isOpen hf' hs ht + +-- XXX: continuous version known? +/-- If a function is `C^k` on open sets `s i`, it is `C^k` on their union -/ +lemma ContMDiffOn.iUnion_of_isOpen {ι : Type*} {s : ι → Set M} + (hf : ∀ i : ι, ContMDiffOn I I' n f (s i)) (hs : ∀ i, IsOpen (s i)) : + ContMDiffOn I I' n f (⋃ i, s i) := by + rintro x ⟨si, ⟨i, rfl⟩, hxsi⟩ + exact (hf i).contMDiffAt ((hs i).mem_nhds hxsi) |>.contMDiffWithinAt + +/-- A function is `C^k` on a union of open sets `s i` iff it is `C^k` on each `s i`. -/ +lemma contMDiffOn_iUnion_iff_of_isOpen {ι : Type*} {s : ι → Set M} + (hs : ∀ i, IsOpen (s i)) : + ContMDiffOn I I' n f (⋃ i, s i) ↔ ∀ i : ι, ContMDiffOn I I' n f (s i) := + ⟨fun h i ↦ h.mono <| subset_iUnion_of_subset i fun _ a ↦ a, + fun h ↦ ContMDiffOn.iUnion_of_isOpen h hs⟩ + +lemma contMDiff_of_contMDiffOn_iUnion_of_isOpen {ι : Type*} {s : ι → Set M} + (hf : ∀ i : ι, ContMDiffOn I I' n f (s i)) (hs : ∀ i, IsOpen (s i)) (hs' : ⋃ i, s i = univ) : + ContMDiff I I' n f := by + rw [← contMDiffOn_univ, ← hs'] + exact ContMDiffOn.iUnion_of_isOpen hf hs + +/-- A section is `C^n` whenever it is `C^n` on its support. +This is a more global version of `contMDiff_of_tsupport` (which does not apply, as it assumes the +co-domain has a zero: the total space of a vector bundle has none): in return for the additional +generality, we need to add a hypothesis about the zero section being smooth. -/ +lemma ContMDiff.of_contMDiffOn_smul_bump_function [SMul 𝕜 M'] (hf : ContMDiffOn I I' n f s) + (hs : IsOpen s) {ψ : M → 𝕜} (hψ : ContMDiff I 𝓘(𝕜) n ψ) (hψ' : tsupport ψ ⊆ s) + -- XXX: is there a better abstraction of "the zero section"? + (hzero : ContMDiff I I' n (fun x ↦ (0 : 𝕜) • f x)) : ContMDiff I I' n (ψ • f) := by + apply contMDiff_of_contMDiffOn_union_of_isOpen ?_ ?_ ?_ hs + (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) + · -- TODO: impose further typeclasses to make this true... + sorry -- scalar multiplication is C^n, for sections: will be done for local frames as well + · apply (hzero.contMDiffOn (s := (tsupport ψ)ᶜ)).congr + intro y hy + simp [image_eq_zero_of_notMem_tsupport hy] + · -- XXX: simplify/clean up this proof! + apply le_antisymm (by simp) + rw [← union_compl_self (s := tsupport ψ)] + change tsupport ψ ∪ (tsupport ψ)ᶜ ⊆ s ∪ (tsupport ψ)ᶜ + gcongr + +-- See also `ContMDiff.of_contMDiffOn_smul_bump_function` for the analogous result applying +-- to sections of vector bundles (whose co-domain has no zero). + +end contMDiff_union + @[ext] structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 505a068d1b72fe..73274809ed0f9f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -404,6 +404,7 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : have (x') : (a * (B.repr v) x') = a • (B.repr v) x' := by rw [smul_eq_mul] simp_rw [this, IsScalarTower.smul_assoc a, Finset.smul_sum] +variable (F) in omit [IsManifold I 0 M] in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] {x : M} (hx : x ∈ e.baseSet) (v : V x) : From df59bae93892b53e0baec1c95a3c123a0edec540 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 30 Jun 2025 21:02:49 +0200 Subject: [PATCH 085/601] Better approach for smoothness of extend: very close --- .../VectorBundle/CovariantDerivative.lean | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1b61b327547ad5..4e0d869a4d7e58 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -186,11 +186,7 @@ lemma ContMDiff.of_contMDiffOn_smul_bump_function [SMul 𝕜 M'] (hf : ContMDiff · apply (hzero.contMDiffOn (s := (tsupport ψ)ᶜ)).congr intro y hy simp [image_eq_zero_of_notMem_tsupport hy] - · -- XXX: simplify/clean up this proof! - apply le_antisymm (by simp) - rw [← union_compl_self (s := tsupport ψ)] - change tsupport ψ ∪ (tsupport ψ)ᶜ ⊆ s ∪ (tsupport ψ)ᶜ - gcongr + · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr hψ' -- See also `ContMDiff.of_contMDiffOn_smul_bump_function` for the analogous result applying -- to sections of vector bundles (whose co-domain has no zero). @@ -553,10 +549,33 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by + --letI b := Basis.ofVectorSpace ℝ F + --letI V₀ := localExtensionOn b t x σ₀ + -- Choose a smooth bump function ψ near `x`, supported within t.baseSet + -- and return ψ • V₀ instead. + letI t := trivializationAt F V x + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + -- XXX: extract ψ and hψ as helper declarations, perhaps private to prevent API leakage? + let hψ := + Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + --let res := ψ.toFun • localExtensionOn b t x σ₀ + unfold extend + -- show ContMDiff I (I.prod 𝓘(ℝ, F)) 1 fun x_1 ↦ TotalSpace.mk' F x_1 (extend I F σ₀ x_1) -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function - sorry - -#exit + -- the latter is easier to just prove directly by hand + refine contMDiff_of_contMDiffOn_union_of_isOpen ?_ ?_ ?_ t.open_baseSet (t := (tsupport ψ)ᶜ) ?_ + · sorry + · have aux : ContMDiffOn I (I.prod 𝓘(ℝ, F)) 1 + (fun x_1 ↦ TotalSpace.mk' F x_1 (0 : V x_1)) (tsupport ↑ψ)ᶜ := by + apply ContMDiff.contMDiffOn + -- #check contMDiff_of_locally_contMDiffOn for the helper lemmas above + -- should be contMDiff_zero_section + sorry + apply aux.congr fun y hy ↦ ?_ + simpa [extend] using Or.inl <| image_eq_zero_of_notMem_tsupport hy + · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr hψ.1 + · exact isOpen_compl_iff.mpr <| isClosed_tsupport ψ /-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] From 680f8981454ea490bd3862fa89dd7fb216da77b8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 30 Jun 2025 21:03:00 +0200 Subject: [PATCH 086/601] chore: fix build, by adding missing argument to extend --- .../VectorBundle/CovariantDerivative.lean | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 4e0d869a4d7e58..9f4294c28f19ca 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -581,7 +581,7 @@ lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := - fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x + fun x X₀ σ₀ ↦ differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x -- -- Note: we conciously register this lemma in unapplied form, -- -- but differenceAux_apply: this means the applied form should simplify down all the way, @@ -599,7 +599,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] [T2Space M] (cov cov' : CovariantDerivative I F V) (x : M) (X₀ : TangentSpace I x) (σ₀ : V x) : difference cov cov' x X₀ σ₀ = - cov (extend E X₀) (extend F σ₀) x - cov' (extend E X₀) (extend F σ₀) x := rfl + cov (extend I E X₀) (extend I F σ₀) x - cov' (extend I E X₀) (extend I F σ₀) x := rfl -- The classification of real connections over a trivial bundle section classification @@ -613,14 +613,14 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime toFun := difference cov (CovariantDerivative.trivial E E') x X map_add' y y' := by -- follows from the (not yet proven) smoothness - have A : fderiv ℝ ((extend E' y (x := x)) + extend E' y' (x := x)) x = - fderiv ℝ (extend E' y (x := x)) x + fderiv ℝ (extend E' y' (x := x)) x := by + have A : fderiv ℝ ((extend 𝓘(ℝ, E) E' y (x := x)) + extend 𝓘(ℝ, E) E' y' (x := x)) x = + fderiv ℝ (extend 𝓘(ℝ, E) E' y (x := x)) x + fderiv ℝ (extend 𝓘(ℝ, E) E' y' (x := x)) x := by rw [fderiv_add] · sorry -- apply (contMDiff_extend _ _).contMDiffAt.DifferentiableAt · sorry -- similar - have B : cov (extend E X (x := x)) (extend E' y (x := x) + extend E' y' (x := x)) x = - cov (extend E X (x := x)) (extend E' y (x := x)) x + - cov (extend E X (x := x)) (extend E' y' (x := x)) x := by + have B : cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = + cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + + cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y' (x := x)) x := by apply cov.addσ · exact (contMDiff_extend _ _).mdifferentiableAt (n := 1) (hn := by norm_num) · apply (contMDiff_extend _ _).mdifferentiableAt (n := 1) (hn := by norm_num) @@ -642,19 +642,19 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi toFun X := cov.endomorph_of_trivial_aux' x X map_add' X Y := by ext Z - simp [cov.addX (extend E X (x := x)) (extend E Y (x := x)) (extend E' Z (x := x))] + simp [cov.addX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E Y (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x))] module map_smul' t X := by ext Z simp -- The following lines should ideally mold into the simp call above. - trans t • (cov (extend E X (x := x)) (extend E' Z (x := x)) x) - - t • (fderiv ℝ (extend E' Z (x := x)) x) X + trans t • (cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) x) + - t • (fderiv ℝ (extend 𝓘(ℝ, E) E' Z (x := x)) x) X swap; · module congr -- TODO: this is almost the item we want, but not quite! not sure where the mismatch comes from - let asdf := cov.smulX (extend E X (x := x)) (extend E' Z (x := x)) (fun x ↦ t) + let asdf := cov.smulX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) sorry @[simps!] @@ -679,7 +679,7 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] have hσ : MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) (fun x' ↦ TotalSpace.mk' E' x' (σ x')) x := sorry have hσ' : MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) - (fun x' ↦ TotalSpace.mk' E' x' ((extend E' (σ x)) x')) x := sorry + (fun x' ↦ TotalSpace.mk' E' x' ((extend 𝓘(ℝ, E) E' (σ x)) x')) x := sorry rw [← CovariantDerivative.trivial_toFun] have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by @@ -689,7 +689,8 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] exact differenceAux_tensorial cov (trivial E E') _ _ _ _ _ hσ hσ' (extend_apply_self (X x)).symm (extend_apply_self (σ x)).symm have h₂ : cov.difference (trivial E E') x (X x) (σ x) = - cov (extend E (X x)) (extend E' (σ x)) x - (fderiv ℝ (extend E' (σ x) (x := x)) x) (X x) := by + cov (extend 𝓘(ℝ, E) E (X x)) (extend 𝓘(ℝ, E) E' (σ x)) x + - (fderiv ℝ (extend 𝓘(ℝ, E) E' (σ x) (x := x)) x) (X x) := by simp rw [← h₂, ← h₁] module From d39e6df18ba0cfa6755e8374200c63c9b137149d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 30 Jun 2025 21:11:44 +0200 Subject: [PATCH 087/601] To summarize: getting close, but not there yet --- .../Manifold/VectorBundle/CovariantDerivative.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 9f4294c28f19ca..8c0b6a7771d1fc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -612,12 +612,15 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x X : E) : E' →ₗ[ℝ] E' where toFun := difference cov (CovariantDerivative.trivial E E') x X map_add' y y' := by - -- follows from the (not yet proven) smoothness have A : fderiv ℝ ((extend 𝓘(ℝ, E) E' y (x := x)) + extend 𝓘(ℝ, E) E' y' (x := x)) x = fderiv ℝ (extend 𝓘(ℝ, E) E' y (x := x)) x + fderiv ℝ (extend 𝓘(ℝ, E) E' y' (x := x)) x := by rw [fderiv_add] - · sorry -- apply (contMDiff_extend _ _).contMDiffAt.DifferentiableAt - · sorry -- similar + · sorry -- like the sorry below! + · apply Differentiable.differentiableAt + rw [← mdifferentiable_iff_differentiable] + apply ContMDiff.mdifferentiable (n := 1) (hn := by norm_num) + sorry -- is contMDiff_extend, except that now we care about + -- the outcome of post-composing with the projection from Trivial E E' to E'... have B : cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y' (x := x)) x := by From ef934c2c392f1117ee851e764634a0677f893918 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 30 Jun 2025 23:40:06 +0200 Subject: [PATCH 088/601] Finish awful differentiability proof --- .../VectorBundle/MDifferentiable.lean | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 210ec5454fdeae..7d4e177d99e510 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -67,21 +67,24 @@ lemma MDifferentiableWithinAt.coordChange {𝕜 : Type*} [ContMDiffVectorBundle 1 F E IB] {e : Trivialization F TotalSpace.proj} (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} - (hf : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀) : + (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) + (hf : MDifferentiableWithinAt IM IB (fun x ↦ (f x).proj) s x₀) + (he'f : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀) : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ := by have : ∀ᶠ x in 𝓝[s] x₀, (e (f x)).2 = e'.coordChangeL 𝕜 e (f x).proj (e' (f x)).2 := by - apply eventually_nhdsWithin_of_eventually_nhds - have mem : ∀ᶠ x in 𝓝 x₀, (f x).proj ∈ e'.baseSet ∩ e.baseSet := sorry + have mem : ∀ᶠ x in 𝓝[s] x₀, (f x).proj ∈ e'.baseSet ∩ e.baseSet := by + exact hf.continuousWithinAt <| + (e'.open_baseSet.eventually_mem he'x₀).and (e.open_baseSet.eventually_mem hex₀) filter_upwards [mem] with x hx rw [e'.coordChangeL_apply e hx, e'.symm_proj_apply (f x) hx.1] - have x₀_mem : (f x₀).proj ∈ e'.baseSet ∩ e.baseSet := sorry apply Filter.EventuallyEq.mdifferentiableWithinAt_iff this ?_ |>.1 - · have := contMDiffAt_coordChangeL (n := 1) (IB := IB) x₀_mem.1 x₀_mem.2 - have := this.mdifferentiableAt le_rfl - -- have foo : MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (e' b).2) (f x₀) := sorry - -- have := this.clm_apply foo - sorry - rw [e'.coordChangeL_apply e x₀_mem, e'.symm_proj_apply (f x₀) x₀_mem.1] + · let c := Trivialization.coordChangeL 𝕜 e' e + have bar : MDifferentiableWithinAt IM 𝓘(𝕜, F →L[𝕜] F) + (fun x : M ↦ (c (f x).proj : F →L[𝕜] F)) s x₀ := by + exact contMDiffAt_coordChangeL he'x₀ hex₀ |>.mdifferentiableAt le_rfl + |>.comp_mdifferentiableWithinAt x₀ hf + exact bar.clm_apply he'f + rw [e'.coordChangeL_apply e ⟨he'x₀, hex₀⟩, e'.symm_proj_apply (f x₀) he'x₀] theorem mdifferentiableWithinAt_coordChange {𝕜 : Type*} {B : Type*} {F : Type*} {M : Type*} {E : B → Type*} [NontriviallyNormedField 𝕜] @@ -94,25 +97,30 @@ theorem mdifferentiableWithinAt_coordChange {𝕜 : Type*} [NormedSpace 𝕜 F] [FiberBundle F E] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] (e e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] - (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : + {f : M → TotalSpace F E} {s : Set M} {x₀ : M} + (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) + (hf : MDifferentiableWithinAt IM IB (fun x ↦ (f x).proj) s x₀) : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ ↔ MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := - ⟨fun h ↦ h.coordChange IB e, fun h ↦ h.coordChange IB e'⟩ + ⟨hf.coordChange IB e he'x₀ hex₀, hf.coordChange IB e' hex₀ he'x₀⟩ /-- Characterization of differentiable functions into a vector bundle in terms of any trivialization. -/ theorem mdifferentiableWithinAt_totalSpace' - [∀ x, AddCommMonoid (E x)] [∀ x, Module 𝕜 (E x)] [NormedAddCommGroup F] - [NormedSpace 𝕜 F] [FiberBundle F E] + [∀ x, AddCommMonoid (E x)] [∀ x, Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] - (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : + (f : M → TotalSpace F E) {s : Set M} {x₀ : M} + (hex₀ : (f x₀).proj ∈ e.baseSet) : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ MDifferentiableWithinAt IM IB (fun x => (f x).proj) s x₀ ∧ MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ := by - rw [mdifferentiableWithinAt_totalSpace, - mdifferentiableWithinAt_coordChange IB e (trivializationAt F E (f x₀).proj)] + rw [mdifferentiableWithinAt_totalSpace] + apply and_congr_right + intro hf + rw [mdifferentiableWithinAt_coordChange IB e (trivializationAt F E (f x₀).proj) hex₀ + (FiberBundle.mem_baseSet_trivializationAt' _) hf] theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ From 939bba65e6826b14c470bb9151057e7f6afbb027 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 10:35:55 +0200 Subject: [PATCH 089/601] Cleanup --- .../VectorBundle/MDifferentiable.lean | 70 ++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 7d4e177d99e510..051de3c416b83c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -55,17 +55,19 @@ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M exact hx · simp only [mfld_simps] -lemma MDifferentiableWithinAt.coordChange {𝕜 : Type*} - {B : Type*} {F : Type*} {M : Type*} {E : B → Type*} [NontriviallyNormedField 𝕜] - [TopologicalSpace (TotalSpace F E)] [(x : B) → TopologicalSpace (E x)] {EB : Type*} - [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {HB : Type*} [TopologicalSpace HB] - (IB : ModelWithCorners 𝕜 EB HB) {EM : Type*} [NormedAddCommGroup EM] [NormedSpace 𝕜 EM] - {HM : Type*} [TopologicalSpace HM] {IM : ModelWithCorners 𝕜 EM HM} [TopologicalSpace M] - [ChartedSpace HM M] [TopologicalSpace B] [ChartedSpace HB B] - [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [NormedAddCommGroup F] - [NormedSpace 𝕜 F] [FiberBundle F E] [VectorBundle 𝕜 F E] - [ContMDiffVectorBundle 1 F E IB] {e : Trivialization F TotalSpace.proj} - (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] +theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : + MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ + MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ + MDifferentiableAt IM 𝓘(𝕜, F) + (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by + simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f + +variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] + [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] + +lemma MDifferentiableWithinAt.coordChange + {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] + (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) (hf : MDifferentiableWithinAt IM IB (fun x ↦ (f x).proj) s x₀) @@ -86,17 +88,8 @@ lemma MDifferentiableWithinAt.coordChange {𝕜 : Type*} exact bar.clm_apply he'f rw [e'.coordChangeL_apply e ⟨he'x₀, hex₀⟩, e'.symm_proj_apply (f x₀) he'x₀] -theorem mdifferentiableWithinAt_coordChange {𝕜 : Type*} - {B : Type*} {F : Type*} {M : Type*} {E : B → Type*} [NontriviallyNormedField 𝕜] - [TopologicalSpace (TotalSpace F E)] [(x : B) → TopologicalSpace (E x)] {EB : Type*} - [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {HB : Type*} [TopologicalSpace HB] - (IB : ModelWithCorners 𝕜 EB HB) {EM : Type*} [NormedAddCommGroup EM] [NormedSpace 𝕜 EM] - {HM : Type*} [TopologicalSpace HM] {IM : ModelWithCorners 𝕜 EM HM} [TopologicalSpace M] - [ChartedSpace HM M] [TopologicalSpace B] [ChartedSpace HB B] - [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [NormedAddCommGroup F] - [NormedSpace 𝕜 F] [FiberBundle F E] [VectorBundle 𝕜 F E] - [ContMDiffVectorBundle 1 F E IB] - (e e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] +theorem mdifferentiableWithinAt_coordChange + {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) (hf : MDifferentiableWithinAt IM IB (fun x ↦ (f x).proj) s x₀) : @@ -104,11 +97,18 @@ theorem mdifferentiableWithinAt_coordChange {𝕜 : Type*} MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := ⟨hf.coordChange IB e he'x₀ hex₀, hf.coordChange IB e' hex₀ he'x₀⟩ +theorem mdifferentiableAt_change_triv + {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] + {f : M → TotalSpace F E} {x₀ : M} + (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) + (hf : MDifferentiableAt IM IB (fun x ↦ (f x).proj) x₀) : + MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) x₀ ↔ + MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) x₀ := by + simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_coordChange IB hex₀ he'x₀ hf + /-- Characterization of differentiable functions into a vector bundle in terms -of any trivialization. -/ -theorem mdifferentiableWithinAt_totalSpace' - [∀ x, AddCommMonoid (E x)] [∀ x, Module 𝕜 (E x)] - [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] +of any trivialization. Version at a point within at set. -/ +theorem Trivialization.mdifferentiableWithinAt_totalSpace_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (f : M → TotalSpace F E) {s : Set M} {x₀ : M} (hex₀ : (f x₀).proj ∈ e.baseSet) : @@ -119,16 +119,22 @@ theorem mdifferentiableWithinAt_totalSpace' rw [mdifferentiableWithinAt_totalSpace] apply and_congr_right intro hf - rw [mdifferentiableWithinAt_coordChange IB e (trivializationAt F E (f x₀).proj) hex₀ - (FiberBundle.mem_baseSet_trivializationAt' _) hf] + rw [mdifferentiableWithinAt_coordChange IB hex₀ (FiberBundle.mem_baseSet_trivializationAt' _) hf] -theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : +/-- Characterization of differentiable functions into a vector bundle in terms +of any trivialization. Version at a point. -/ +theorem Trivialization.mdifferentiableAt_totalSpace_iff + (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] + (f : M → TotalSpace F E) {x₀ : M} + (hex₀ : (f x₀).proj ∈ e.baseSet) : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ MDifferentiableAt IM 𝓘(𝕜, F) - (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by - simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f - + (fun x ↦ (e (f x)).2) x₀ := by + rw [mdifferentiableAt_totalSpace] + apply and_congr_right + intro hf + rw [mdifferentiableAt_change_triv IB hex₀ (FiberBundle.mem_baseSet_trivializationAt' _) hf] end section From 0e0152da4bdcbe422166e683742399586bebf937 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 10:26:25 +0200 Subject: [PATCH 090/601] More contMDiff_foo_section API (and slightly clean up variables in that section) --- .../VectorBundle/CovariantDerivative.lean | 172 +++++++++++++++++- 1 file changed, 170 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 8c0b6a7771d1fc..da407ed451189d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -127,8 +127,6 @@ variable {𝕜 E E' M M' H H' : Type*} [NontriviallyNormedField 𝕜] [ChartedSpace H M] /-[IsManifold I n M]-/ [ChartedSpace H' M'] -- [IsManifold I' n M'] {f : M → M'} {s t : Set M} --- TODO: add ContMDiffWithinAt, perhaps ContmDiffAt versions! - /-- If a function is `C^k` on two open sets, it is also `C^n` on their union. -/ lemma ContMDiffOn.union_of_isOpen (hf : ContMDiffOn I I' n f s) (hf' : ContMDiffOn I I' n f t) (hs : IsOpen s) (ht : IsOpen t) : @@ -193,6 +191,176 @@ lemma ContMDiff.of_contMDiffOn_smul_bump_function [SMul 𝕜 M'] (hf : ContMDiff end contMDiff_union +section contMDiff_addsmulfinsum_section + +-- Proofs taken from SmoothSection: TODO golf those with these lemmas! +-- XXX: also add sub, neg, nsmul, zsmul lemmas? + +variable {I F n V} + +variable {f : M → 𝕜} {a : 𝕜} {s t : Π x : M, V x} {u : Set M} {x₀ : M} + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffWithinAt_add_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (ht : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by + rw [contMDiffWithinAt_section] at hs ht ⊢ + set e := trivializationAt F V x₀ + + refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) + · intro x hx + apply (e.linear 𝕜 hx).1 + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).1 + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffAt_add_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by + rw [contMDiffAt_section] at hs ht ⊢ + set e := trivializationAt F V x₀ + refine (hs.add ht).congr_of_eventuallyEq ?_ + refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ + intro x hx + apply (e.linear 𝕜 hx).1 + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffOn_add_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) + (ht : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_add_section (hs x₀ hx₀) (ht x₀ hx₀) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiff_add_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) + (ht : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := + fun x₀ ↦ contMDiffAt_add_section (hs x₀) (ht x₀) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffWithinAt_smul_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by + rw [contMDiffWithinAt_section] at hs ⊢ + set e := trivializationAt F V x₀ + refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) + · intro x hx + apply (e.linear 𝕜 hx).2 + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffAt_smul_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (hf : ContMDiffAt I 𝓘(𝕜) n f x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by + rw [contMDiffAt_section] at hs ⊢ + set e := trivializationAt F V x₀ + refine (hf.smul hs).congr_of_eventuallyEq ?_ + refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ + intro x hx + apply (e.linear 𝕜 hx).2 + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffOn_smul_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) + (hf : ContMDiffOn I 𝓘(𝕜) n f u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_smul_section (hs x₀ hx₀) (hf x₀ hx₀) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiff_smul_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) + (hf : ContMDiff I 𝓘(𝕜) n f) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) := + fun x₀ ↦ contMDiffAt_smul_section (hs x₀) (hf x₀) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffWithinAt_smul_const_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := + contMDiffWithinAt_smul_section hs contMDiffWithinAt_const + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffAt_smul_const_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := + contMDiffAt_smul_section hs contMDiffAt_const + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffOn_smul_const_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u := + contMDiffOn_smul_section hs contMDiffOn_const + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiff_smul_const_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) := + fun x₀ ↦ contMDiffAt_smul_const_section (hs x₀) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} + (hs : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n + (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by + classical + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + -- TODO: x₀ ∈ u should not be required -> add contMDiffWithinAt_zeroSection! + apply ContMDiff.contMDiffOn + · apply contMDiff_zeroSection + · sorry -- x₀ ∈ u... + | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} {x₀ : M} + (hs : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by + classical + induction s using Finset.induction_on with + | empty => simpa using contMDiff_zeroSection .. + | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiffOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} + (hs : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_finsum_section fun i ↦ hs i x₀ hx₀ + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma contMDiff_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} + (hs : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := + fun x₀ ↦ contMDiffAt_finsum_section fun i ↦ (hs i) x₀ + +end contMDiff_addsmulfinsum_section + @[ext] structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) From 837190b593734f3652de48690bddbec2f1702c99 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 11:13:40 +0200 Subject: [PATCH 091/601] Fix the build and a few new warnings --- .../VectorBundle/CovariantDerivative.lean | 21 ++++++++++--------- .../Manifold/VectorBundle/LocalFrame.lean | 7 ++++--- .../Manifold/VectorBundle/Tensoriality.lean | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index da407ed451189d..47c6804c1cf389 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -422,7 +422,7 @@ lemma sum_X (cov : CovariantDerivative I F V) classical induction s using Finset.induction_on with | empty => simp - | insert a s ha h => simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h, cov.addX] + | insert a s ha h => simp [Finset.sum_insert ha, ← h, cov.addX] /-- A convex combination of covariant derivatives is a covariant derivative. -/ @[simps] @@ -469,22 +469,21 @@ noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : addX X X' σ := by ext x by_cases h : DifferentiableAt 𝕜 σ x - · simp [h, map_add]; abel + · simp [map_add]; abel · simp [fderiv_zero_of_not_differentiableAt h] smulX X σ c' := by ext; simp addσ X σ σ' e hσ hσ' := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' - rw [fderiv_add hσ hσ'] - simp [hσ, hσ'] + simp [fderiv_add hσ hσ'] abel smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] leibniz X σ f x hσ hf := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ rw [mdifferentiableAt_iff_differentiableAt] at hf - have h : DifferentiableAt 𝕜 (f • σ) x := hf.smul hσ + -- have h : DifferentiableAt 𝕜 (f • σ) x := hf.smul hσ have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := fderiv_smul (by simp_all) (by simp_all) - simp [this, bar, hσ, h] + simp [this, bar] module section real @@ -686,7 +685,6 @@ noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) (x' : M) → V x' := letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x - letI V₀ := localExtensionOn b t x v -- Choose a smooth bump function ψ near `x`, supported within t.baseSet -- and return ψ • V₀ instead. letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) @@ -746,7 +744,8 @@ lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V · exact isOpen_compl_iff.mpr <| isClosed_tsupport ψ /-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] +noncomputable def difference + [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) : Π x : M, TangentSpace I x → V x → V x := fun x X₀ σ₀ ↦ differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x @@ -789,7 +788,8 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime apply ContMDiff.mdifferentiable (n := 1) (hn := by norm_num) sorry -- is contMDiff_extend, except that now we care about -- the outcome of post-composing with the projection from Trivial E E' to E'... - have B : cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = + have B : cov (extend 𝓘(ℝ, E) E X (x := x)) + (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y' (x := x)) x := by apply cov.addσ @@ -813,7 +813,8 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi toFun X := cov.endomorph_of_trivial_aux' x X map_add' X Y := by ext Z - simp [cov.addX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E Y (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x))] + simp [cov.addX (extend 𝓘(ℝ, E) E X (x := x)) + (extend 𝓘(ℝ, E) E Y (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x))] module map_smul' t X := by ext Z diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 73274809ed0f9f..8004e54e76241d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -399,10 +399,11 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : ext x' by_cases hx: x ∈ e.baseSet; swap · simp [hx, localExtensionOn] - · simp [hx, localExtensionOn] + · simp [hx, localExtensionOn, Finset.smul_sum] set B := Basis.localFrame_toBasis_at e b hx - have (x') : (a * (B.repr v) x') = a • (B.repr v) x' := by rw [smul_eq_mul] - simp_rw [this, IsScalarTower.smul_assoc a, Finset.smul_sum] + congr + ext i + rw [mul_smul a ((B.repr v) i)] variable (F) in omit [IsManifold I 0 M] in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 16c7d6b301a775..df825ddb6f3f9e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -83,7 +83,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDim apply (contMDiff_zeroSection _ _).mdifferentiableAt ENat.LEInfty.out | insert a s ha h => change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h] + simp [Finset.sum_insert ha, ← h] erw [φ_add] apply hσ a sorry @@ -137,7 +137,7 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi simp | insert a s ha h => change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h] + simp [Finset.sum_insert ha, ← h] erw [φ_add] have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F From b54248043a96f6338f40e98e15e594a6b424db48 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 11:18:22 +0200 Subject: [PATCH 092/601] Add differentiability to cheatsheet --- Mathlib/Geometry/Manifold/CheatSheet.md | 35 +++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/CheatSheet.md b/Mathlib/Geometry/Manifold/CheatSheet.md index 881259a7c17545..e5f3b55b074742 100644 --- a/Mathlib/Geometry/Manifold/CheatSheet.md +++ b/Mathlib/Geometry/Manifold/CheatSheet.md @@ -34,8 +34,39 @@ variable {𝕜 E M H : Type*} [NontriviallyNormedField 𝕜] [NormedAddCommGroup {I : ModelWithCorners 𝕜 E H} [ChartedSpace H M] [IsManifold I ω M] ``` -Let f : M \to N be smooth. -Let f : M \to E (a normed space) be smooth. +Differentiability of functions between manifolds +``` +import Mathlib.Geometry.Manifold.MFDeriv.Defs +import Mathlib.Geometry.Manifold.ContMDiff.Defs + +variable + -- Given a non-trivially normed field 𝕜 + {𝕜 : Type*} [NontriviallyNormedField 𝕜] + -- A manifold M over 𝕜 + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + -- A manifold M' over 𝕜 + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 E' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + -- A function from M to M' and x in M + (f : M → M') (x : M) + +variable (x : M) in +-- f is differentiable at x +#check MDifferentiableAt I I' f x + +variable (n : WithTop ℕ∞) in -- A natural number or ∞ or ω +#check ContMDiff I I' n f + + +variable + {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + (g : M → F) in +open scoped Manifold in +#check ContMDiff I 𝓘(𝕜, F) n g -- g is n times continuously differentiable +``` Consider the product manifold M \times N. From 5a90653f89f9dc7291f5910f0095d60f1a619c43 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 11:47:28 +0200 Subject: [PATCH 093/601] chore: move contMDiffFoo_section API to SmoothSection - use it to golf the instances there - also tick off one sorry in LocalFrame, which was just these --- .../VectorBundle/CovariantDerivative.lean | 170 ------------------ .../Manifold/VectorBundle/LocalFrame.lean | 15 +- .../Manifold/VectorBundle/SmoothSection.lean | 164 ++++++++++++++--- 3 files changed, 148 insertions(+), 201 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 47c6804c1cf389..5d3b85f54a47f1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -191,176 +191,6 @@ lemma ContMDiff.of_contMDiffOn_smul_bump_function [SMul 𝕜 M'] (hf : ContMDiff end contMDiff_union -section contMDiff_addsmulfinsum_section - --- Proofs taken from SmoothSection: TODO golf those with these lemmas! --- XXX: also add sub, neg, nsmul, zsmul lemmas? - -variable {I F n V} - -variable {f : M → 𝕜} {a : 𝕜} {s t : Π x : M, V x} {u : Set M} {x₀ : M} - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffWithinAt_add_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (ht : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by - rw [contMDiffWithinAt_section] at hs ht ⊢ - set e := trivializationAt F V x₀ - - refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ - · apply eventually_of_mem (U := e.baseSet) - · exact mem_nhdsWithin_of_mem_nhds <| - (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) - · intro x hx - apply (e.linear 𝕜 hx).1 - · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).1 - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffAt_add_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by - rw [contMDiffAt_section] at hs ht ⊢ - set e := trivializationAt F V x₀ - refine (hs.add ht).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).1 - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffOn_add_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) - (ht : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u := - fun x₀ hx₀ ↦ contMDiffWithinAt_add_section (hs x₀ hx₀) (ht x₀ hx₀) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiff_add_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) - (ht : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := - fun x₀ ↦ contMDiffAt_add_section (hs x₀) (ht x₀) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffWithinAt_smul_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by - rw [contMDiffWithinAt_section] at hs ⊢ - set e := trivializationAt F V x₀ - refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ - · apply eventually_of_mem (U := e.baseSet) - · exact mem_nhdsWithin_of_mem_nhds <| - (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) - · intro x hx - apply (e.linear 𝕜 hx).2 - · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffAt_smul_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (hf : ContMDiffAt I 𝓘(𝕜) n f x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by - rw [contMDiffAt_section] at hs ⊢ - set e := trivializationAt F V x₀ - refine (hf.smul hs).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).2 - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffOn_smul_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) - (hf : ContMDiffOn I 𝓘(𝕜) n f u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := - fun x₀ hx₀ ↦ contMDiffWithinAt_smul_section (hs x₀ hx₀) (hf x₀ hx₀) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiff_smul_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) - (hf : ContMDiff I 𝓘(𝕜) n f) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) := - fun x₀ ↦ contMDiffAt_smul_section (hs x₀) (hf x₀) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffWithinAt_smul_const_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := - contMDiffWithinAt_smul_section hs contMDiffWithinAt_const - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffAt_smul_const_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := - contMDiffAt_smul_section hs contMDiffAt_const - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffOn_smul_const_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u := - contMDiffOn_smul_section hs contMDiffOn_const - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiff_smul_const_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) := - fun x₀ ↦ contMDiffAt_smul_const_section (hs x₀) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} - (hs : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n - (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by - classical - induction s using Finset.induction_on with - | empty => - simp only [Finset.sum_empty] - -- TODO: x₀ ∈ u should not be required -> add contMDiffWithinAt_zeroSection! - apply ContMDiff.contMDiffOn - · apply contMDiff_zeroSection - · sorry -- x₀ ∈ u... - | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} {x₀ : M} - (hs : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by - classical - induction s using Finset.induction_on with - | empty => simpa using contMDiff_zeroSection .. - | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiffOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} - (hs : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := - fun x₀ hx₀ ↦ contMDiffWithinAt_finsum_section fun i ↦ hs i x₀ hx₀ - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma contMDiff_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} - (hs : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := - fun x₀ ↦ contMDiffAt_finsum_section fun i ↦ (hs i) x₀ - -end contMDiff_addsmulfinsum_section - @[ext] structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 8004e54e76241d..82b4fe8b4fd911 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -3,8 +3,8 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Geometry.Manifold.Algebra.Monoid +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection /-! # Local frames in a vector bundle @@ -241,7 +241,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 apply this.congr_of_eventuallyEq_of_mem ?_ trivial apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, hy, Basis.localFrame_repr_eq_repr hy] + simp [aux, Basis.localFrame_repr_eq_repr hy] simp only [aux] -- step 2: `s` read in trivialization `e` is `C^k` @@ -307,14 +307,9 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C -- lemma localFrame_repr is smooth, localFrame is smooth => scalar product is -- does this already exist? if not, missing API! sorry - let rhs₀ (i) := fun x' ↦ (localFrame_repr e b i) s x' • localFrame e b i x' - let rhs := fun x' ↦ ∑ i, rhs₀ i x' - have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k - (fun x ↦ TotalSpace.mk' F x (rhs x)) t := by - unfold rhs - -- TODO: add a dependent function version of contMDiffOn_finsum, for sections of a vector bundle - -- have aux := contMDiffOn_finsum (I' := I) (I := I.prod 𝓘(𝕜, F)) (f := fun i x ↦ rhs₀ i x) - sorry + let rhs := fun x' ↦ ∑ i, (localFrame_repr e b i) s x' • localFrame e b i x' + have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := + contMDiffOn_finsum_section fun i ↦ inner i apply almost.congr intro y hy congr diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 70b089444ae531..444acc0bc825f0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -31,6 +31,145 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `V` vector bundle [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] +-- Binary and finite sums and scalar products of smooth sections are smooth +-- XXX: also add sub, neg, nsmul and zsmul lemma (re-using proofs later in this file) +section operations + +-- Let V be a vector bundle +variable [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] + +variable {I F n V} + +variable {f : M → 𝕜} {a : 𝕜} {s t : Π x : M, V x} {u : Set M} {x₀ : M} + +lemma contMDiffWithinAt_add_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (ht : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by + rw [contMDiffWithinAt_section] at hs ht ⊢ + set e := trivializationAt F V x₀ + refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) + · intro x hx + apply (e.linear 𝕜 hx).1 + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).1 + +lemma contMDiffAt_add_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by + rw [contMDiffAt_section] at hs ht ⊢ + set e := trivializationAt F V x₀ + refine (hs.add ht).congr_of_eventuallyEq ?_ + refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ + intro x hx + apply (e.linear 𝕜 hx).1 + +lemma contMDiffOn_add_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) + (ht : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_add_section (hs x₀ hx₀) (ht x₀ hx₀) + +lemma contMDiff_add_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) + (ht : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := + fun x₀ ↦ contMDiffAt_add_section (hs x₀) (ht x₀) + +lemma contMDiffWithinAt_smul_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by + rw [contMDiffWithinAt_section] at hs ⊢ + set e := trivializationAt F V x₀ + refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) + · intro x hx + apply (e.linear 𝕜 hx).2 + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 + +lemma contMDiffAt_smul_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (hf : ContMDiffAt I 𝓘(𝕜) n f x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by + rw [contMDiffAt_section] at hs ⊢ + set e := trivializationAt F V x₀ + refine (hf.smul hs).congr_of_eventuallyEq ?_ + refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ + intro x hx + apply (e.linear 𝕜 hx).2 + +lemma contMDiffOn_smul_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) + (hf : ContMDiffOn I 𝓘(𝕜) n f u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_smul_section (hs x₀ hx₀) (hf x₀ hx₀) + +lemma contMDiff_smul_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) + (hf : ContMDiff I 𝓘(𝕜) n f) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) := + fun x₀ ↦ contMDiffAt_smul_section (hs x₀) (hf x₀) + +lemma contMDiffWithinAt_smul_const_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := + contMDiffWithinAt_smul_section hs contMDiffWithinAt_const + +lemma contMDiffAt_smul_const_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := + contMDiffAt_smul_section hs contMDiffAt_const + +lemma contMDiffOn_smul_const_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u := + contMDiffOn_smul_section hs contMDiffOn_const + +lemma contMDiff_smul_const_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) := + fun x₀ ↦ contMDiffAt_smul_const_section (hs x₀) + +lemma contMDiffWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} + (hs : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n + (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by + classical + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + -- TODO: x₀ ∈ u should not be required -> add contMDiffWithinAt_zeroSection! + apply ContMDiff.contMDiffOn + · apply contMDiff_zeroSection + · sorry -- x₀ ∈ u... + | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h + +lemma contMDiffAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} {x₀ : M} + (hs : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by + classical + induction s using Finset.induction_on with + | empty => simpa using contMDiff_zeroSection .. + | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h + +lemma contMDiffOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} + (hs : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_finsum_section fun i ↦ hs i x₀ hx₀ + +lemma contMDiff_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} + (hs : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := + fun x₀ ↦ contMDiffAt_finsum_section fun i ↦ (hs i) x₀ + +end operations + /-- Bundled `n` times continuously differentiable sections of a vector bundle. Denoted as `Cₛ^n⟮I; F, V⟯` within the `Manifold` namespace. -/ structure ContMDiffSection where @@ -74,17 +213,8 @@ theorem ext (h : ∀ x, s x = t x) : s = t := DFunLike.ext _ _ h section variable [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] -instance instAdd : Add Cₛ^n⟮I; F, V⟯ := by - refine ⟨fun s t => ⟨s + t, ?_⟩⟩ - intro x₀ - have hs := s.contMDiff x₀ - have ht := t.contMDiff x₀ - rw [contMDiffAt_section] at hs ht ⊢ - set e := trivializationAt F V x₀ - refine (hs.add ht).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).1 +instance instAdd : Add Cₛ^n⟮I; F, V⟯ := + ⟨fun s t ↦ ⟨s + t, contMDiff_add_section s.contMDiff t.contMDiff⟩⟩ @[simp] theorem coe_add (s t : Cₛ^n⟮I; F, V⟯) : ⇑(s + t) = ⇑s + t := @@ -154,16 +284,8 @@ theorem coe_zsmul (s : Cₛ^n⟮I; F, V⟯) (z : ℤ) : ⇑(z • s : Cₛ^n⟮I instance instAddCommGroup : AddCommGroup Cₛ^n⟮I; F, V⟯ := coe_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub coe_nsmul coe_zsmul -instance instSMul : SMul 𝕜 Cₛ^n⟮I; F, V⟯ := by - refine ⟨fun c s => ⟨c • ⇑s, ?_⟩⟩ - intro x₀ - have hs := s.contMDiff x₀ - rw [contMDiffAt_section] at hs ⊢ - set e := trivializationAt F V x₀ - refine ((contMDiffAt_const (c := c)).smul hs).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).2 +instance instSMul : SMul 𝕜 Cₛ^n⟮I; F, V⟯ := + ⟨fun c s ↦ ⟨c • ⇑s, contMDiff_smul_const_section s.contMDiff⟩⟩ @[simp] theorem coe_smul (r : 𝕜) (s : Cₛ^n⟮I; F, V⟯) : ⇑(r • s : Cₛ^n⟮I; F, V⟯) = r • ⇑s := From c2d5e5d8cf9682ca307af5373606b91e6ff679e4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 13:06:36 +0200 Subject: [PATCH 094/601] chore: also add contMDiffFoo_{sub,neg}_section proofs --- .../Manifold/VectorBundle/SmoothSection.lean | 81 ++++++++++++++----- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 444acc0bc825f0..e0e14bc4eae012 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -32,7 +32,7 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] -- Binary and finite sums and scalar products of smooth sections are smooth --- XXX: also add sub, neg, nsmul and zsmul lemma (re-using proofs later in this file) +-- XXX: also add nsmul and zsmul lemmas (re-using proofs later in this file) section operations -- Let V be a vector bundle @@ -79,6 +79,60 @@ lemma contMDiff_add_section ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := fun x₀ ↦ contMDiffAt_add_section (hs x₀) (ht x₀) +lemma contMDiffWithinAt_neg_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (- s x)) u x₀ := by + rw [contMDiffWithinAt_section] at hs ⊢ + set e := trivializationAt F V x₀ + refine hs.neg.congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) + · intro x hx + apply (e.linear 𝕜 hx).map_neg + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).map_neg + +lemma contMDiffAt_neg_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (- s x)) x₀ := + contMDiffWithinAt_neg_section hs + +lemma contMDiffOn_neg_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (-s x)) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_neg_section (hs x₀ hx₀) + +lemma contMDiff_neg_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (-s x)) := + fun x₀ ↦ contMDiffAt_neg_section (hs x₀) + +lemma contMDiffWithinAt_sub_section + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (ht : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u x₀ := by + rw [sub_eq_add_neg] + apply contMDiffWithinAt_add_section hs <| contMDiffWithinAt_neg_section ht + +lemma contMDiffAt_sub_section + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) x₀ := by + rw [sub_eq_add_neg] + apply contMDiffAt_add_section hs <| contMDiffAt_neg_section ht + +lemma contMDiffOn_sub_section + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) + (ht : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u := + fun x₀ hx₀ ↦ contMDiffWithinAt_sub_section (hs x₀ hx₀) (ht x₀ hx₀) + +lemma contMDiff_sub_section + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) + (ht : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) := + fun x₀ ↦ contMDiffAt_sub_section (hs x₀) (ht x₀) + lemma contMDiffWithinAt_smul_section (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) : @@ -220,17 +274,8 @@ instance instAdd : Add Cₛ^n⟮I; F, V⟯ := theorem coe_add (s t : Cₛ^n⟮I; F, V⟯) : ⇑(s + t) = ⇑s + t := rfl -instance instSub : Sub Cₛ^n⟮I; F, V⟯ := by - refine ⟨fun s t => ⟨s - t, ?_⟩⟩ - intro x₀ - have hs := s.contMDiff x₀ - have ht := t.contMDiff x₀ - rw [contMDiffAt_section] at hs ht ⊢ - set e := trivializationAt F V x₀ - refine (hs.sub ht).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).map_sub +instance instSub : Sub Cₛ^n⟮I; F, V⟯ := + ⟨fun s t ↦ ⟨s - t, contMDiff_sub_section s.contMDiff t.contMDiff⟩⟩ @[simp] theorem coe_sub (s t : Cₛ^n⟮I; F, V⟯) : ⇑(s - t) = s - t := @@ -246,16 +291,8 @@ instance inhabited : Inhabited Cₛ^n⟮I; F, V⟯ := theorem coe_zero : ⇑(0 : Cₛ^n⟮I; F, V⟯) = 0 := rfl -instance instNeg : Neg Cₛ^n⟮I; F, V⟯ := by - refine ⟨fun s => ⟨-s, ?_⟩⟩ - intro x₀ - have hs := s.contMDiff x₀ - rw [contMDiffAt_section] at hs ⊢ - set e := trivializationAt F V x₀ - refine hs.neg.congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).map_neg +instance instNeg : Neg Cₛ^n⟮I; F, V⟯ := + ⟨fun s ↦ ⟨-s, contMDiff_neg_section s.contMDiff⟩⟩ @[simp] theorem coe_neg (s : Cₛ^n⟮I; F, V⟯) : ⇑(-s : Cₛ^n⟮I; F, V⟯) = -s := From 25e50e51230f473649b7967771ed89790739cd99 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 13:18:10 +0200 Subject: [PATCH 095/601] Squash one more smoothness sorry in LocalFrame --- .../Manifold/VectorBundle/LocalFrame.lean | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 82b4fe8b4fd911..43c35dc54208e0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -293,6 +293,7 @@ lemma contMDiffAt_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace -- needs two missing API lemmas, see below sorry +omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -300,21 +301,19 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := by - refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun i ↦ ?_⟩ - - have inner (i) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ - TotalSpace.mk' F x ((localFrame_repr e b i) s x • localFrame e b i x)) t := by - -- lemma localFrame_repr is smooth, localFrame is smooth => scalar product is - -- does this already exist? if not, missing API! - sorry + refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ + have this (i) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ + TotalSpace.mk' F x ((localFrame_repr e b i) s x • localFrame e b i x)) t := + contMDiffOn_smul_section ((contMDiffOn_localFrame_baseSet k e b i).mono ht') (hi i) let rhs := fun x' ↦ ∑ i, (localFrame_repr e b i) s x' • localFrame e b i x' have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := - contMDiffOn_finsum_section fun i ↦ inner i + contMDiffOn_finsum_section fun i ↦ this i apply almost.congr intro y hy congr exact localFrame_repr_sum_eq s (ht' hy) +omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] From 036bec1284a9d65585a6df94331879cccfd1704e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 13:45:05 +0200 Subject: [PATCH 096/601] chore(LocalFrame): rejigger namespaces Move smoothness results out of the Basis namespace; use dot notation a bit more to compensate --- .../Manifold/VectorBundle/LocalFrame.lean | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 43c35dc54208e0..13703f9f163601 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -71,17 +71,18 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] -- `V` vector bundle -namespace Basis +section variable {ι : Type*} +namespace Basis + noncomputable def localFrame_toBasis_at (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := b.map (e.linearEquivAt (R := 𝕜) x hx).symm - open scoped Classical in -- If x is outside of `e.baseSet`, this returns the junk value 0. noncomputable def localFrame @@ -156,18 +157,17 @@ noncomputable def localFrame_repr by_cases hx : x ∈ e.baseSet <;> simp [hx] variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} + [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} variable (e b) in @[simp] -lemma localFrame_repr_apply_of_notMem_baseSet {x : M} - (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e i s x = 0 := by +lemma localFrame_repr_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : + b.localFrame_repr e i s x = 0 := by simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim variable (e b) in @[simp] -lemma localFrame_repr_apply_of_mem_baseSet {x : M} - (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : +lemma localFrame_repr_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by simp [localFrame_repr, hx] @@ -186,10 +186,6 @@ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_repr_sum_eq s h, e.open_baseSet, hxe⟩ -variable {ι : Type*} {x : M} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] - /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma localFrame_repr_congr (b : Basis ι 𝕜 F) {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : @@ -224,6 +220,11 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] +end Basis + +variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} + [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} + omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame near `x` induced by `e` and `b` -/ @@ -271,7 +272,7 @@ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := - fun _ hx ↦ (b.contMDiffAt_localFrame_repr (ht' hx) + fun _ hx ↦ (contMDiffAt_localFrame_repr (ht' hx) b (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in @@ -289,7 +290,7 @@ lemma contMDiffAt_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace {s : Π x : M, V x} {k : WithTop ℕ∞} {x' : M} (hx : x' ∈ e.baseSet) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ ∀ i, ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x' := by - refine ⟨fun h i ↦ b.contMDiffAt_localFrame_repr hx h i, fun i ↦ ?_⟩ + refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun i ↦ ?_⟩ -- needs two missing API lemmas, see below sorry @@ -303,15 +304,15 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := by refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ have this (i) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ - TotalSpace.mk' F x ((localFrame_repr e b i) s x • localFrame e b i x)) t := - contMDiffOn_smul_section ((contMDiffOn_localFrame_baseSet k e b i).mono ht') (hi i) - let rhs := fun x' ↦ ∑ i, (localFrame_repr e b i) s x' • localFrame e b i x' + TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) t := + contMDiffOn_smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') (hi i) + let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := contMDiffOn_finsum_section fun i ↦ this i apply almost.congr intro y hy congr - exact localFrame_repr_sum_eq s (ht' hy) + exact b.localFrame_repr_sum_eq s (ht' hy) omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its @@ -320,9 +321,9 @@ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by - rw [b.contMDiffOn_iff_localFrame_repr e.open_baseSet (subset_refl _)] + rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] -end Basis +end -- local extension of a vector field in a trivialisation's base set section extendLocally @@ -407,7 +408,7 @@ lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are -- constant, hence smoothness follows. - rw [b.contMDiffOn_baseSet_iff_localFrame_repr] + rw [contMDiffOn_baseSet_iff_localFrame_repr b] intro i apply (contMDiffOn_const (c := (b.localFrame_repr e i) (localExtensionOn b e x v) x)).congr intro y hy From ba1e56c0580934bc59ad620381ea3262cea83ec3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 13:46:01 +0200 Subject: [PATCH 097/601] chore(LocalFrame): fix last smoothness sorry --- .../Manifold/VectorBundle/LocalFrame.lean | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 13703f9f163601..9e4b3ce09274a6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -108,6 +108,14 @@ lemma contMDiffOn_localFrame_baseSet intro y hy simp [localFrame, hy, localFrame_toBasis_at] +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +lemma _root_.contMDiffAt_localFrame_of_mem + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) {x : M} (hx : x ∈ e.baseSet) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n + (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) x := + (contMDiffOn_localFrame_baseSet n e b i).contMDiffAt <| e.open_baseSet.mem_nhds hx + @[simp] lemma localFrame_apply_of_mem_baseSet (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) @@ -284,15 +292,23 @@ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSp ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ +omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` at `x ∈ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma contMDiffAt_iff_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} {x' : M} (hx : x' ∈ e.baseSet) : +lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {x' : M} (hx : x' ∈ e.baseSet) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ ∀ i, ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x' := by - refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun i ↦ ?_⟩ - -- needs two missing API lemmas, see below - sorry + refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ + have this (i) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ + TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + contMDiffAt_smul_section (contMDiffAt_localFrame_of_mem k e b i hx) (hi i) + have almost : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k + (fun x ↦ TotalSpace.mk' F x (∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + contMDiffAt_finsum_section fun i ↦ this i + apply almost.congr_of_eventuallyEq ?_ + obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) + exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its From b2393cd2725639fea2032e0e0116f5fabb060089 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 14:05:40 +0200 Subject: [PATCH 098/601] chore: add contMDiffWithinAt_zeroSection --- Mathlib/Geometry/Manifold/VectorBundle/Basic.lean | 4 ++++ Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 63e9fbe329175e..7c9038266a2eb7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -276,6 +276,10 @@ theorem contMDiff_zeroSection : ContMDiff IB (IB.prod 𝓘(𝕜, F)) n (zeroSect (mem_baseSet_trivializationAt F E x)] with y hy using congr_arg Prod.snd <| (trivializationAt F E x).zeroSection 𝕜 hy +theorem contMDiffWithinAt_zeroSection {t : Set B} {x : B} : + ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (zeroSection F E) t x := + (contMDiff_zeroSection _ _ x).contMDiffWithinAt + end Bundle end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index e0e14bc4eae012..b3fd519e10d827 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -197,11 +197,7 @@ lemma contMDiffWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → classical induction s using Finset.induction_on with | empty => - simp only [Finset.sum_empty] - -- TODO: x₀ ∈ u should not be required -> add contMDiffWithinAt_zeroSection! - apply ContMDiff.contMDiffOn - · apply contMDiff_zeroSection - · sorry -- x₀ ∈ u... + simpa only [Finset.sum_empty] using contMDiffWithinAt_zeroSection .. | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h lemma contMDiffAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} {x₀ : M} From 4328cce9ccbefea3c0866055826c8f47d89f3015 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 14:07:07 +0200 Subject: [PATCH 099/601] API for MDifferentiableAt for sections of vector bundles --- .../Manifold/MFDeriv/SpecificFunctions.lean | 14 ++ .../VectorBundle/MDifferentiable.lean | 201 ++++++++++++++++++ 2 files changed, 215 insertions(+) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 4822ae40b97223..0b92730d1a9304 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -580,14 +580,28 @@ section Group variable {z : M} {f g : M → E'} {f' g' : TangentSpace I z →L[𝕜] E'} +theorem HasMFDerivWithinAt.add {s : Set M} (hf : HasMFDerivWithinAt I 𝓘(𝕜, E') f s z f') + (hg : HasMFDerivWithinAt I 𝓘(𝕜, E') g s z g') : + HasMFDerivWithinAt I 𝓘(𝕜, E') (f + g) s z (f' + g') := + ⟨hf.1.add hg.1, hf.2.add hg.2⟩ + theorem HasMFDerivAt.add (hf : HasMFDerivAt I 𝓘(𝕜, E') f z f') (hg : HasMFDerivAt I 𝓘(𝕜, E') g z g') : HasMFDerivAt I 𝓘(𝕜, E') (f + g) z (f' + g') := ⟨hf.1.add hg.1, hf.2.add hg.2⟩ +theorem MDifferentiableWithinAt.add {s : Set M} (hf : MDifferentiableWithinAt I 𝓘(𝕜, E') f s z) + (hg : MDifferentiableWithinAt I 𝓘(𝕜, E') g s z) : + MDifferentiableWithinAt I 𝓘(𝕜, E') (f + g) s z := + (hf.hasMFDerivWithinAt.add hg.hasMFDerivWithinAt).mdifferentiableWithinAt + theorem MDifferentiableAt.add (hf : MDifferentiableAt I 𝓘(𝕜, E') f z) (hg : MDifferentiableAt I 𝓘(𝕜, E') g z) : MDifferentiableAt I 𝓘(𝕜, E') (f + g) z := (hf.hasMFDerivAt.add hg.hasMFDerivAt).mdifferentiableAt +theorem MDifferentiableOn.add {s : Set M} (hf : MDifferentiableOn I 𝓘(𝕜, E') f s) + (hg : MDifferentiableOn I 𝓘(𝕜, E') g s) : MDifferentiableOn I 𝓘(𝕜, E') (f + g) s := + fun x hx => (hf x hx).add (hg x hx) + theorem MDifferentiable.add (hf : MDifferentiable I 𝓘(𝕜, E') f) (hg : MDifferentiable I 𝓘(𝕜, E') g) : MDifferentiable I 𝓘(𝕜, E') (f + g) := fun x => (hf x).add (hg x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 051de3c416b83c..8249c8b43fd606 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ import Mathlib.Geometry.Manifold.VectorBundle.Basic +import Mathlib.Geometry.Manifold.Algebra.Monoid import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions @@ -62,6 +63,22 @@ theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f +/-- Characterization of differentiable sections of a vector bundle at a point within a set +in term of the preferred trivialization at that point. -/ +theorem mdifferentiableWithinAt_section (s : Π b, E b) {u : Set B} {b₀ : B} : + MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) u b₀ ↔ + MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) u b₀ := by + rw [mdifferentiableWithinAt_totalSpace] + change MDifferentiableWithinAt _ _ id _ _ ∧ _ ↔ _ + simp [mdifferentiableWithinAt_id] + +/-- Characterization of differentiable sections of a vector bundle at a point within a set +in term of the preferred trivialization at that point. -/ +theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : + MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) b₀ ↔ + MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by + simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ + variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] @@ -135,8 +152,192 @@ theorem Trivialization.mdifferentiableAt_totalSpace_iff apply and_congr_right intro hf rw [mdifferentiableAt_change_triv IB hex₀ (FiberBundle.mem_baseSet_trivializationAt' _) hf] + +/-- Characterization of differentiable sections a vector bundle in terms +of any trivialization. Version at a point within at set. -/ +theorem Trivialization.mdifferentiableWithinAt_section_iff + (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] + (s : Π b : B, E b) {u : Set B} {b₀ : B} + (hex₀ : b₀ ∈ e.baseSet) : + MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) u b₀ ↔ + MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) u b₀ := by + rw [e.mdifferentiableWithinAt_totalSpace_iff IB] + · change MDifferentiableWithinAt IB IB id u b₀ ∧ _ ↔ _ + simp [mdifferentiableWithinAt_id] + simp [hex₀] + +/-- Characterization of differentiable functions into a vector bundle in terms +of any trivialization. Version at a point. -/ +theorem Trivialization.mdifferentiableAt_section_iff + (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] + (s : Π b : B, E b) {b₀ : B} + (hex₀ : b₀ ∈ e.baseSet) : + MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) b₀ ↔ + MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) b₀ := by + simpa [← mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_section_iff IB s hex₀ end +section contMDiff_addsmulfinsum_section + +variable {𝕜 B B' F M : Type*} {E : B → Type*} + +variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup F] [NormedSpace 𝕜 F] + [TopologicalSpace (TotalSpace F E)] [∀ x, TopologicalSpace (E x)] {EB : Type*} + [NormedAddCommGroup EB] [NormedSpace 𝕜 EB] {HB : Type*} [TopologicalSpace HB] + (I : ModelWithCorners 𝕜 EB HB) -- (E' : B → Type*) [∀ x, Zero (E' x)] {EM : Type*} + -- [NormedAddCommGroup EM] [NormedSpace 𝕜 EM] {HM : Type*} [TopologicalSpace HM] + -- {IM : ModelWithCorners 𝕜 EM HM} [TopologicalSpace M] [ChartedSpace HM M] + -- {n : ℕ∞} + +variable [TopologicalSpace B] [ChartedSpace HB B] [FiberBundle F E] + +variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] + [VectorBundle 𝕜 F E] + +-- Proofs taken from SmoothSection: TODO golf those with these lemmas! +-- XXX: also add sub, neg, nsmul, zsmul lemmas? + +variable {I V} + +variable {f : B → 𝕜} {a : 𝕜} {s t : Π x : B, E x} {u : Set B} {x₀ : B} + +omit [ContMDiffVectorBundle 1 F E I] in +lemma mdifferentiableWithinAt_add_section + (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (ht : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by + rw [mdifferentiableWithinAt_section] at hs ht ⊢ + set e := trivializationAt F E x₀ + + refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) + · intro x hx + apply (e.linear 𝕜 hx).1 + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).1 + +omit [ContMDiffVectorBundle 1 F E I] in +lemma mdifferentiableAt_add_section + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (ht : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by + rw [mdifferentiableAt_section] at hs ht ⊢ + set e := trivializationAt F E x₀ + refine (hs.add ht).congr_of_eventuallyEq ?_ + refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) ?_ + intro x hx + apply (e.linear 𝕜 hx).1 + +lemma mdifferentiableOn_add_section + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) + (ht : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u := + fun x₀ hx₀ ↦ mdifferentiableWithinAt_add_section (hs x₀ hx₀) (ht x₀ hx₀) + +lemma mdifferentiable_add_section + (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) + (ht : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x))) : + MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := + fun x₀ ↦ mdifferentiableAt_add_section (hs x₀) (ht x₀) + +lemma mdifferentiableWithinAt_smul_section + (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (hf : MDifferentiableWithinAt I 𝓘(𝕜) f u x₀) : + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by + rw [mdifferentiableWithinAt_section] at hs ⊢ + set e := trivializationAt F E x₀ + refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) + · intro x hx + apply (e.linear 𝕜 hx).2 + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 + +lemma mdifferentiableAt_smul_section + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (hf : MDifferentiableAt I 𝓘(𝕜) f x₀) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by + rw [mdifferentiableAt_section] at hs ⊢ + set e := trivializationAt F E x₀ + refine (hf.smul hs).congr_of_eventuallyEq ?_ + refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) ?_ + intro x hx + apply (e.linear 𝕜 hx).2 + +lemma mdifferentiableOn_smul_section + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) + (hf : MDifferentiableOn I 𝓘(𝕜) f u) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := + fun x₀ hx₀ ↦ mdifferentiableWithinAt_smul_section (hs x₀ hx₀) (hf x₀ hx₀) + +lemma mdifferentiable_smul_section + (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) + (hf : MDifferentiable I 𝓘(𝕜) f) : + MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) := + fun x₀ ↦ mdifferentiableAt_smul_section (hs x₀) (hf x₀) + +lemma mdifferentiableWithinAt_smul_const_section + (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := + mdifferentiableWithinAt_smul_section hs mdifferentiableWithinAt_const + +lemma mdifferentiableAt_smul_const_section + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := + mdifferentiableAt_smul_section hs mdifferentiableAt_const + +lemma mdifferentiableOn_smul_const_section + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u := + mdifferentiableOn_smul_section hs mdifferentiableOn_const + +lemma mdifferentiable_smul_const_section + (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : + MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) := + fun x₀ ↦ mdifferentiableAt_smul_const_section (hs x₀) + +lemma mdifferentiableWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} + (hs : ∀ i, MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) + (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) + (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by + classical + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + -- TODO: x₀ ∈ u should not be required -> add mdifferentiableWithinAt_zeroSection! + apply MDifferentiable.mdifferentiableOn + · apply ContMDiff.mdifferentiable _ le_rfl + apply contMDiff_zeroSection + · sorry -- x₀ ∈ u... + | insert i s hi h => + simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h + +lemma mdifferentiableAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} {x₀ : B} + (hs : ∀ i, MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by + classical + induction s using Finset.induction_on with + | empty => + apply ContMDiff.mdifferentiable _ le_rfl + apply contMDiff_zeroSection + | insert i s hi h => + simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h + +lemma mdifferentiableOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} + (hs : ∀ i, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := + fun x₀ hx₀ ↦ mdifferentiableWithinAt_finsum_section fun i ↦ hs i x₀ hx₀ + +lemma mdifferentiable_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} + (hs : ∀ i, MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x))) : + MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := + fun x₀ ↦ mdifferentiableAt_finsum_section fun i ↦ (hs i) x₀ + +end contMDiff_addsmulfinsum_section + section /- Declare two manifolds `B₁` and `B₂` (with models `IB₁ : HB₁ → EB₁` and `IB₂ : HB₂ → EB₂`), From 732837d5d5214459dc6c45793a4f4af2ff55edfb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 14:26:34 +0200 Subject: [PATCH 100/601] chore: clean-up MDifferentiable additions --- .../VectorBundle/MDifferentiable.lean | 73 ++++++------------- 1 file changed, 23 insertions(+), 50 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 8249c8b43fd606..d01638d9f9a68f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -177,7 +177,7 @@ theorem Trivialization.mdifferentiableAt_section_iff simpa [← mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_section_iff IB s hex₀ end -section contMDiff_addsmulfinsum_section +section operations variable {𝕜 B B' F M : Type*} {E : B → Type*} @@ -191,11 +191,7 @@ variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup F] [NormedSpace 𝕜 variable [TopologicalSpace B] [ChartedSpace HB B] [FiberBundle F E] -variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] - [VectorBundle 𝕜 F E] - --- Proofs taken from SmoothSection: TODO golf those with these lemmas! --- XXX: also add sub, neg, nsmul, zsmul lemmas? +variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] variable {I V} @@ -208,7 +204,6 @@ lemma mdifferentiableWithinAt_add_section MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by rw [mdifferentiableWithinAt_section] at hs ht ⊢ set e := trivializationAt F E x₀ - refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ · apply eventually_of_mem (U := e.baseSet) · exact mem_nhdsWithin_of_mem_nhds <| @@ -222,12 +217,8 @@ lemma mdifferentiableAt_add_section (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) (ht : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by - rw [mdifferentiableAt_section] at hs ht ⊢ - set e := trivializationAt F E x₀ - refine (hs.add ht).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).1 + rw [← mdifferentiableWithinAt_univ] at hs ht ⊢ + apply mdifferentiableWithinAt_add_section hs ht lemma mdifferentiableOn_add_section (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) @@ -242,8 +233,8 @@ lemma mdifferentiable_add_section fun x₀ ↦ mdifferentiableAt_add_section (hs x₀) (ht x₀) lemma mdifferentiableWithinAt_smul_section - (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (hf : MDifferentiableWithinAt I 𝓘(𝕜) f u x₀) : + (hf : MDifferentiableWithinAt I 𝓘(𝕜) f u x₀) + (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by rw [mdifferentiableWithinAt_section] at hs ⊢ set e := trivializationAt F E x₀ @@ -255,43 +246,36 @@ lemma mdifferentiableWithinAt_smul_section apply (e.linear 𝕜 hx).2 · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 -lemma mdifferentiableAt_smul_section - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (hf : MDifferentiableAt I 𝓘(𝕜) f x₀) : +lemma mdifferentiableAt_smul_section (hf : MDifferentiableAt I 𝓘(𝕜) f x₀) + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by - rw [mdifferentiableAt_section] at hs ⊢ - set e := trivializationAt F E x₀ - refine (hf.smul hs).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).2 + rw [← mdifferentiableWithinAt_univ] at hs ⊢ + exact mdifferentiableWithinAt_smul_section hf hs -lemma mdifferentiableOn_smul_section - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) - (hf : MDifferentiableOn I 𝓘(𝕜) f u) : +lemma mdifferentiableOn_smul_section (hf : MDifferentiableOn I 𝓘(𝕜) f u) + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := - fun x₀ hx₀ ↦ mdifferentiableWithinAt_smul_section (hs x₀ hx₀) (hf x₀ hx₀) + fun x₀ hx₀ ↦ mdifferentiableWithinAt_smul_section (hf x₀ hx₀) (hs x₀ hx₀) -lemma mdifferentiable_smul_section - (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) - (hf : MDifferentiable I 𝓘(𝕜) f) : +lemma mdifferentiable_smul_section (hf : MDifferentiable I 𝓘(𝕜) f) + (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) := - fun x₀ ↦ mdifferentiableAt_smul_section (hs x₀) (hf x₀) + fun x₀ ↦ mdifferentiableAt_smul_section (hf x₀) (hs x₀) lemma mdifferentiableWithinAt_smul_const_section (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := - mdifferentiableWithinAt_smul_section hs mdifferentiableWithinAt_const + mdifferentiableWithinAt_smul_section mdifferentiableWithinAt_const hs lemma mdifferentiableAt_smul_const_section (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := - mdifferentiableAt_smul_section hs mdifferentiableAt_const + mdifferentiableAt_smul_section mdifferentiableAt_const hs lemma mdifferentiableOn_smul_const_section (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u := - mdifferentiableOn_smul_section hs mdifferentiableOn_const + mdifferentiableOn_smul_section mdifferentiableOn_const hs lemma mdifferentiable_smul_const_section (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : @@ -305,26 +289,15 @@ lemma mdifferentiableWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by classical induction s using Finset.induction_on with - | empty => - simp only [Finset.sum_empty] - -- TODO: x₀ ∈ u should not be required -> add mdifferentiableWithinAt_zeroSection! - apply MDifferentiable.mdifferentiableOn - · apply ContMDiff.mdifferentiable _ le_rfl - apply contMDiff_zeroSection - · sorry -- x₀ ∈ u... + | empty => simpa using (contMDiffWithinAt_zeroSection 𝕜 E).mdifferentiableWithinAt (n := 1) le_rfl | insert i s hi h => simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h lemma mdifferentiableAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} {x₀ : B} (hs : ∀ i, MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by - classical - induction s using Finset.induction_on with - | empty => - apply ContMDiff.mdifferentiable _ le_rfl - apply contMDiff_zeroSection - | insert i s hi h => - simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h + simp_rw [← mdifferentiableWithinAt_univ] at hs ⊢ + exact mdifferentiableWithinAt_finsum_section hs lemma mdifferentiableOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} (hs : ∀ i, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u) : @@ -336,7 +309,7 @@ lemma mdifferentiable_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := fun x₀ ↦ mdifferentiableAt_finsum_section fun i ↦ (hs i) x₀ -end contMDiff_addsmulfinsum_section +end operations section From 7294adaec993a6cffb33bf60d9b3f9c85616fe1e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 14:30:37 +0200 Subject: [PATCH 101/601] chore: same golfs to SmoothSection Prove the ContMDiffAt versions in terms of their ContMDiffWithinAt equivalent. And put hf arguments before hs arguments in _smul_section lemmas --- .../Manifold/VectorBundle/SmoothSection.lean | 57 +++++++------------ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index b3fd519e10d827..237038167a2bf2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -60,12 +60,8 @@ lemma contMDiffAt_add_section (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by - rw [contMDiffAt_section] at hs ht ⊢ - set e := trivializationAt F V x₀ - refine (hs.add ht).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).1 + rw [← contMDiffWithinAt_univ] at hs ⊢ + exact contMDiffWithinAt_add_section hs ht lemma contMDiffOn_add_section (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) @@ -94,8 +90,9 @@ lemma contMDiffWithinAt_neg_section lemma contMDiffAt_neg_section (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (- s x)) x₀ := - contMDiffWithinAt_neg_section hs + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (- s x)) x₀ := by + rw [← contMDiffWithinAt_univ] at hs ⊢ + exact contMDiffWithinAt_neg_section hs lemma contMDiffOn_neg_section (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : @@ -133,9 +130,8 @@ lemma contMDiff_sub_section ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) := fun x₀ ↦ contMDiffAt_sub_section (hs x₀) (ht x₀) -lemma contMDiffWithinAt_smul_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) : +lemma contMDiffWithinAt_smul_section (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) + (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by rw [contMDiffWithinAt_section] at hs ⊢ set e := trivializationAt F V x₀ @@ -147,43 +143,36 @@ lemma contMDiffWithinAt_smul_section apply (e.linear 𝕜 hx).2 · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 -lemma contMDiffAt_smul_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (hf : ContMDiffAt I 𝓘(𝕜) n f x₀) : +lemma contMDiffAt_smul_section (hf : ContMDiffAt I 𝓘(𝕜) n f x₀) + (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by - rw [contMDiffAt_section] at hs ⊢ - set e := trivializationAt F V x₀ - refine (hf.smul hs).congr_of_eventuallyEq ?_ - refine eventually_of_mem (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) ?_ - intro x hx - apply (e.linear 𝕜 hx).2 + rw [← contMDiffWithinAt_univ] at hs ⊢ + exact contMDiffWithinAt_smul_section hf hs -lemma contMDiffOn_smul_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) - (hf : ContMDiffOn I 𝓘(𝕜) n f u) : +lemma contMDiffOn_smul_section (hf : ContMDiffOn I 𝓘(𝕜) n f u) + (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := - fun x₀ hx₀ ↦ contMDiffWithinAt_smul_section (hs x₀ hx₀) (hf x₀ hx₀) + fun x₀ hx₀ ↦ contMDiffWithinAt_smul_section (hf x₀ hx₀) (hs x₀ hx₀) -lemma contMDiff_smul_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) - (hf : ContMDiff I 𝓘(𝕜) n f) : +lemma contMDiff_smul_section (hf : ContMDiff I 𝓘(𝕜) n f) + (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) := - fun x₀ ↦ contMDiffAt_smul_section (hs x₀) (hf x₀) + fun x₀ ↦ contMDiffAt_smul_section (hf x₀) (hs x₀) lemma contMDiffWithinAt_smul_const_section (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := - contMDiffWithinAt_smul_section hs contMDiffWithinAt_const + contMDiffWithinAt_smul_section contMDiffWithinAt_const hs lemma contMDiffAt_smul_const_section (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := - contMDiffAt_smul_section hs contMDiffAt_const + contMDiffAt_smul_section contMDiffAt_const hs lemma contMDiffOn_smul_const_section (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u := - contMDiffOn_smul_section hs contMDiffOn_const + contMDiffOn_smul_section contMDiffOn_const hs lemma contMDiff_smul_const_section (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : @@ -203,10 +192,8 @@ lemma contMDiffWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → lemma contMDiffAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} {x₀ : M} (hs : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by - classical - induction s using Finset.induction_on with - | empty => simpa using contMDiff_zeroSection .. - | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h + simp_rw [← contMDiffWithinAt_univ] at hs ⊢ + exact contMDiffWithinAt_finsum_section hs lemma contMDiffOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} (hs : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : From c364c4cd2a641d1ea79cdab64b4d55075c0147df Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 14:42:50 +0200 Subject: [PATCH 102/601] feat: add MDifferentiable{WithinAt,At,On,}_{neg,sub}_section --- .../Manifold/MFDeriv/SpecificFunctions.lean | 12 ++++ .../VectorBundle/MDifferentiable.lean | 58 ++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 0b92730d1a9304..8e120680fbe9b1 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -629,6 +629,10 @@ theorem const_smul_mfderiv (hf : MDifferentiableAt I 𝓘(𝕜, E') f z) (s : (s • mfderiv I 𝓘(𝕜, E') f z : TangentSpace I z →L[𝕜] E') := (hf.hasMFDerivAt.const_smul s).mfderiv +theorem HasMFDerivWithinAt.neg {s : Set M} (hf : HasMFDerivWithinAt I 𝓘(𝕜, E') f s z f') : + HasMFDerivWithinAt I 𝓘(𝕜, E') (-f) s z (-f') := + ⟨hf.1.neg, hf.2.neg⟩ + theorem HasMFDerivAt.neg (hf : HasMFDerivAt I 𝓘(𝕜, E') f z f') : HasMFDerivAt I 𝓘(𝕜, E') (-f) z (-f') := ⟨hf.1.neg, hf.2.neg⟩ @@ -636,10 +640,18 @@ theorem HasMFDerivAt.neg (hf : HasMFDerivAt I 𝓘(𝕜, E') f z f') : theorem hasMFDerivAt_neg : HasMFDerivAt I 𝓘(𝕜, E') (-f) z (-f') ↔ HasMFDerivAt I 𝓘(𝕜, E') f z f' := ⟨fun hf => by convert hf.neg <;> rw [neg_neg], fun hf => hf.neg⟩ +theorem MDifferentiableWithinAt.neg {s : Set M} (hf : MDifferentiableWithinAt I 𝓘(𝕜, E') f s z) : + MDifferentiableWithinAt I 𝓘(𝕜, E') (-f) s z := + (hf.hasMFDerivWithinAt.neg).mdifferentiableWithinAt + theorem MDifferentiableAt.neg (hf : MDifferentiableAt I 𝓘(𝕜, E') f z) : MDifferentiableAt I 𝓘(𝕜, E') (-f) z := hf.hasMFDerivAt.neg.mdifferentiableAt +theorem MDifferentiableOn.neg {s : Set M} (hf : MDifferentiableOn I 𝓘(𝕜, E') f s) : + MDifferentiableOn I 𝓘(𝕜, E') (-f) s := + fun x hx ↦ (hf x hx).neg + theorem mdifferentiableAt_neg : MDifferentiableAt I 𝓘(𝕜, E') (-f) z ↔ MDifferentiableAt I 𝓘(𝕜, E') f z := ⟨fun hf => by convert hf.neg; rw [neg_neg], fun hf => hf.neg⟩ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index d01638d9f9a68f..c58fdeff921388 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -191,7 +191,7 @@ variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup F] [NormedSpace 𝕜 variable [TopologicalSpace B] [ChartedSpace HB B] [FiberBundle F E] -variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] +variable [(x : B) → AddCommGroup (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] variable {I V} @@ -232,6 +232,62 @@ lemma mdifferentiable_add_section MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := fun x₀ ↦ mdifferentiableAt_add_section (hs x₀) (ht x₀) +lemma mdifferentiableWithinAt_neg_section + (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (- s x)) u x₀ := by + rw [mdifferentiableWithinAt_section] at hs ⊢ + set e := trivializationAt F E x₀ + sorry + -- refine hs.neg.congr_of_eventuallyEq ?_ ?_ + -- · apply eventually_of_mem (U := e.baseSet) + -- · exact mem_nhdsWithin_of_mem_nhds <| + -- (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) + -- · intro x hx + -- apply (e.linear 𝕜 hx).map_neg + -- · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).map_neg + +lemma mdifferentiableAt_neg_section + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (- s x)) x₀ := by + rw [← mdifferentiableWithinAt_univ] at hs ⊢ + exact mdifferentiableWithinAt_neg_section hs + +lemma mdifferentiableOn_neg_section + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (-s x)) u := + fun x₀ hx₀ ↦ mdifferentiableWithinAt_neg_section (hs x₀ hx₀) + +lemma mdifferentiable_neg_section + (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : + MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (-s x)) := + fun x₀ ↦ mdifferentiableAt_neg_section (hs x₀) + +lemma mdifferentiableWithinAt_sub_section + (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) + (ht : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u x₀ := by + rw [sub_eq_add_neg] + apply mdifferentiableWithinAt_add_section hs <| mdifferentiableWithinAt_neg_section ht + +lemma mdifferentiableAt_sub_section + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) + (ht : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) x₀ := by + rw [sub_eq_add_neg] + apply mdifferentiableAt_add_section hs <| mdifferentiableAt_neg_section ht + +lemma mDifferentiableOn_sub_section + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) + (ht : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u := + fun x₀ hx₀ ↦ mdifferentiableWithinAt_sub_section (hs x₀ hx₀) (ht x₀ hx₀) + +lemma mdifferentiable_sub_section + (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) + (ht : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x))) : + MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) := + fun x₀ ↦ mdifferentiableAt_sub_section (hs x₀) (ht x₀) + lemma mdifferentiableWithinAt_smul_section (hf : MDifferentiableWithinAt I 𝓘(𝕜) f u x₀) (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : From d41982b58a32626cffcc48dfb7019a2593823498 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 14:44:26 +0200 Subject: [PATCH 103/601] Complete .neg sorry --- .../Manifold/VectorBundle/MDifferentiable.lean | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index c58fdeff921388..74af5bbe7f5769 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -237,14 +237,13 @@ lemma mdifferentiableWithinAt_neg_section MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (- s x)) u x₀ := by rw [mdifferentiableWithinAt_section] at hs ⊢ set e := trivializationAt F E x₀ - sorry - -- refine hs.neg.congr_of_eventuallyEq ?_ ?_ - -- · apply eventually_of_mem (U := e.baseSet) - -- · exact mem_nhdsWithin_of_mem_nhds <| - -- (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F V x₀) - -- · intro x hx - -- apply (e.linear 𝕜 hx).map_neg - -- · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).map_neg + refine hs.neg.congr_of_eventuallyEq ?_ ?_ + · apply eventually_of_mem (U := e.baseSet) + · exact mem_nhdsWithin_of_mem_nhds <| + (e.open_baseSet.mem_nhds <| mem_baseSet_trivializationAt F E x₀) + · intro x hx + apply (e.linear 𝕜 hx).map_neg + · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).map_neg lemma mdifferentiableAt_neg_section (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : From fe1d3885ae6447de7902999a353fd1fbf5423cff Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 15:00:13 +0200 Subject: [PATCH 104/601] Use VectorBundle.MDifferentiable in Tensoriality --- .../Manifold/VectorBundle/Tensoriality.lean | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index df825ddb6f3f9e..b166b50cc9a535 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -6,6 +6,7 @@ Authors: Patrick Massot, Michael Rothgang import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.MFDeriv.Basic import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! # The tensoriality criterion @@ -84,25 +85,33 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDim | insert a s ha h => change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ simp [Finset.sum_insert ha, ← h] - erw [φ_add] - apply hσ a - sorry + exact φ_add _ _ (hσ a) (mdifferentiableAt_finsum_section hσ) have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) let c := Basis.localFrame_repr t b - rw [locality _ _ (b.localFrame_repr_spec x_mem σ), locality _ _ (b.localFrame_repr_spec x_mem σ'), - sum_phi, sum_phi] + have hs (i) : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (s i x)) x:= + (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl + have hc {σ : (x : M) → V x} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (i) : + MDifferentiableAt I 𝓘(ℝ, ℝ) ((c i) σ) x := by + sorry + have hφ {σ : (x : M) → V x} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) : + φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by + exact + locality hσ + (mdifferentiableAt_finsum_section fun i ↦ mdifferentiableAt_smul_section (hs i) (hc hσ i)) + (Basis.localFrame_repr_spec b x_mem σ) + rw [hφ hσ, hφ hσ', sum_phi, sum_phi] · change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x congr ext i - rw [φ_smul, φ_smul] - · congr - apply b.localFrame_repr_congr - assumption - all_goals sorry - all_goals sorry + rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i), + Basis.localFrame_repr_congr b hσσ'] + · exact fun i ↦ mdifferentiableAt_smul_section (hs i) (hc hσ' i) + · exact fun i ↦ mdifferentiableAt_smul_section (hs i) (hc hσ i) include I in omit [IsManifold I 1 M] [∀ (x : M), IsTopologicalAddGroup (V x)] From 5ad787c278f5c092a758d37143d9204a6a52d830 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 14:48:08 +0200 Subject: [PATCH 105/601] Fix the build --- Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 9e4b3ce09274a6..84efc64ccc6c6b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -302,7 +302,7 @@ lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ have this (i) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) x' := - contMDiffAt_smul_section (contMDiffAt_localFrame_of_mem k e b i hx) (hi i) + contMDiffAt_smul_section (hi i) (contMDiffAt_localFrame_of_mem k e b i hx) have almost : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := contMDiffAt_finsum_section fun i ↦ this i @@ -321,7 +321,7 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ have this (i) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) t := - contMDiffOn_smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') (hi i) + contMDiffOn_smul_section (hi i) ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := contMDiffOn_finsum_section fun i ↦ this i From 92f0c4ffd8164ea3dfd0f467109d990521c62323 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 15:05:11 +0200 Subject: [PATCH 106/601] WIP: MDifferentiableAt analogue of contMDiffAt_localFrame_repr --- .../Manifold/VectorBundle/LocalFrame.lean | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 84efc64ccc6c6b..ebc0f6973add21 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.Algebra.Monoid +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection /-! @@ -339,6 +340,120 @@ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] +-- TODO: start filling in all the details from here onwards! + +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +/-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame +near `x` induced by `e` and `b` -/ +lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) + {s : Π x : M, V x} + (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x) + (i : ι) : MDifferentiableAt I 𝓘(𝕜) (b.localFrame_repr e i s) x := by + -- This boils down to computing the frame coefficients in a local trivialisation. + classical + sorry /- + -- step 1: on e.baseSet, can compute the coefficient very well + let aux := fun x ↦ b.repr (e (s x)).2 i + -- Since e.baseSet is open, this is sufficient. + suffices ContMDiffAt I 𝓘(𝕜) k aux x by + apply this.congr_of_eventuallyEq_of_mem ?_ trivial + apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) + intro y hy + simp [aux, Basis.localFrame_repr_eq_repr hy] + simp only [aux] + + -- step 2: `s` read in trivialization `e` is `C^k` + have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by + rw [contMDiffAt_section_of_mem_baseSet hxe] at hs + exact hs + -- step 3: `b.repr` is a linear map, so the composition is smooth + let bas := fun v ↦ b.repr v i + let basl : F →ₗ[𝕜] 𝕜 := { + toFun := bas + map_add' m m' := by simp [bas] + map_smul' m x := by simp [bas] + } + let basL : F →L[𝕜] 𝕜 := { + toLinearMap := basl + cont := basl.continuous_of_finiteDimensional + } + have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k basL (e (s x)).2 := + contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt + exact hbas.comp x h₁ -/ + +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +/-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` +in the local frame induced by `e` -/ +lemma mdifferentiableOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) + {s : Π x : M, V x} {t : Set M} + (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : + MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) t := + fun _ hx ↦ (mdifferentiableAt_localFrame_repr (ht' hx) b + (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt + +omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +/-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the +local frame induced by `e` -/ +lemma mdifferentiableOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} + (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) + (i : ι) : + MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := + mdifferentiableOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ + +omit [IsManifold I 0 M] in +/-- A section `s` of `V` is differentiable at `x ∈ e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma mdifferentiableAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : + MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ + ∀ i, MDifferentiableAt I 𝓘(𝕜) (b.localFrame_repr e i s) x' := by + refine ⟨fun h i ↦ mdifferentiableAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ + have this (i) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ + TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + mdifferentiableAt_smul_section (hi i) + ((contMDiffAt_localFrame_of_mem 1 e b i hx).mdifferentiableAt le_rfl) + have almost : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) + (fun x ↦ TotalSpace.mk' F x (∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + mdifferentiableAt_finsum_section fun i ↦ this i + apply almost.congr_of_eventuallyEq ?_ + obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) + exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] + +omit [IsManifold I 0 M] in +/-- A section `s` of `V` is differentiable on `t ⊆ e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} + (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ + ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) t := by + refine ⟨fun h i ↦ mdifferentiableOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ + have this (i) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ + TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) t := + mdifferentiableOn_smul_section (hi i) <| + ((b.contMDiffOn_localFrame_baseSet 1 e i).mono ht').mdifferentiableOn le_rfl + let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' + have almost : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (rhs x)) t := + mdifferentiableOn_finsum_section fun i ↦ this i + sorry /- TODO, missing API: MDifferentiableOn.congr! #check ContMDiffOn.congr + apply almost.congr + intro y hy + congr + exact b.localFrame_repr_sum_eq s (ht' hy) -/ + +omit [IsManifold I 0 M] in +/-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma mdifferentiableOn_baseSet_iff_localFrame_repr + [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + (b : Basis ι 𝕜 F) {s : Π x : M, V x} : + MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := by + rw [mdifferentiableOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] + end -- local extension of a vector field in a trivialisation's base set From d12316fa0d396faab4ba82d66eed5575a46d5b6d Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 15:14:33 +0200 Subject: [PATCH 107/601] Fix argument order --- Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index b166b50cc9a535..e4f4c90e9cc8bd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -102,7 +102,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDim φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by exact locality hσ - (mdifferentiableAt_finsum_section fun i ↦ mdifferentiableAt_smul_section (hs i) (hc hσ i)) + (mdifferentiableAt_finsum_section fun i ↦ mdifferentiableAt_smul_section (hc hσ i) (hs i)) (Basis.localFrame_repr_spec b x_mem σ) rw [hφ hσ, hφ hσ', sum_phi, sum_phi] · change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x @@ -110,8 +110,8 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDim ext i rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i), Basis.localFrame_repr_congr b hσσ'] - · exact fun i ↦ mdifferentiableAt_smul_section (hs i) (hc hσ' i) - · exact fun i ↦ mdifferentiableAt_smul_section (hs i) (hc hσ i) + · exact fun i ↦ mdifferentiableAt_smul_section (hc hσ' i) (hs i) + · exact fun i ↦ mdifferentiableAt_smul_section (hc hσ i) (hs i) include I in omit [IsManifold I 1 M] [∀ (x : M), IsTopologicalAddGroup (V x)] From a8fde55c8607efdaa6437eda8bf6c691ede88684 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 15:13:43 +0200 Subject: [PATCH 108/601] Progress --- .../Manifold/VectorBundle/LocalFrame.lean | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index ebc0f6973add21..7b764b56883099 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -340,7 +340,8 @@ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] --- TODO: start filling in all the details from here onwards! +-- Differentiability of a section can be checked in terms of its local frame coefficients +section MDifferentiable omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame @@ -352,21 +353,20 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac (i : ι) : MDifferentiableAt I 𝓘(𝕜) (b.localFrame_repr e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical - sorry /- -- step 1: on e.baseSet, can compute the coefficient very well let aux := fun x ↦ b.repr (e (s x)).2 i -- Since e.baseSet is open, this is sufficient. - suffices ContMDiffAt I 𝓘(𝕜) k aux x by - apply this.congr_of_eventuallyEq_of_mem ?_ trivial + suffices MDifferentiableAt I 𝓘(𝕜) aux x by + sorry /-apply this.congr_of_eventuallyEq_of_mem ?_ trivial apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, Basis.localFrame_repr_eq_repr hy] + simp [aux, Basis.localFrame_repr_eq_repr hy] -/ simp only [aux] - -- step 2: `s` read in trivialization `e` is `C^k` - have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by - rw [contMDiffAt_section_of_mem_baseSet hxe] at hs - exact hs + -- step 2: `s` read in trivialization `e` is differentiable + have h₁ : MDifferentiableAt I 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) x := by + sorry /-rw [mdifferentiableAt_section_of_mem_baseSet hxe] at hs + exact hs -/ -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i let basl : F →ₗ[𝕜] 𝕜 := { @@ -378,9 +378,9 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac toLinearMap := basl cont := basl.continuous_of_finiteDimensional } - have hbas : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k basL (e (s x)).2 := - contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt - exact hbas.comp x h₁ -/ + have hbas : MDifferentiableAt 𝓘(𝕜, F) 𝓘(𝕜) basL (e (s x)).2 := + mdifferentiableAt_iff_differentiableAt.mpr (basL.differentiable _) + exact hbas.comp x h₁ omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` @@ -454,6 +454,8 @@ lemma mdifferentiableOn_baseSet_iff_localFrame_repr ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := by rw [mdifferentiableOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] +end MDifferentiable + end -- local extension of a vector field in a trivialisation's base set From d2e82d73e30921a51e16e954b317d79713a27b31 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 15:18:45 +0200 Subject: [PATCH 109/601] fix(VectorBundle/Basic): typos in a few comments And squash one easy sorry --- Mathlib/Geometry/Manifold/VectorBundle/Basic.lean | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 7c9038266a2eb7..1db26be0d398d8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -211,16 +211,17 @@ theorem contMDiffAt_section {s : ∀ x, E x} (x₀ : B) : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) x₀ := by simp_rw [contMDiffAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffAt_id -/-- Continuity of a `C^n` section at `x` can be determined +/-- Smoothness of a `C^n` section at `x` can be determined using any trivialisation whose `baseSet` contains `x`. -/ theorem contMDiffAt_section_of_mem_baseSet {s : ∀ x, E x} {x₀ : B} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by - sorry -- use the WithinAt version + simp_rw [← contMDiffWithinAt_univ] + exact contMDiffWithinAt_section_of_mem_BaseSet s univ e hx₀ -/-- Continuity of a `C^n` section on `s` can be determined +/-- Smoothness of a `C^n` section on `s` can be determined using any trivialisation whose `baseSet` contains `s`. -/ theorem contMDiffOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} @@ -238,7 +239,7 @@ theorem contMDiffOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} (h x hx).contMDiffAt <| ha.mem_nhds hx exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mpr this).contMDiffWithinAt -/-- For any trivialization `e`, the continuity of a `C^n` section on `e.baseSet` +/-- For any trivialization `e`, the smoothness of a `C^n` section on `e.baseSet` can be determined using `e`. -/ theorem contMDiffOn_section_of_mem_baseSet₀ {s : ∀ x, E x} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} From f97caa755774441988beb024547041f96466dc22 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 15:26:20 +0200 Subject: [PATCH 110/601] chore: more MDifferentiable API; one sorry down --- .../Manifold/VectorBundle/LocalFrame.lean | 4 +- .../VectorBundle/MDifferentiable.lean | 52 ++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 7b764b56883099..a146da625098ad 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -365,8 +365,8 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac -- step 2: `s` read in trivialization `e` is differentiable have h₁ : MDifferentiableAt I 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) x := by - sorry /-rw [mdifferentiableAt_section_of_mem_baseSet hxe] at hs - exact hs -/ + rw [mdifferentiableAt_section_of_mem_baseSet hxe] at hs + exact hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i let basl : F →ₗ[𝕜] 𝕜 := { diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 74af5bbe7f5769..b29bc5b9b3984b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -64,7 +64,7 @@ theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f /-- Characterization of differentiable sections of a vector bundle at a point within a set -in term of the preferred trivialization at that point. -/ +in terms of the preferred trivialization at that point. -/ theorem mdifferentiableWithinAt_section (s : Π b, E b) {u : Set B} {b₀ : B} : MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) u b₀ ↔ MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) u b₀ := by @@ -73,12 +73,60 @@ theorem mdifferentiableWithinAt_section (s : Π b, E b) {u : Set B} {b₀ : B} : simp [mdifferentiableWithinAt_id] /-- Characterization of differentiable sections of a vector bundle at a point within a set -in term of the preferred trivialization at that point. -/ +in terms of the preferred trivialization at that point. -/ theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) b₀ ↔ MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ +variable {IB} in +theorem mdifferentiableWithinAt_section_of_mem_BaseSet (s : ∀ x, E x) (a : Set B) {x₀ : B} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : + MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) a x₀ ↔ + MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) a x₀ := by + sorry + +variable {IB} in +/-- Differentiability of a section at `x` can be determined +using any trivialisation whose `baseSet` contains `x`. -/ +theorem mdifferentiableAt_section_of_mem_baseSet {s : ∀ x, E x} {x₀ : B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : + MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ + MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by + simp_rw [← mdifferentiableWithinAt_univ] + exact mdifferentiableWithinAt_section_of_mem_BaseSet s univ e hx₀ + +variable {IB} in +/-- Differentiability of a section on `s` can be determined +using any trivialisation whose `baseSet` contains `s`. -/ +theorem mdifferentiableOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ + MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) a := by + -- golfing useful? + constructor + · intro h x hx + have : MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x := + (h x hx).mdifferentiableAt <| ha.mem_nhds hx + exact ((mdifferentiableAt_section_of_mem_baseSet (ha' hx)).mp this).mdifferentiableWithinAt + · intro h x hx + have : MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e { proj := x, snd := s x }).2) x := + (h x hx).mdifferentiableAt <| ha.mem_nhds hx + exact ((mdifferentiableAt_section_of_mem_baseSet (ha' hx)).mpr this).mdifferentiableWithinAt + +variable {IB} in +/-- For any trivialization `e`, the differentiability of a section on `e.baseSet` +can be determined using `e`. -/ +theorem mdifferentiableOn_section_of_mem_baseSet₀ {s : ∀ x, E x} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] : + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := + mdifferentiableOn_section_of_mem_baseSet e.open_baseSet (subset_refl _) + variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] From cd150c896fb519c2527db12fa1aba109e5044991 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 15:40:42 +0200 Subject: [PATCH 111/601] chore: squash some easy sorries; some got lost in a merge conflict --- .../VectorBundle/CovariantDerivative.lean | 28 +++++++------------ .../Manifold/VectorBundle/LocalFrame.lean | 2 +- .../Manifold/VectorBundle/Tensoriality.lean | 10 +++---- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 5d3b85f54a47f1..137d0ab900cc75 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -543,31 +543,23 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ simpa [extend] using localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v -lemma contMDiff_extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) 1 (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by - --letI b := Basis.ofVectorSpace ℝ F - --letI V₀ := localExtensionOn b t x σ₀ - -- Choose a smooth bump function ψ near `x`, supported within t.baseSet - -- and return ψ • V₀ instead. +lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by letI t := trivializationAt F V x letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht -- XXX: extract ψ and hψ as helper declarations, perhaps private to prevent API leakage? let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - --let res := ψ.toFun • localExtensionOn b t x σ₀ - unfold extend - -- show ContMDiff I (I.prod 𝓘(ℝ, F)) 1 fun x_1 ↦ TotalSpace.mk' F x_1 (extend I F σ₀ x_1) -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function -- the latter is easier to just prove directly by hand refine contMDiff_of_contMDiffOn_union_of_isOpen ?_ ?_ ?_ t.open_baseSet (t := (tsupport ψ)ᶜ) ?_ - · sorry - · have aux : ContMDiffOn I (I.prod 𝓘(ℝ, F)) 1 - (fun x_1 ↦ TotalSpace.mk' F x_1 (0 : V x_1)) (tsupport ↑ψ)ᶜ := by - apply ContMDiff.contMDiffOn - -- #check contMDiff_of_locally_contMDiffOn for the helper lemmas above - -- should be contMDiff_zero_section - sorry + · exact contMDiffOn_smul_section ψ.contMDiff.contMDiffOn <| + contMDiffOn_localExtensionOn _ (FiberBundle.mem_baseSet_trivializationAt' x) σ₀ + · have aux : ContMDiffOn I (I.prod 𝓘(ℝ, F)) ∞ + (fun x_1 ↦ TotalSpace.mk' F x_1 (0 : V x_1)) (tsupport ↑ψ)ᶜ := + (contMDiff_zeroSection _ _).contMDiffOn apply aux.congr fun y hy ↦ ?_ simpa [extend] using Or.inl <| image_eq_zero_of_notMem_tsupport hy · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr hψ.1 @@ -623,8 +615,8 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y' (x := x)) x := by apply cov.addσ - · exact (contMDiff_extend _ _).mdifferentiableAt (n := 1) (hn := by norm_num) - · apply (contMDiff_extend _ _).mdifferentiableAt (n := 1) (hn := by norm_num) + · exact (contMDiff_extend _ _).mdifferentiableAt (n := ∞) (hn := by norm_num) + · apply (contMDiff_extend _ _).mdifferentiableAt (n := ∞) (hn := by norm_num) simp [A, B] module map_smul' a v := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index a146da625098ad..e3cb9114355979 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -537,7 +537,7 @@ variable (F) in omit [IsManifold I 0 M] in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] {x : M} (hx : x ∈ e.baseSet) (v : V x) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) 1 + ContMDiffOn I (I.prod 𝓘(𝕜, F)) ∞ (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are -- constant, hence smoothness follows. diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index e4f4c90e9cc8bd..8c3761f74687eb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -95,8 +95,8 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDim (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl have hc {σ : (x : M) → V x} (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (i) : - MDifferentiableAt I 𝓘(ℝ, ℝ) ((c i) σ) x := by - sorry + MDifferentiableAt I 𝓘(ℝ, ℝ) ((c i) σ) x := + mdifferentiableAt_localFrame_repr x_mem b hσ i have hφ {σ : (x : M) → V x} (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) : φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by @@ -145,9 +145,9 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl, φ_smul] simp | insert a s ha h => - change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp [Finset.sum_insert ha, ← h] - erw [φ_add] + change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ + simp [Finset.sum_insert ha, ← h] + erw [φ_add] have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x From 756f697710ebc6e765b734ae1294da8d9201faa7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 17:06:44 +0200 Subject: [PATCH 112/601] chore: add equivalent congruence lemmas for MFDifferentiableWithinAt One more sorry about local frames resolved --- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 29 +++++++++++++++++++ .../Manifold/VectorBundle/LocalFrame.lean | 3 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index 9f7897f42382b2..7578cbd661e671 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -963,6 +963,23 @@ theorem HasMFDerivAt.congr_of_eventuallyEq (h : HasMFDerivAt I I' f x f') (h₁ apply h.congr_of_eventuallyEq _ (mem_of_mem_nhds h₁ :) rwa [nhdsWithin_univ] +theorem mdifferentiableWithinAt_congr (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : f₁ x = f x) : + MDifferentiableWithinAt I I' f₁ s x ↔ MDifferentiableWithinAt I I' f s x := + differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_iff h₁ hx + +theorem MDifferentiableWithinAt.congr_of_mem + (h : MDifferentiableWithinAt I I' f s x) (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : x ∈ s) : + MDifferentiableWithinAt I I' f₁ s x := + differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_of_mem h h₁ hx + +theorem mdifferentiableWithinAt_congr_of_mem (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : x ∈ s) : + MDifferentiableWithinAt I I' f₁ s x ↔ MDifferentiableWithinAt I I' f s x := + differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_iff_of_mem h₁ hx + +theorem Filter.EventuallyEq.mdifferentiablefWithinAt_iff (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : + MDifferentiableWithinAt I I' f₁ s x ↔ MDifferentiableWithinAt I I' f s x := + differentiableWithinAt_localInvariantProp.liftPropWithinAt_congr_iff_of_eventuallyEq h₁ hx + theorem MDifferentiableWithinAt.congr_of_eventuallyEq (h : MDifferentiableWithinAt I I' f s x) (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : MDifferentiableWithinAt I I' f₁ s x := (h.hasMFDerivWithinAt.congr_of_eventuallyEq h₁ hx).mdifferentiableWithinAt @@ -997,6 +1014,18 @@ theorem MDifferentiableWithinAt.congr (h : MDifferentiableWithinAt I I' f s x) (ht : ∀ x ∈ s, f₁ x = f x) (hx : f₁ x = f x) : MDifferentiableWithinAt I I' f₁ s x := (HasMFDerivWithinAt.congr_mono h.hasMFDerivWithinAt ht hx (Subset.refl _)).mdifferentiableWithinAt +theorem Filter.EventuallyEq.mdifferentiableAt_iff (h₁ : f₁ =ᶠ[𝓝 x] f) : + MDifferentiableAt I I' f₁ x ↔ MDifferentiableAt I I' f x := + differentiableWithinAt_localInvariantProp.liftPropAt_congr_iff_of_eventuallyEq h₁ + +theorem MDifferentiableOn.congr (h : MDifferentiableOn I I' f s) (h₁ : ∀ y ∈ s, f₁ y = f y) : + MDifferentiableOn I I' f₁ s := + differentiableWithinAt_localInvariantProp.liftPropOn_congr h h₁ + +theorem mdifferentiableOn_congr (h₁ : ∀ y ∈ s, f₁ y = f y) : + MDifferentiableOn I I' f₁ s ↔ MDifferentiableOn I I' f s := + differentiableWithinAt_localInvariantProp.liftPropOn_congr_iff h₁ + theorem MDifferentiableOn.congr_mono (h : MDifferentiableOn I I' f s) (h' : ∀ x ∈ t, f₁ x = f x) (h₁ : t ⊆ s) : MDifferentiableOn I I' f₁ t := fun x hx => (h x (h₁ hx)).congr_mono h' (h' x hx) h₁ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index e3cb9114355979..d0bcd0419d4ce2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -438,11 +438,10 @@ lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' have almost : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (rhs x)) t := mdifferentiableOn_finsum_section fun i ↦ this i - sorry /- TODO, missing API: MDifferentiableOn.congr! #check ContMDiffOn.congr apply almost.congr intro y hy congr - exact b.localFrame_repr_sum_eq s (ht' hy) -/ + exact b.localFrame_repr_sum_eq s (ht' hy) omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its From 42df8a5a29eb6c208370c781a785f39cde6aa67a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 17:09:57 +0200 Subject: [PATCH 113/601] Another sorry --- Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index d0bcd0419d4ce2..023d366cba3e63 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -248,7 +248,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 let aux := fun x ↦ b.repr (e (s x)).2 i -- Since e.baseSet is open, this is sufficient. suffices ContMDiffAt I 𝓘(𝕜) k aux x by - apply this.congr_of_eventuallyEq_of_mem ?_ trivial + apply this.congr_of_eventuallyEq ?_ apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy simp [aux, Basis.localFrame_repr_eq_repr hy] @@ -357,10 +357,10 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac let aux := fun x ↦ b.repr (e (s x)).2 i -- Since e.baseSet is open, this is sufficient. suffices MDifferentiableAt I 𝓘(𝕜) aux x by - sorry /-apply this.congr_of_eventuallyEq_of_mem ?_ trivial + apply this.congr_of_eventuallyEq apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, Basis.localFrame_repr_eq_repr hy] -/ + simp [aux, Basis.localFrame_repr_eq_repr hy] simp only [aux] -- step 2: `s` read in trivialization `e` is differentiable From 7b336e3077ca7f9ef707535fb6b0d943767729aa Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 17:12:46 +0200 Subject: [PATCH 114/601] chore(Tensoriality): small variable clean-up --- .../Manifold/VectorBundle/Tensoriality.lean | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 8c3761f74687eb..41d6ccde052212 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -25,8 +25,8 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] (n : WithTop ℕ∞) (V : M → Type*) [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] + -- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] [FiberBundle F V] [VectorBundle ℝ F V] -- `V` vector bundle @@ -34,9 +34,10 @@ variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] (m : WithTop ℕ∞) (V' : M → Type*) [TopologicalSpace (TotalSpace F' V')] [∀ x, AddCommGroup (V' x)] [∀ x, Module ℝ (V' x)] - [∀ x : M, TopologicalSpace (V' x)] [∀ x, IsTopologicalAddGroup (V' x)] - [∀ x, ContinuousSMul ℝ (V' x)] + [∀ x : M, TopologicalSpace (V' x)] + -- [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] +omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] [IsManifold I ∞ M] @@ -114,9 +115,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDim · exact fun i ↦ mdifferentiableAt_smul_section (hc hσ i) (hs i) include I in -omit [IsManifold I 1 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul ℝ (V x)] [FiberBundle F V] [VectorBundle ℝ F V] - [∀ (x : M), IsTopologicalAddGroup (V' x)] [∀ (x : M), ContinuousSMul ℝ (V' x)] in +omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] {φ : (Π x : M, V x) → (Π x, V' x)} {x} From fede64dee19d50e3db0877270ef9f6caebe184c9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 18:02:21 +0200 Subject: [PATCH 115/601] chore: clean up the bump function lemma --- .../Geometry/Manifold/ContMDiff/Basic.lean | 3 +- .../VectorBundle/CovariantDerivative.lean | 68 ++++++++++--------- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean index 4155ff38a48684..2f420b5ca283cb 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean @@ -224,7 +224,8 @@ end const /-- `f` is continuously differentiable if it is cont. differentiable at each `x ∈ mulTSupport f`. -/ @[to_additive "`f` is continuously differentiable if it is continuously -differentiable at each `x ∈ tsupport f`."] +differentiable at each `x ∈ tsupport f`. See also `contMDiff_section_of_smul_smoothBumpFunction` +for a similar result for sections of vector bundles, paired with a smooth bump function."] theorem contMDiff_of_mulTSupport [One M'] {f : M → M'} (hf : ∀ x ∈ mulTSupport f, ContMDiffAt I I' n f x) : ContMDiff I I' n f := by intro x diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 137d0ab900cc75..3f38d12a025a23 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -169,26 +169,6 @@ lemma contMDiff_of_contMDiffOn_iUnion_of_isOpen {ι : Type*} {s : ι → Set M} rw [← contMDiffOn_univ, ← hs'] exact ContMDiffOn.iUnion_of_isOpen hf hs -/-- A section is `C^n` whenever it is `C^n` on its support. -This is a more global version of `contMDiff_of_tsupport` (which does not apply, as it assumes the -co-domain has a zero: the total space of a vector bundle has none): in return for the additional -generality, we need to add a hypothesis about the zero section being smooth. -/ -lemma ContMDiff.of_contMDiffOn_smul_bump_function [SMul 𝕜 M'] (hf : ContMDiffOn I I' n f s) - (hs : IsOpen s) {ψ : M → 𝕜} (hψ : ContMDiff I 𝓘(𝕜) n ψ) (hψ' : tsupport ψ ⊆ s) - -- XXX: is there a better abstraction of "the zero section"? - (hzero : ContMDiff I I' n (fun x ↦ (0 : 𝕜) • f x)) : ContMDiff I I' n (ψ • f) := by - apply contMDiff_of_contMDiffOn_union_of_isOpen ?_ ?_ ?_ hs - (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) - · -- TODO: impose further typeclasses to make this true... - sorry -- scalar multiplication is C^n, for sections: will be done for local frames as well - · apply (hzero.contMDiffOn (s := (tsupport ψ)ᶜ)).congr - intro y hy - simp [image_eq_zero_of_notMem_tsupport hy] - · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr hψ' - --- See also `ContMDiff.of_contMDiffOn_smul_bump_function` for the analogous result applying --- to sections of vector bundles (whose co-domain has no zero). - end contMDiff_union @[ext] @@ -471,6 +451,7 @@ lemma differenceAux_smul_eq' (cov cov' : CovariantDerivative I F V) differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by simp [differenceAux, cov.smulX, cov'.smulX, smul_sub] +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] @@ -543,6 +524,39 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ simpa [extend] using localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +/-- If `ψ: M → ℝ` a smooth bump function and `s` is a section of a smooth vector bundle `V → M`, +the scalar product `ψ s` is `C^n` if `s` is `C^n` on an open set containing `tsupport ψ`. +This is a vector bundle analogue of `contMDiff_of_tsupport`: the total space of `V` has no zero, +but we only consider sections of the form `ψ s`. -/ +lemma _root_.contMDiff_section_of_smul_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] + {s : Π (x : M), V x} {ψ : SmoothBumpFunction I x} {t : Set M} + (hs : ContMDiffOn I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) t) + (ht : IsOpen t) (ht' : tsupport ψ ⊆ t) (hn : n ≤ ∞) : + ContMDiff I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by + apply contMDiff_of_contMDiffOn_union_of_isOpen + (contMDiffOn_smul_section (ψ.contMDiff.of_le hn).contMDiffOn hs) ?_ ?_ ht + (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) + · apply ((contMDiff_zeroSection _ _).contMDiffOn (s := (tsupport ψ)ᶜ)).congr + intro y hy + simp [image_eq_zero_of_notMem_tsupport hy, zeroSection] + · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr ht' + +-- unused, but might be nice to have +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +/-- If `ψ: M → ℝ` a smooth bump function and `s` is a section of a smooth vector bundle `V → M`, +the scalar product `ψ s` is `C^n` if `s` is `C^n` at each `x ∈ tsupport ψ`. +This is a vector bundle analogue of `contMDiff_of_tsupport`: the total space of `V` has no zero, +but we only consider sections of the form `ψ s`. -/ +lemma _root_.contMDiff_section_of_smul_smoothBumpFunction' [T2Space M] [IsManifold I ∞ M] + {s : Π (x : M), V x} {ψ : SmoothBumpFunction I x} (hn : n ≤ ∞) + (hs : ∀ x ∈ tsupport ψ, + ContMDiffAt I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by + -- apply contMDiff_of_smul_smoothBumpFunction (s := s) (hn := hn) --?_ ?_ ?_ ?_ + sorry + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by letI t := trivializationAt F V x @@ -552,18 +566,8 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M -- XXX: extract ψ and hψ as helper declarations, perhaps private to prevent API leakage? let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - -- use contMDiffOn_localExtensionOn, plus an abstract result about capping with a bump function - -- the latter is easier to just prove directly by hand - refine contMDiff_of_contMDiffOn_union_of_isOpen ?_ ?_ ?_ t.open_baseSet (t := (tsupport ψ)ᶜ) ?_ - · exact contMDiffOn_smul_section ψ.contMDiff.contMDiffOn <| - contMDiffOn_localExtensionOn _ (FiberBundle.mem_baseSet_trivializationAt' x) σ₀ - · have aux : ContMDiffOn I (I.prod 𝓘(ℝ, F)) ∞ - (fun x_1 ↦ TotalSpace.mk' F x_1 (0 : V x_1)) (tsupport ↑ψ)ᶜ := - (contMDiff_zeroSection _ _).contMDiffOn - apply aux.congr fun y hy ↦ ?_ - simpa [extend] using Or.inl <| image_eq_zero_of_notMem_tsupport hy - · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr hψ.1 - · exact isOpen_compl_iff.mpr <| isClosed_tsupport ψ + apply _root_.contMDiff_section_of_smul_smoothBumpFunction _ ?_ t.open_baseSet hψ.1 le_rfl + apply contMDiffOn_localExtensionOn _ hx /-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference From 4063d3f2934ce4da6192099e4c8cbced813c1570 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 18:13:41 +0200 Subject: [PATCH 116/601] Fix stuff --- .../VectorBundle/CovariantDerivative.lean | 6 +- .../Manifold/VectorBundle/LocalFrame.lean | 19 ++--- .../VectorBundle/MDifferentiable.lean | 78 +++++++------------ .../Manifold/VectorBundle/Tensoriality.lean | 3 +- 4 files changed, 45 insertions(+), 61 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 3f38d12a025a23..02d0f8cc9cad79 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -454,7 +454,7 @@ lemma differenceAux_smul_eq' (cov cov' : CovariantDerivative I F V) omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - [FiniteDimensional ℝ F] + [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] (X X' : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x₀ : M) (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x₀) (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x₀) @@ -556,7 +556,6 @@ lemma _root_.contMDiff_section_of_smul_smoothBumpFunction' [T2Space M] [IsManifo -- apply contMDiff_of_smul_smoothBumpFunction (s := s) (hn := hn) --?_ ?_ ?_ ?_ sorry -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by letI t := trivializationAt F V x @@ -583,7 +582,8 @@ noncomputable def difference -- @[simp] -- lemma difference_toFun [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] -- (cov cov' : CovariantDerivative I F V) : --- cov.difference cov' = fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) (extend F σ₀) x := rfl +-- cov.difference cov' = fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) +-- (extend F σ₀) x := rfl -- show? the map differenceAux to difference is injective diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 023d366cba3e63..1891b2dc93c4b1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -343,10 +343,11 @@ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional -- Differentiability of a section can be checked in terms of its local frame coefficients section MDifferentiable -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in /-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame near `x` induced by `e` and `b` -/ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + [ContMDiffVectorBundle 1 F V I] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x) @@ -365,8 +366,7 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac -- step 2: `s` read in trivialization `e` is differentiable have h₁ : MDifferentiableAt I 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) x := by - rw [mdifferentiableAt_section_of_mem_baseSet hxe] at hs - exact hs + exact e.mdifferentiableAt_section_iff I s hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i let basl : F →ₗ[𝕜] 𝕜 := { @@ -382,22 +382,22 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac mdifferentiableAt_iff_differentiableAt.mpr (basL.differentiable _) exact hbas.comp x h₁ -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in /-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma mdifferentiableOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {t : Set M} + [ContMDiffVectorBundle 1 F V I] {s : Π x : M, V x} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) t := fun _ hx ↦ (mdifferentiableAt_localFrame_repr (ht' hx) b (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in /-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma mdifferentiableOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} + [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := @@ -407,6 +407,7 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable at `x ∈ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ ∀ i, MDifferentiableAt I 𝓘(𝕜) (b.localFrame_repr e i s) x' := by @@ -426,7 +427,7 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on `t ⊆ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} + [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) t := by @@ -447,7 +448,7 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableOn_baseSet_iff_localFrame_repr - [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] + [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index b29bc5b9b3984b..9aff23c4192661 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -79,54 +79,6 @@ theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ -variable {IB} in -theorem mdifferentiableWithinAt_section_of_mem_BaseSet (s : ∀ x, E x) (a : Set B) {x₀ : B} - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) - [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : - MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) a x₀ ↔ - MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) a x₀ := by - sorry - -variable {IB} in -/-- Differentiability of a section at `x` can be determined -using any trivialisation whose `baseSet` contains `x`. -/ -theorem mdifferentiableAt_section_of_mem_baseSet {s : ∀ x, E x} {x₀ : B} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : - MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ - MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by - simp_rw [← mdifferentiableWithinAt_univ] - exact mdifferentiableWithinAt_section_of_mem_BaseSet s univ e hx₀ - -variable {IB} in -/-- Differentiability of a section on `s` can be determined -using any trivialisation whose `baseSet` contains `s`. -/ -theorem mdifferentiableOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : - MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ - MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) a := by - -- golfing useful? - constructor - · intro h x hx - have : MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x := - (h x hx).mdifferentiableAt <| ha.mem_nhds hx - exact ((mdifferentiableAt_section_of_mem_baseSet (ha' hx)).mp this).mdifferentiableWithinAt - · intro h x hx - have : MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e { proj := x, snd := s x }).2) x := - (h x hx).mdifferentiableAt <| ha.mem_nhds hx - exact ((mdifferentiableAt_section_of_mem_baseSet (ha' hx)).mpr this).mdifferentiableWithinAt - -variable {IB} in -/-- For any trivialization `e`, the differentiability of a section on `e.baseSet` -can be determined using `e`. -/ -theorem mdifferentiableOn_section_of_mem_baseSet₀ {s : ∀ x, E x} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] : - MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ - MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := - mdifferentiableOn_section_of_mem_baseSet e.open_baseSet (subset_refl _) - variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] @@ -223,6 +175,36 @@ theorem Trivialization.mdifferentiableAt_section_iff MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) b₀ ↔ MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) b₀ := by simpa [← mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_section_iff IB s hex₀ + +variable {IB} in +/-- Differentiability of a section on `s` can be determined +using any trivialisation whose `baseSet` contains `s`. -/ +theorem mdifferentiableOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ + MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) a := by + -- golfing useful? + constructor + · intro h x hx + have : MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x := + (h x hx).mdifferentiableAt <| ha.mem_nhds hx + exact ((e.mdifferentiableAt_section_iff _ _ (ha' hx)).mp this).mdifferentiableWithinAt + · intro h x hx + have : MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e { proj := x, snd := s x }).2) x := + (h x hx).mdifferentiableAt <| ha.mem_nhds hx + exact ((e.mdifferentiableAt_section_iff _ _ (ha' hx)).mpr this).mdifferentiableWithinAt + +variable {IB} in +/-- For any trivialization `e`, the differentiability of a section on `e.baseSet` +can be determined using `e`. -/ +theorem mdifferentiableOn_section_of_mem_baseSet₀ {s : ∀ x, E x} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] : + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := + mdifferentiableOn_section_of_mem_baseSet e.open_baseSet (subset_refl _) + end section operations diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 41d6ccde052212..432f3412416831 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -38,7 +38,8 @@ variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] -- [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in -lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] +lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] + [ContMDiffVectorBundle 1 F V I] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] [IsManifold I ∞ M] {φ : (Π x : M, V x) → (Π x, V' x)} {x} From 2d3a798f430dd8b921f5ce03653ddf0cd9837084 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 18:21:27 +0200 Subject: [PATCH 117/601] =?UTF-8?q?Dump=20Kyle=E2=80=99s=20#check'=20in=20?= =?UTF-8?q?the=20vector=20bundle=20folder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Geometry/Manifold/VectorBundle/Basic.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 1db26be0d398d8..45a2abf259eac8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -57,6 +57,18 @@ fields, etc. vector bundle. -/ +-- Kyle’s #check' command. This has nothing to do here but will be convenient for us +open Lean Elab Command PrettyPrinter Delaborator in +elab tk:"#check' " name:ident : command => runTermElabM fun _ => do + for c in (← realizeGlobalConstWithInfos name) do + addCompletionInfo <| .id name name.getId (danglingDot := false) {} none + let info ← getConstInfo c + let delab : Delab := do + delabForallParamsWithSignature fun binders type => do + let binders := binders.filter fun binder => binder.raw.isOfKind ``Parser.Term.explicitBinder + return ⟨← `(declSigWithId| $(mkIdent c) $binders* : $type)⟩ + logInfoAt tk <| .ofFormatWithInfosM (PrettyPrinter.ppExprWithInfos (delab := delab) info.type) + assert_not_exists mfderiv open Bundle Set PartialHomeomorph From b147ab9cdccc823dd6848dad9e521d82170f4ba3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 18:48:04 +0200 Subject: [PATCH 118/601] doc: slightly extend the cheat sheet --- Mathlib/Geometry/Manifold/CheatSheet.md | 36 ++++++++++++++++++------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/CheatSheet.md b/Mathlib/Geometry/Manifold/CheatSheet.md index e5f3b55b074742..ede331a4011da6 100644 --- a/Mathlib/Geometry/Manifold/CheatSheet.md +++ b/Mathlib/Geometry/Manifold/CheatSheet.md @@ -41,15 +41,15 @@ import Mathlib.Geometry.Manifold.ContMDiff.Defs variable -- Given a non-trivially normed field 𝕜 - {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {𝕜 : Type*} [NontriviallyNormedField 𝕜] -- A manifold M over 𝕜 - {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- A manifold M' over 𝕜 {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 E' H') - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 E' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] -- A function from M to M' and x in M (f : M → M') (x : M) @@ -58,14 +58,14 @@ variable (x : M) in #check MDifferentiableAt I I' f x variable (n : WithTop ℕ∞) in -- A natural number or ∞ or ω -#check ContMDiff I I' n f +#check ContMDiff I I' n f -variable - {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] +variable + {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] (g : M → F) in open scoped Manifold in -#check ContMDiff I 𝓘(𝕜, F) n g -- g is n times continuously differentiable +#check ContMDiff I 𝓘(𝕜, F) n g -- g is n times continuously differentiable ``` Consider the product manifold M \times N. @@ -82,8 +82,25 @@ Let E\to M be a topological vector bundle. Let E\to M be a smooth vector bundle. Let s be a section of E. +``` +variable (s : Π x : M, V x) +``` +Let X be a vector field on `M` +``` +(X : Π x : M, TangentSpace I x) +``` + Let s be a C^k section of E. / The section s of E is C^k. +``` +ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (fun x ↦ TotalSpace.mk' F x (σ x)) +``` +Let `X` be a C^k vector field on M. +``` +variable {X : Π x : M, TangentSpace I x} +-- TODO: this doesn't work! +-- variable (___hX: ContMDiff I I.tangent 2 (fun x ↦ (X x : TangentBundle I M))) +``` Let \phi be the preferred local trivialisation at x\in E. Let \phi be any compatible trivialisation on M. @@ -92,7 +109,6 @@ Consider the tangent bundle TM of M. Let X be a C^k vector field on M. - explain TotalSpace.mk' somewhere in here... From b97bfef8033b154dae21367bab4c989c74505b0f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 18:48:43 +0200 Subject: [PATCH 119/601] chore: first notion of regularity of a connection and prove that some constructions are as regular as we think. TODO, cannot encode regularity of X yet --- .../VectorBundle/CovariantDerivative.lean | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 02d0f8cc9cad79..acaf30e18cd1e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -189,6 +189,21 @@ structure CovariantDerivative where smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), toFun X (a • σ) = a • toFun X σ +variable {I F V} +/-- +A covariant derivative ∇ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) where + regularity : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x), + ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (fun x ↦ TotalSpace.mk' F x (σ x)) → + -- TODO: this condition does not typecheck! + -- ContMDiff I I.tangent k (fun x ↦ (X x : TangentBundle I M)) → + ContMDiff I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (cov.toFun X σ x)) + +-- future: if g is a C^k metric, the LC connection is of class C^k ? + namespace CovariantDerivative attribute [coe] toFun @@ -217,7 +232,6 @@ lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -variable {I F V} in /-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ lemma congr_σ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) (x : M) : @@ -236,9 +250,9 @@ lemma sum_X (cov : CovariantDerivative I F V) /-- A convex combination of covariant derivatives is a covariant derivative. -/ @[simps] -def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : +def convexCombination (cov cov' : CovariantDerivative I F V) (f : M → 𝕜) : CovariantDerivative I F V where - toFun X s := (t • (cov X s)) + (1 - t) • (cov' X s) + toFun X s := (f • (cov X s)) + (1 - f) • (cov' X s) addX X X' σ := by simp only [cov.addX, cov'.addX]; module smulX X σ f := by simp only [cov.smulX, cov'.smulX]; module addσ X σ σ' x hσ hσ' := by @@ -251,9 +265,24 @@ def convexCombination (cov cov' : CovariantDerivative I F V) (t : 𝕜) : simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] module +omit [IsManifold I 0 M] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +/-- A convex combination of two `C^k` connections is a `C^k` connection. -/ +lemma convexCombination_isRegular (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} + (hf : ContMDiff I 𝓘(𝕜) n f) + (hcov : IsCkConnection cov n) (hcov' : IsCkConnection cov' n) : + IsCkConnection (convexCombination cov cov' f) n where + regularity X σ hX /-hσ-/ := by + apply contMDiff_add_section + · exact contMDiff_smul_section hf <| hcov.regularity X σ hX + · exact contMDiff_smul_section (contMDiff_const.sub hf) <| hcov'.regularity X σ hX + +-- Future: prove finsum version of this, and one with a locally finite sum + variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] variable (E E') in +/-- The trivial connection on a trivial bundle, given by the directional derivative -/ @[simps] noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where @@ -271,6 +300,15 @@ noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' simp [this, bar] rfl +open scoped Manifold + +/-- The trivial connection on the trivial bundle is smooth -/ +-- TODO: fix parsing error with putting exponent ∞ +lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') 42 where + regularity X σ hX /-hσ-/ := by + simp [trivial] + sorry -- where's the relevant lemma in the library? + open scoped Classical in @[simps] noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : @@ -296,6 +334,8 @@ noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : simp [this, bar] module +-- TODO: prove something about the regularity of this connection + section real variable {E : Type*} [NormedAddCommGroup E] From 48ddd8541cf589dd801f0e40b0f050d4b61cfd82 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 1 Jul 2025 18:54:30 +0200 Subject: [PATCH 120/601] Remove a differentiability sorry and fix stuff --- .../Geometry/Manifold/VectorBundle/Basic.lean | 91 ++++++++++--------- .../VectorBundle/CovariantDerivative.lean | 4 +- .../Manifold/VectorBundle/LocalFrame.lean | 28 +++--- 3 files changed, 65 insertions(+), 58 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 45a2abf259eac8..ef1a9ab673d366 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -210,55 +210,12 @@ theorem contMDiffWithinAt_section (s : ∀ x, E x) (a : Set B) (x₀ : B) : ContMDiffWithinAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) a x₀ := by simp_rw [contMDiffWithinAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffWithinAt_id -theorem contMDiffWithinAt_section_of_mem_BaseSet (s : ∀ x, E x) (a : Set B) {x₀ : B} - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) - [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : - ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a x₀ ↔ - ContMDiffWithinAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a x₀ := by - sorry - /-- Characterization of `C^n` sections of a vector bundle. -/ theorem contMDiffAt_section {s : ∀ x, E x} (x₀ : B) : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) x₀ := by simp_rw [contMDiffAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffAt_id -/-- Smoothness of a `C^n` section at `x` can be determined -using any trivialisation whose `baseSet` contains `x`. -/ -theorem contMDiffAt_section_of_mem_baseSet {s : ∀ x, E x} {x₀ : B} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : - ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ - ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by - simp_rw [← contMDiffWithinAt_univ] - exact contMDiffWithinAt_section_of_mem_BaseSet s univ e hx₀ - -/-- Smoothness of a `C^n` section on `s` can be determined -using any trivialisation whose `baseSet` contains `s`. -/ -theorem contMDiffOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : - ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ - ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a := by - -- golfing useful? - constructor - · intro h x hx - have : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x := - (h x hx).contMDiffAt <| ha.mem_nhds hx - exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mp this).contMDiffWithinAt - · intro h x hx - have : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e { proj := x, snd := s x }).2) x := - (h x hx).contMDiffAt <| ha.mem_nhds hx - exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mpr this).contMDiffWithinAt - -/-- For any trivialization `e`, the smoothness of a `C^n` section on `e.baseSet` -can be determined using `e`. -/ -theorem contMDiffOn_section_of_mem_baseSet₀ {s : ∀ x, E x} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] : - ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ - ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := - contMDiffOn_section_of_mem_baseSet e.open_baseSet (subset_refl _) variable (E) @@ -544,6 +501,54 @@ theorem Trivialization.contMDiffOn_symm (e : Trivialization F (π F E)) [MemTriv contMDiffOn_snd.congr fun x hx ↦ ?_⟩ rw [e.apply_symm_apply hx] +/-- Smoothness of a `C^n` section at `x₀` within a set `a` can be determined +using any trivialisation whose `baseSet` contains `x₀`. -/ +theorem Trivialization.contMDiffWithinAt_section (s : ∀ x, E x) (a : Set B) {x₀ : B} + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : + ContMDiffWithinAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a x₀ ↔ + ContMDiffWithinAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a x₀ := by + rw [e.contMDiffWithinAt_iff] + · change ContMDiffWithinAt IB IB n id a x₀ ∧ _ ↔ _ + simp [contMDiffWithinAt_id] + · rwa [mem_source] + +/-- Smoothness of a `C^n` section at `x₀` can be determined +using any trivialisation whose `baseSet` contains `x₀`. -/ +theorem contMDiffAt_section_of_mem_baseSet {s : ∀ x, E x} {x₀ : B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] (hx₀ : x₀ ∈ e.baseSet) : + ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀ ↔ + ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) x₀ := by + simp_rw [← contMDiffWithinAt_univ] + exact e.contMDiffWithinAt_section s univ hx₀ + +/-- Smoothness of a `C^n` section on `s` can be determined +using any trivialisation whose `baseSet` contains `s`. -/ +theorem contMDiffOn_section_of_mem_baseSet {s : ∀ x, E x} {a : Set B} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : + ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ + ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) a := by + -- golfing useful? + constructor + · intro h x hx + have : ContMDiffAt IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x := + (h x hx).contMDiffAt <| ha.mem_nhds hx + exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mp this).contMDiffWithinAt + · intro h x hx + have : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (e { proj := x, snd := s x }).2) x := + (h x hx).contMDiffAt <| ha.mem_nhds hx + exact ((contMDiffAt_section_of_mem_baseSet (ha' hx)).mpr this).contMDiffWithinAt + +/-- For any trivialization `e`, the smoothness of a `C^n` section on `e.baseSet` +can be determined using `e`. -/ +theorem contMDiffOn_section_of_mem_baseSet₀ {s : ∀ x, E x} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] : + ContMDiffOn IB (IB.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + ContMDiffOn IB 𝓘(𝕜, F) n (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := + contMDiffOn_section_of_mem_baseSet e.open_baseSet (subset_refl _) end /-! ### Core construction for `C^n` vector bundles -/ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index acaf30e18cd1e1..8d366fc2fc4195 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -596,7 +596,9 @@ lemma _root_.contMDiff_section_of_smul_smoothBumpFunction' [T2Space M] [IsManifo -- apply contMDiff_of_smul_smoothBumpFunction (s := s) (hn := hn) --?_ ?_ ?_ ?_ sorry -lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] {x : M} (σ₀ : V x) : +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by letI t := trivializationAt F V x letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 1891b2dc93c4b1..9e99dbe8236f23 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -96,7 +96,7 @@ noncomputable def localFrame -- TODO: understand why this isn’t already a simp lemma attribute [simp] Trivialization.apply_mk_symm -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in /-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_localFrame_baseSet @@ -109,7 +109,7 @@ lemma contMDiffOn_localFrame_baseSet intro y hy simp [localFrame, hy, localFrame_toBasis_at] -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in lemma _root_.contMDiffAt_localFrame_of_mem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) {x : M} (hx : x ∈ e.baseSet) : @@ -234,12 +234,12 @@ end Basis variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in /-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} + {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) (i : ι) : ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. @@ -256,8 +256,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 -- step 2: `s` read in trivialization `e` is `C^k` have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by - rw [contMDiffAt_section_of_mem_baseSet hxe] at hs - exact hs + exact contMDiffAt_section_of_mem_baseSet hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i let basl : F →ₗ[𝕜] 𝕜 := { @@ -273,11 +272,11 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt exact hbas.comp x h₁ -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in /-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) - {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} + {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} [ContMDiffVectorBundle k F V I] (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := @@ -288,7 +287,7 @@ omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in /-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ @@ -297,7 +296,8 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` at `x ∈ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {x' : M} (hx : x' ∈ e.baseSet) : + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] + {x' : M} (hx : x' ∈ e.baseSet) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ ∀ i, ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x' := by refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ @@ -315,8 +315,8 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} - (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] + {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := by refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ @@ -335,7 +335,7 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} : + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] @@ -536,7 +536,7 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : variable (F) in omit [IsManifold I 0 M] in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - {x : M} (hx : x ∈ e.baseSet) (v : V x) : + {x : M} (hx : x ∈ e.baseSet) (v : V x) [ContMDiffVectorBundle ∞ F V I] : ContMDiffOn I (I.prod 𝓘(𝕜, F)) ∞ (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are From 53691b16960b6da2439854d5af0d5b7d59afbbe9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 21:17:28 +0200 Subject: [PATCH 121/601] fix(SmoothSection): correct hypotheses for contMDiffFoo_finsum_section The previous lemmas were correct, but too strong (and not what I meant). --- .../Manifold/VectorBundle/LocalFrame.lean | 4 ++-- .../Manifold/VectorBundle/SmoothSection.lean | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 9e99dbe8236f23..8bf3c4b5ebc5a3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -306,7 +306,7 @@ lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C contMDiffAt_smul_section (hi i) (contMDiffAt_localFrame_of_mem k e b i hx) have almost : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := - contMDiffAt_finsum_section fun i ↦ this i + contMDiffAt_finsum_section fun i _ ↦ this i apply almost.congr_of_eventuallyEq ?_ obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] @@ -325,7 +325,7 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C contMDiffOn_smul_section (hi i) ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := - contMDiffOn_finsum_section fun i ↦ this i + contMDiffOn_finsum_section fun i _ ↦ this i apply almost.congr intro y hy congr diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 237038167a2bf2..ec8f64e79b4a3f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -180,30 +180,34 @@ lemma contMDiff_smul_const_section fun x₀ ↦ contMDiffAt_smul_const_section (hs x₀) lemma contMDiffWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} - (hs : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : + (hs : ∀ i ∈ s, + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by classical induction s using Finset.induction_on with | empty => simpa only [Finset.sum_empty] using contMDiffWithinAt_zeroSection .. - | insert i s hi h => simpa [Finset.sum_insert hi] using contMDiffWithinAt_add_section (hs i) h + | insert i s hi h => + simp only [Finset.sum_insert hi] + apply contMDiffWithinAt_add_section (hs _ (s.mem_insert_self i)) + exact h fun i a ↦ hs _ (s.mem_insert_of_mem a) lemma contMDiffAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} {x₀ : M} - (hs : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : + (hs : ∀ i ∈ s, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by simp_rw [← contMDiffWithinAt_univ] at hs ⊢ exact contMDiffWithinAt_finsum_section hs lemma contMDiffOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} - (hs : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : + (hs : ∀ i ∈ s, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := - fun x₀ hx₀ ↦ contMDiffWithinAt_finsum_section fun i ↦ hs i x₀ hx₀ + fun x₀ hx₀ ↦ contMDiffWithinAt_finsum_section fun i hi ↦ hs i hi x₀ hx₀ lemma contMDiff_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : M) → V x} - (hs : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : + (hs : ∀ i ∈ s, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := - fun x₀ ↦ contMDiffAt_finsum_section fun i ↦ (hs i) x₀ + fun x₀ ↦ contMDiffAt_finsum_section fun i hi ↦ (hs i hi) x₀ end operations From 1a402005f9d04817d8f47ee123195a6103c4c99c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 1 Jul 2025 20:00:44 +0200 Subject: [PATCH 122/601] WIP: finite convex combinations of covariant derivatives Define a finite sum of covariant derivatives (some proofs are still sorried) and prove it remains C^k regular. --- .../VectorBundle/CovariantDerivative.lean | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 8d366fc2fc4195..dc775d69ab9797 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -258,13 +258,55 @@ def convexCombination (cov cov' : CovariantDerivative I F V) (f : M → 𝕜) : addσ X σ σ' x hσ hσ' := by simp [cov.addσ X σ σ' x hσ hσ', cov'.addσ X σ σ' x hσ hσ'] module - smul_const_σ X {σ x} /-hσ-/ := by + smul_const_σ X {σ a} /-hσ-/ := by simp [cov.smul_const_σ, cov'.smul_const_σ] module leibniz X σ f x hσ hf := by simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] module +/-- A finite convex combination of covariant derivatives is a covariant derivative. -/ +def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] + (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : + CovariantDerivative I F V where + toFun X t := ∑ i ∈ s, (f i) • (cov i) X t + addX X X' σ := by + rw [← Finset.sum_add_distrib] + congr + ext i + simp [(cov i).addX] + smulX X σ g := by + rw [Finset.smul_sum] + congr + ext i + simp [(cov i).smulX] + module + addσ X σ σ' x hσ hσ' := by + -- XXX: is this nicer using induction? + classical + induction s using Finset.induction with + | empty => simp + | insert a s has h => + simp [Finset.sum_insert has] + sorry + smul_const_σ X {σ a} /-hσ-/ := by + rw [Finset.smul_sum] + congr + ext i x + simp [(cov i).smul_const_σ] + module + leibniz X σ g x hσ hf := by + calc (∑ i ∈ s, f i • (cov i) X (g • σ)) x + _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := sorry -- rewrite using (cov i).leibniz + _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := by + rw [Finset.sum_add_distrib] + simp; sorry + _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x := + -- use hf and pull out g... + sorry + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ @@ -277,7 +319,26 @@ lemma convexCombination_isRegular (cov cov' : CovariantDerivative I F V) {f : M · exact contMDiff_smul_section hf <| hcov.regularity X σ hX · exact contMDiff_smul_section (contMDiff_const.sub hf) <| hcov'.regularity X σ hX --- Future: prove finsum version of this, and one with a locally finite sum +omit [IsManifold I 0 M] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +/-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ +lemma convexCombination'_isRegular {ι : Type*} {s : Finset ι} [Nonempty s] + (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} + (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) + (hcov : ∀ i ∈ s, IsCkConnection (cov i) n) : + IsCkConnection (convexCombination' cov hf) n where + regularity X σ hX /-hσ-/ := by + unfold convexCombination' + dsimp + have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n + fun x ↦ TotalSpace.mk' F x ((f i • (cov i) X σ) x) := by + apply contMDiff_smul_section (hf' i hi) + exact IsCkConnection.regularity X σ hX (self := hcov i hi) + simp only [Finset.sum_apply, Pi.smul_apply'] + exact contMDiff_finsum_section (t := fun i ↦ f i • (cov i) X σ) ms + +-- Future: prove a version with a locally finite sum, and deduce that C^k connections always +-- exist (using a partition of unity argument) variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] From 2e312e3d5db196cbf0f9fa81229f3410c7ee8b83 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 2 Jul 2025 13:31:56 +0200 Subject: [PATCH 123/601] Remove a sorry --- Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index dc775d69ab9797..a730daff915c0a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -756,7 +756,7 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi congr -- TODO: this is almost the item we want, but not quite! not sure where the mismatch comes from let asdf := cov.smulX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) - sorry + simpa using congr_fun asdf x @[simps!] noncomputable def endomorph_of_trivial_aux''' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] From 6120779240ad0f0668e0c65025ee9d8f73ec9870 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 2 Jul 2025 13:48:49 +0200 Subject: [PATCH 124/601] chore: clean up --- .../Manifold/VectorBundle/CovariantDerivative.lean | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index a730daff915c0a..31a038c5538996 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -747,16 +747,14 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi module map_smul' t X := by ext Z - simp - + simp only [endomorph_of_trivial_aux'_apply, extend_smul, map_smul, RingHom.id_apply, + ContinuousLinearMap.coe_smul', Pi.smul_apply] -- The following lines should ideally mold into the simp call above. trans t • (cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) x) - t • (fderiv ℝ (extend 𝓘(ℝ, E) E' Z (x := x)) x) X swap; · module - congr - -- TODO: this is almost the item we want, but not quite! not sure where the mismatch comes from - let asdf := cov.smulX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) - simpa using congr_fun asdf x + let h := cov.smulX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) + simpa using congr_fun h x @[simps!] noncomputable def endomorph_of_trivial_aux''' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] From 75aa3d118c4636ba879179cb56487bfbfb4fff6c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 2 Jul 2025 13:52:26 +0200 Subject: [PATCH 125/601] chore: make some arguments to differenceAux_tensorial implicit --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 31a038c5538996..fa963b3edbebc0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -556,7 +556,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] - (X X' : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x₀ : M) + {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x₀) (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x₀) (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) : @@ -784,8 +784,7 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by -- Do not unfold differenceAux: we use the tensoriality of differenceAux. rw [difference] - -- Should x be implicit? Or X, X', σ, σ' perhaps? - exact differenceAux_tensorial cov (trivial E E') _ _ _ _ _ hσ hσ' + exact differenceAux_tensorial cov (trivial E E') hσ hσ' (extend_apply_self (X x)).symm (extend_apply_self (σ x)).symm have h₂ : cov.difference (trivial E E') x (X x) (σ x) = cov (extend 𝓘(ℝ, E) E (X x)) (extend 𝓘(ℝ, E) E' (σ x)) x From 0d110313860b18571b0d51db780aa3b806d086c5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 2 Jul 2025 14:08:40 +0200 Subject: [PATCH 126/601] fix: correct classification of connections on the trivial bundle The map from covariant derivative -> zero-order term -> covariant derivative does not round-trip perfectly: if sigma is not differentiable at x, the initial and final covariant derivative at x may be different. This is not mathematically meaningful in practice. Explain this issue and adjust the classification statement accordingly. --- .../VectorBundle/CovariantDerivative.lean | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index fa963b3edbebc0..961f7d53cecd6a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -764,28 +764,34 @@ noncomputable def endomorph_of_trivial_aux''' [FiniteDimensional ℝ E] [FiniteD /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term + +For technical reasons, this is only almost true: the left hand sides agree for all `X`, `σ` and `x` +such that `σ` is differentiable at `x`. (Since the literature mostly considers smooth connections, +this is not an issue for mathematical practice at all.) +The reason is because of the construction of a covariant derivative from a zero-order term `A`: +`of_endomorphism A X₀ σ₀` is defined by turning the tangent vectors `X₀` and `σ₀` at `x` +into vector fields near `x` --- which are smooth by construction. Thus, if `σ` is not differentiable +at `x`, `of_endomorphism A` at `x` uses a smooth extension of `σ x`, with different results. -/ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : - ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), cov = .of_endomorphism A := by + ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), + ∀ X : (x : E) → TangentSpace 𝓘(ℝ, E) x, ∀ σ : (x : E) → Trivial E E' x, ∀ x : E, + MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) + (fun x' ↦ TotalSpace.mk' E' x' (σ x')) x → + cov X σ x = (CovariantDerivative.of_endomorphism A) X σ x := by use cov.endomorph_of_trivial_aux''' - ext X σ x + intro X σ x hσ -- TODO: this is unfolding too much; need to fix this manually below... -- think about a better design that actually works... simp only [of_endomorphism_toFun, endomorph_of_trivial_aux'''_apply_apply] - - -- TODO: this case has a gap; if hσ is false, currently hσ' is still true... - have hσ : MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) - (fun x' ↦ TotalSpace.mk' E' x' (σ x')) x := sorry - have hσ' : MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) - (fun x' ↦ TotalSpace.mk' E' x' ((extend 𝓘(ℝ, E) E' (σ x)) x')) x := sorry - rw [← CovariantDerivative.trivial_toFun] have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by -- Do not unfold differenceAux: we use the tensoriality of differenceAux. rw [difference] - exact differenceAux_tensorial cov (trivial E E') hσ hσ' + apply differenceAux_tensorial cov (trivial E E') hσ ?_ (extend_apply_self (X x)).symm (extend_apply_self (σ x)).symm + exact ((contMDiff_extend _).contMDiffAt).mdifferentiableAt (by norm_num) have h₂ : cov.difference (trivial E E') x (X x) (σ x) = cov (extend 𝓘(ℝ, E) E (X x)) (extend 𝓘(ℝ, E) E' (σ x)) x - (fderiv ℝ (extend 𝓘(ℝ, E) E' (σ x) (x := x)) x) (X x) := by From 67c75989b2e6fb18e524479d939d44668c0ccc7a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 2 Jul 2025 14:40:05 +0200 Subject: [PATCH 127/601] Fix warning; the fderiv sorry needs more API (but not too much) --- .../VectorBundle/CovariantDerivative.lean | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 961f7d53cecd6a..20f2aaa3d4644d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -298,7 +298,8 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] leibniz X σ g x hσ hf := by calc (∑ i ∈ s, f i • (cov i) X (g • σ)) x _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x - + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := sorry -- rewrite using (cov i).leibniz + + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := + sorry -- rewrite using (cov i).leibniz _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := by rw [Finset.sum_add_distrib] @@ -361,14 +362,32 @@ noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' simp [this, bar] rfl -open scoped Manifold +-- TODO: does it make sense to speak of analytic connections? if so, change the definition of +-- regularity and use ∞ from `open scoped ContDiff` instead. /-- The trivial connection on the trivial bundle is smooth -/ --- TODO: fix parsing error with putting exponent ∞ -lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') 42 where +lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') (⊤ : ℕ∞) where regularity X σ hX /-hσ-/ := by - simp [trivial] - sorry -- where's the relevant lemma in the library? + -- except for locla trivialisations, contDiff_infty_iff_fderiv covers this well + simp only [trivial] + -- use a local trivialisation + intro x + specialize hX x + -- TODO: use contMDiffOn instead, to get something like + -- have hX' : ContMDiffOn 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (∞ + 1) + -- (fun x ↦ TotalSpace.mk' E' x (σ x)) (trivializationAt x).baseSet := hX.contMDiffOn + -- then want a version contMDiffOn_totalSpace + rw [contMDiffAt_totalSpace] at hX ⊢ + simp only [Trivial.fiberBundle_trivializationAt', Trivial.trivialization_apply] + refine ⟨contMDiff_id _, ?_⟩ + obtain ⟨h₁, h₂⟩ := hX + -- ... hopefully telling me + -- have h₂scifi : ContMDiffOn 𝓘(𝕜, E) 𝓘(𝕜, E') ∞ + -- (fun x ↦ σ x) (trivializationAt _).baseSet_ := sorry + simp at h₂ + -- now use ContMDiffOn.congr and contDiff_infty_iff_fderiv, + -- or perhaps a contMDiffOn version of this lemma? + sorry open scoped Classical in @[simps] From e9e323b406ddb2ffa63fe128e5f853fd65bbe0f8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 2 Jul 2025 16:03:22 +0200 Subject: [PATCH 128/601] Define the torsion of a connection --- .../VectorBundle/CovariantDerivative.lean | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 20f2aaa3d4644d..80ff38e490d605 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -10,6 +10,7 @@ import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +import Mathlib.Geometry.Manifold.VectorField.LieBracket /-! # Covariant derivatives @@ -820,6 +821,53 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] end classification +section torsion + +variable [h : IsManifold I ∞ M] + +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} + +omit [FiniteDimensional ℝ E] + +variable (cov) in +noncomputable def torsion : + (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := + fun X Y ↦ cov X Y - cov Y X - VectorField.mlieBracket I X Y + +omit [FiniteDimensional ℝ E] in +lemma torsion_self (X : Π x : M, TangentSpace I x) : torsion cov X X = 0 := by + simp [torsion] + +omit [FiniteDimensional ℝ E] in +lemma torsion_antisymm (X Y : Π x : M, TangentSpace I x) : torsion cov X Y = - torsion cov Y X := by + simp only [torsion] + rw [VectorField.mlieBracket_swap] + module + +@[simp] +lemma torsion_zero (X : Π x : M, TangentSpace I x) : torsion cov 0 X = 0 := by + ext x + simp [torsion] + sorry -- missing lemma? + +@[simp] +lemma torsion_zero' (X : Π x : M, TangentSpace I x) : torsion cov X 0 = 0 := by + rw [torsion_antisymm, torsion_zero]; simp + +-- next steps: torsion_add, torsion_smul (in the left and right arguments) +-- conclude: torsion is tensorial + +variable (cov) in +/-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ +def IsTorsionFree : Prop := torsion cov = 0 + +lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] + +-- lemma: the trivial connection is torsion free + +end torsion + end real end CovariantDerivative From 49782900aa03ef42c264ffbdab762a3b9f6dc659 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 2 Jul 2025 22:46:34 +0200 Subject: [PATCH 129/601] Progress with basic properties of torsion --- .../VectorBundle/CovariantDerivative.lean | 84 +++++++++++++++++-- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 80ff38e490d605..ea6c34ee6ca95e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -835,28 +835,83 @@ noncomputable def torsion : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := fun X Y ↦ cov X Y - cov Y X - VectorField.mlieBracket I X Y -omit [FiniteDimensional ℝ E] in -lemma torsion_self (X : Π x : M, TangentSpace I x) : torsion cov X X = 0 := by +variable {X X' Y : Π x : M, TangentSpace I x} + +variable (X) in +lemma torsion_self : torsion cov X X = 0 := by simp [torsion] -omit [FiniteDimensional ℝ E] in -lemma torsion_antisymm (X Y : Π x : M, TangentSpace I x) : torsion cov X Y = - torsion cov Y X := by +variable (X Y) in +lemma torsion_antisymm : torsion cov X Y = - torsion cov Y X := by simp only [torsion] rw [VectorField.mlieBracket_swap] module +variable (X) in @[simp] -lemma torsion_zero (X : Π x : M, TangentSpace I x) : torsion cov 0 X = 0 := by +lemma torsion_zero : torsion cov 0 X = 0 := by ext x simp [torsion] sorry -- missing lemma? +variable (X) in @[simp] -lemma torsion_zero' (X : Π x : M, TangentSpace I x) : torsion cov X 0 = 0 := by - rw [torsion_antisymm, torsion_zero]; simp +lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp + +variable (Y) in +lemma torsion_add_left [CompleteSpace E] + (hX : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X x))) + (hX' : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X' x))) : + torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by + ext x + simp [torsion, cov.addX] + rw [cov.addσ _ X X' _ (hX x) (hX' x), VectorField.mlieBracket_add_left (hX x) (hX' x)] + module --- next steps: torsion_add, torsion_smul (in the left and right arguments) --- conclude: torsion is tensorial +lemma torsion_add_right [CompleteSpace E] + (hX : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X x))) + (hX' : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X' x))) : + torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by + rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module + +-- TODO: prove (for sections in any vector bundle); follow-up to 24932 +lemma _root_.VectorField.mlieBracket_fun_smul_left' {f : M → ℝ} (hf : MDifferentiableAt I 𝓘(ℝ) f x) + {V W : Π x : M, TangentSpace I x} + (hV : MDifferentiableAt I I.tangent (fun x ↦ TotalSpace.mk' E x (V x)) x) : + VectorField.mlieBracket I (fun y ↦ f y • V y) W x = + - (mfderiv I 𝓘(ℝ) f x) (W x) • (V x) + (f x) • VectorField.mlieBracket I V W x := by + sorry + +-- TODO: prove (for sections in any vector bundle); follow-up to 24932 +lemma _root_.VectorField.mlieBracket_smul_left' {f : M → ℝ} (hf : MDifferentiableAt I 𝓘(ℝ) f x) + {V W : Π x : M, TangentSpace I x} + (hV : MDifferentiableAt I I.tangent (fun x ↦ TotalSpace.mk' E x (V x)) x) : + VectorField.mlieBracket I (f • V) W x = + - (mfderiv I 𝓘(ℝ) f x) (W x) • (V x) + (f x) • VectorField.mlieBracket I V W x := by + sorry + +variable (Y) in +lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable I 𝓘(ℝ) f) + (hX : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X x))) : + torsion cov (f • X) Y = f • torsion cov X Y := by + simp only [torsion, cov.smulX] + ext x + simp [cov.leibniz Y X f x (hX x) (hf x)] + rw [VectorField.mlieBracket_smul_left' (hf x) (hX x)] + have missing : (bar (f x)) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Y x)) • X x - + -(mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) • X x = 0 := by + set A := mfderiv I 𝓘(ℝ, ℝ) f x (Y x) + set B := X x + sorry -- should be a lemma about `bar` now... + sorry -- should be missing and `module` now + +variable (X) in +lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable I 𝓘(ℝ) f) + (hY : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (Y x))) : + torsion cov X (f • Y) = f • torsion cov X Y := by + rw [torsion_antisymm, torsion_smul_left X hf hY, torsion_antisymm X]; module + +-- finally, conclude that torsion is tensorial variable (cov) in /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ @@ -866,6 +921,17 @@ lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTo -- lemma: the trivial connection is torsion free +-- API for the trivial bundle (does some of this exist already?) +-- there is a single trivialisation, whose baseSet is univ +-- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, +-- w.r.t. to this trivialisation +-- add lemmas: globalFrame is contMDiff globally + +-- proof of above lemma: write sections s and t in the global frame above +-- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) +-- compute: their Lie bracket is zero (intuitively, as their flows commute) +-- compute: the other two terms cancel, done + end torsion end real From 72e4cc4a90f9e5f31a5f0b98c76875bf4045efdb Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 3 Jul 2025 11:40:41 +0200 Subject: [PATCH 130/601] Some more differentiability --- .../VectorBundle/CovariantDerivative.lean | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ea6c34ee6ca95e..8b92a821716bb2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -691,6 +691,12 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M apply _root_.contMDiff_section_of_smul_smoothBumpFunction _ ?_ t.open_baseSet hψ.1 le_rfl apply contMDiffOn_localExtensionOn _ hx +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := + contMDiff_extend σ₀ |>.mdifferentiable (by simp) + /-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] @@ -723,6 +729,15 @@ section classification variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] +theorem contDiff_extend {E : Type*} + [NormedAddCommGroup E] [NormedSpace ℝ E] {E' : Type*} [NormedAddCommGroup E'] + [NormedSpace ℝ E'] [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (x : E) (y : E') : + ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by + rw [contDiff_iff_contDiffAt] + intro x' + rw [← contMDiffAt_iff_contDiffAt] + simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') y x' + @[simps] noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x X : E) : E' →ₗ[ℝ] E' where @@ -730,13 +745,7 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime map_add' y y' := by have A : fderiv ℝ ((extend 𝓘(ℝ, E) E' y (x := x)) + extend 𝓘(ℝ, E) E' y' (x := x)) x = fderiv ℝ (extend 𝓘(ℝ, E) E' y (x := x)) x + fderiv ℝ (extend 𝓘(ℝ, E) E' y' (x := x)) x := by - rw [fderiv_add] - · sorry -- like the sorry below! - · apply Differentiable.differentiableAt - rw [← mdifferentiable_iff_differentiable] - apply ContMDiff.mdifferentiable (n := 1) (hn := by norm_num) - sorry -- is contMDiff_extend, except that now we care about - -- the outcome of post-composing with the projection from Trivial E E' to E'... + rw [fderiv_add] <;> exact (contDiff_extend x _).contDiffAt.differentiableAt (by simp) have B : cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + From c438d3617d7ab9d72ca09532b49e56e6cd8b9e40 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 3 Jul 2025 14:10:12 +0200 Subject: [PATCH 131/601] Remove one torsion sorry --- .../Manifold/VectorBundle/CovariantDerivative.lean | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 8b92a821716bb2..e6b9d4e449875b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -907,12 +907,8 @@ lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable ext x simp [cov.leibniz Y X f x (hX x) (hf x)] rw [VectorField.mlieBracket_smul_left' (hf x) (hX x)] - have missing : (bar (f x)) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Y x)) • X x - - -(mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) • X x = 0 := by - set A := mfderiv I 𝓘(ℝ, ℝ) f x (Y x) - set B := X x - sorry -- should be a lemma about `bar` now... - sorry -- should be missing and `module` now + simp [bar, smul_sub] + abel variable (X) in lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable I 𝓘(ℝ) f) From 5e6f47c5e87866fc411ea6db32e3938072a7ad84 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 3 Jul 2025 17:25:38 +0200 Subject: [PATCH 132/601] Clean up one lemma --- .../Manifold/VectorBundle/CovariantDerivative.lean | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e6b9d4e449875b..966ccd4cdb20f3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -54,16 +54,11 @@ def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] --- TODO: cleanup @[simp] theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ DifferentiableAt 𝕜 σ e := by - rw [← mdifferentiableWithinAt_univ, mdifferentiableWithinAt_totalSpace, - mdifferentiableWithinAt_univ, mdifferentiableWithinAt_univ] - change MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E) id e ∧ MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') σ e ↔ - DifferentiableAt 𝕜 σ e - simp [mdifferentiableAt_id, mdifferentiableAt_iff_differentiableAt] + simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] attribute [simp] mdifferentiableAt_iff_differentiableAt From dea07e954729d4b608be9863e97f0acc3bb46025 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 3 Jul 2025 18:27:07 +0200 Subject: [PATCH 133/601] Start horizontal subbundle stub --- .../VectorBundle/CovariantDerivative.lean | 32 ++++++++++++++++++- .../VectorBundle/MDifferentiable.lean | 2 ++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 966ccd4cdb20f3..12a57f330fb4b1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -825,6 +825,36 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] end classification +section horiz + +def proj (cov : CovariantDerivative I F V) (e : TotalSpace F V) : + TangentSpace (I.prod 𝓘(ℝ, F)) e →L[ℝ] V e.proj := by + sorry + +noncomputable def horiz (cov : CovariantDerivative I F V) (e : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) e) := + LinearMap.ker (cov.proj e) + +noncomputable def _root_.Bundle.vert (e : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) e) := + LinearMap.ker (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj e) + +lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (e : TotalSpace F V) : + IsCompl (cov.horiz e) (vert e) := by + sorry + +variable [IsManifold I 1 M] +variable {cov : CovariantDerivative I F V} + +lemma proj_mderiv {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) + (hX : MDifferentiableAt I I.tangent (fun x ↦ TotalSpace.mk' E x (X x)) x) + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) : + cov X σ x = cov.proj (σ x) + (mfderiv I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x (X x)) := by + sorry + +end horiz + section torsion variable [h : IsManifold I ∞ M] @@ -935,7 +965,7 @@ lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTo end torsion end real - +#where end CovariantDerivative end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 9aff23c4192661..76e95f4f72d661 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -82,6 +82,8 @@ theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] +-- TODO: compare with ContMDiffWithinAt.change_section_trivialization + lemma MDifferentiableWithinAt.coordChange {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e'] From 48506c8379d006a857603cebed70a0563d4106e7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 01:29:24 +0200 Subject: [PATCH 134/601] WIP: Lie bracket with zero is zero (using the junk value of fderiv --- Mathlib/Analysis/Calculus/VectorField.lean | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Mathlib/Analysis/Calculus/VectorField.lean b/Mathlib/Analysis/Calculus/VectorField.lean index 7def050f539bd3..dec1a917c294dd 100644 --- a/Mathlib/Analysis/Calculus/VectorField.lean +++ b/Mathlib/Analysis/Calculus/VectorField.lean @@ -143,6 +143,22 @@ lemma lieBracketWithin_swap : lieBracketWithin 𝕜 V W s = - lieBracketWithin lemma lieBracket_swap : lieBracket 𝕜 V W x = - lieBracket 𝕜 W V x := by simp [lieBracket] +-- TODO: prove within version of this? + +/-- We have `[0, W] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. -/ +@[simp] +lemma lieBracket_zero_left : lieBracket 𝕜 0 W x = 0 := by + by_cases hW : DifferentiableAt 𝕜 W x + · have := lieBracket_add_left (W := W) (differentiableAt_zero x) hW + simp_all + · simp [lieBracket] + +/-- We have `[W, 0] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. -/ +@[simp] +lemma lieBracket_zero_right : lieBracket 𝕜 W 0 x = 0 := by simp [lieBracket] + @[simp] lemma lieBracketWithin_self : lieBracketWithin 𝕜 V V s = 0 := by ext x; simp [lieBracketWithin] From 0cbc7cccac8d35b836311f2920b6ce2dc2c168d0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 10:20:48 +0200 Subject: [PATCH 135/601] Remove noisy output --- Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 12a57f330fb4b1..c6790130466347 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -965,7 +965,7 @@ lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTo end torsion end real -#where + end CovariantDerivative end From c0e9c9b0bcda608871e0902bd263bac181fbe2bc Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 14:10:52 +0200 Subject: [PATCH 136/601] Revert "WIP: Lie bracket with zero is zero (using the junk value of fderiv" This reverts commit 48506c8379d006a857603cebed70a0563d4106e7. --- Mathlib/Analysis/Calculus/VectorField.lean | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Mathlib/Analysis/Calculus/VectorField.lean b/Mathlib/Analysis/Calculus/VectorField.lean index dec1a917c294dd..7def050f539bd3 100644 --- a/Mathlib/Analysis/Calculus/VectorField.lean +++ b/Mathlib/Analysis/Calculus/VectorField.lean @@ -143,22 +143,6 @@ lemma lieBracketWithin_swap : lieBracketWithin 𝕜 V W s = - lieBracketWithin lemma lieBracket_swap : lieBracket 𝕜 V W x = - lieBracket 𝕜 W V x := by simp [lieBracket] --- TODO: prove within version of this? - -/-- We have `[0, W] = 0` for all vector fields `W`: this depends on the junk value 0 -if `W` is not differentiable. -/ -@[simp] -lemma lieBracket_zero_left : lieBracket 𝕜 0 W x = 0 := by - by_cases hW : DifferentiableAt 𝕜 W x - · have := lieBracket_add_left (W := W) (differentiableAt_zero x) hW - simp_all - · simp [lieBracket] - -/-- We have `[W, 0] = 0` for all vector fields `W`: this depends on the junk value 0 -if `W` is not differentiable. -/ -@[simp] -lemma lieBracket_zero_right : lieBracket 𝕜 W 0 x = 0 := by simp [lieBracket] - @[simp] lemma lieBracketWithin_self : lieBracketWithin 𝕜 V V s = 0 := by ext x; simp [lieBracketWithin] From cd339acf877f3415359dbb8c368766022f41aaac Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 13:28:20 +0200 Subject: [PATCH 137/601] feat: lieBracket with zero is zero --- Mathlib/Analysis/Calculus/VectorField.lean | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mathlib/Analysis/Calculus/VectorField.lean b/Mathlib/Analysis/Calculus/VectorField.lean index 7def050f539bd3..38027b4ab926ce 100644 --- a/Mathlib/Analysis/Calculus/VectorField.lean +++ b/Mathlib/Analysis/Calculus/VectorField.lean @@ -122,6 +122,26 @@ lemma lieBracket_add_left (hV : DifferentiableAt 𝕜 V x) (hV₁ : Differentiab rw [fderiv_add hV hV₁, ContinuousLinearMap.add_apply] abel +/-- We have `[0, W] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. Version within a set. -/ +@[simp] +lemma lieBracketWithin_zero_left : lieBracketWithin 𝕜 0 W s x = 0 := by simp [lieBracketWithin] + +/-- We have `[W, 0] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. Version within a set. -/ +@[simp] +lemma lieBracketWithin_zero_right : lieBracketWithin 𝕜 W 0 s x = 0 := by simp [lieBracketWithin] + +/-- We have `[0, W] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. -/ +@[simp] +lemma lieBracket_zero_left : lieBracket 𝕜 0 W x = 0 := by simp [lieBracket] + +/-- We have `[W, 0] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. -/ +@[simp] +lemma lieBracket_zero_right : lieBracket 𝕜 W 0 x = 0 := by simp [lieBracket] + lemma lieBracketWithin_add_right (hW : DifferentiableWithinAt 𝕜 W s x) (hW₁ : DifferentiableWithinAt 𝕜 W₁ s x) (hs : UniqueDiffWithinAt 𝕜 s x) : lieBracketWithin 𝕜 V (W + W₁) s x = From ae91e4dd9a5b68f53c7ac6d6a96616a7e9a0b51a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 13:51:43 +0200 Subject: [PATCH 138/601] feat: mpullback(Within)_zero --- Mathlib/Geometry/Manifold/VectorField/Pullback.lean | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean index 453e36220aa3bb..a00fc0f0f7fc96 100644 --- a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean +++ b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean @@ -125,6 +125,11 @@ lemma mpullbackWithin_add : ext x simp [mpullbackWithin_apply] +@[simp] +lemma mpullbackWithin_zero : mpullbackWithin I I' f 0 s = 0 := by + have aux := mpullbackWithin_add (f := f) (s := s) (I := I) (I' := I') (V := 0) (V₁ := 0) + simp_all + lemma mpullbackWithin_neg_apply : mpullbackWithin I I' f (-V) s x = - mpullbackWithin I I' f V s x := by simp [mpullbackWithin_apply] @@ -172,6 +177,9 @@ lemma mpullback_neg : ext x simp [mpullback_apply, mpullbackWithin_apply] +@[simp] +lemma mpullback_zero : mpullback I I' f 0 = 0 := by simp [← mpullbackWithin_univ] + lemma mpullbackWithin_eq_pullbackWithin {f : E → E'} {V : E' → E'} {s : Set E} : mpullbackWithin 𝓘(𝕜, E) 𝓘(𝕜, E') f V s = pullbackWithin 𝕜 f V s := by ext x From e3fbca02bac076c98b719ea1fef9e28a7ebe275a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 14:05:32 +0200 Subject: [PATCH 139/601] Manifold case --- .../Manifold/VectorField/LieBracket.lean | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index febe77c5473d1c..6f1cc43364347d 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -332,6 +332,38 @@ lemma mlieBracket_add_left simp only [← mlieBracketWithin_univ] at hV hV₁ ⊢ exact mlieBracketWithin_add_left hV hV₁ (uniqueMDiffWithinAt_univ _) +omit [IsManifold I 2 M] [CompleteSpace E] in +/-- We have `[0, W] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. Version within a set. -/ +@[simp] +lemma mlieBracketWithin_zero_left : mlieBracketWithin I 0 W s x = 0 := by + -- Need to help the simplifier find this. + have : lieBracketWithin 𝕜 0 (mpullbackWithin 𝓘(𝕜, E) I + ((chartAt H x).symm ∘ I.symm) W (range I)) + ((chartAt H x).symm ∘ I.symm ⁻¹' s ∩ range I) = 0 := by + ext x + apply lieBracketWithin_zero_left + simp [mlieBracketWithin, this] + +omit [IsManifold I 2 M] [CompleteSpace E] in +/-- We have `[W, 0] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. Version within a set. -/ +@[simp] +lemma mlieBracketWithin_zero_right : mlieBracketWithin I W 0 s x = 0 := by + rw [mlieBracketWithin_swap]; simp + +omit [IsManifold I 2 M] [CompleteSpace E] in +/-- We have `[0, W] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. -/ +@[simp] +lemma mlieBracket_zero_left : mlieBracket I 0 W x = 0 := by simp [← mlieBracketWithin_univ] + +omit [IsManifold I 2 M] [CompleteSpace E] in +/-- We have `[W, 0] = 0` for all vector fields `W`: this depends on the junk value 0 +if `W` is not differentiable. -/ +@[simp] +lemma mlieBracket_zero_right : mlieBracket I W 0 x = 0 := by simp [← mlieBracketWithin_univ] + lemma mlieBracketWithin_add_right (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) (hW₁ : MDifferentiableWithinAt I I.tangent (fun x ↦ (W₁ x : TangentBundle I M)) s x) From 4ec3b0f6048e877f88b821439d10d8c8da6ef72a Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 4 Jul 2025 19:09:30 +0200 Subject: [PATCH 140/601] Add experimental elaborators for geometry --- Mathlib.lean | 2 + Mathlib/Geometry/Manifold/Elaborators.lean | 324 +++++++++++++++++++++ Mathlib/Geometry/Manifold/Traces.lean | 16 + 3 files changed, 342 insertions(+) create mode 100644 Mathlib/Geometry/Manifold/Elaborators.lean create mode 100644 Mathlib/Geometry/Manifold/Traces.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8db14077209954..86a4471ec047e7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3681,6 +3681,7 @@ import Mathlib.Geometry.Manifold.ContMDiffMFDeriv import Mathlib.Geometry.Manifold.ContMDiffMap import Mathlib.Geometry.Manifold.DerivationBundle import Mathlib.Geometry.Manifold.Diffeomorph +import Mathlib.Geometry.Manifold.Elaborators import Mathlib.Geometry.Manifold.GroupLieAlgebra import Mathlib.Geometry.Manifold.Instances.Real import Mathlib.Geometry.Manifold.Instances.Sphere @@ -3720,6 +3721,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.VectorField.Pullback +import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.WhitneyEmbedding import Mathlib.Geometry.RingedSpace.Basic import Mathlib.Geometry.RingedSpace.LocallyRingedSpace diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean new file mode 100644 index 00000000000000..a8ad2baf32fa74 --- /dev/null +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -0,0 +1,324 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +import Mathlib.Geometry.Manifold.VectorBundle.Tangent +import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +import Mathlib.Geometry.Manifold.VectorField.LieBracket +import Mathlib.Geometry.Manifold.Traces + +/-! +# Elaborators for differential geometry + +TODO: add a more complete doc-string + +-/ + +open Bundle Filter Function Topology + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +section + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] + -- `V` vector bundle + +open Lean Meta Elab Tactic +open Mathlib.Tactic + +def _root_.Lean.Expr.getUniverse (e : Expr) : TermElabM (Level) := do + if let .sort (.succ u) ← inferType e >>= instantiateMVars then + return u + else + throwError m!"Could not find universe of {e}." + +@[match_pattern] def mkApp12 (f a b c d e g e₁ e₂ e₃ e₄ e₅ e₆ : Expr) := + mkApp6 (mkApp6 f a b c d e g) e₁ e₂ e₃ e₄ e₅ e₆ + +elab "T%" t:term : term => do + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE x base (mkApp3 (.const `Bundle.Trivial _) E E' _) _ => + trace[TotalSpaceMk] "Section of a trivial bundle" + if E == base then + return ← withLocalDecl x BinderInfo.default base fun x ↦ do + let body ← mkAppM ``Bundle.TotalSpace.mk' #[E', x, .app e x] + mkLambdaFVars #[x] body + | .forallE x base (mkApp12 (.const `TangentSpace _) _k _ E _ _ _H _ _I _M _ _ _x) _ => + trace[TotalSpaceMk] "Vector field" + return ← withLocalDecl x BinderInfo.default base fun x ↦ do + let body ← mkAppM ``Bundle.TotalSpace.mk' #[E, x, .app e x] + mkLambdaFVars #[x] body + | .forallE x base (.app V _) _ => + trace[TotalSpaceMk] "Section of a bundle as a dependent function" + for decl in ← getLocalHyps do + let decltype ← inferType decl >>= instantiateMVars + match decltype with + | mkApp7 (.const `FiberBundle _) _ F _ _ E _ _ => + if E == V then + return ← withLocalDecl x BinderInfo.default base fun x ↦ do + let body ← mkAppM ``Bundle.TotalSpace.mk' #[F, x, .app e x] + mkLambdaFVars #[x] body + | _ => pure () + | .forallE x src tgt _ => + trace[TotalSpaceMk] "Section of a trivial bundle as a non-dependent function" + let us ← src.getUniverse + let ut ← tgt.getUniverse + let triv_bundle := mkAppN (.const `Bundle.Trivial [us, ut]) #[src, tgt] + return ← withLocalDecl x BinderInfo.default src fun x ↦ do + let body := mkAppN (.const ``Bundle.TotalSpace.mk' [us, ut, ut]) + #[src, triv_bundle, tgt, x, .app e x] + mkLambdaFVars #[x] body + | _ => pure () + return e + +variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} + +/-- info: fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V -/ +#guard_msgs in +#check T% σ + +/-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% σ' + +/-- info: fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% s + +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + +/-- info: fun m ↦ TotalSpace.mk' E m (X m) : M → TotalSpace E (TangentSpace I) -/ +#guard_msgs in +#check T% X + +example : (fun m ↦ (X m : TangentBundle I M)) = (fun m ↦ TotalSpace.mk' E m (X m)) := rfl + +-- FIXME: better failure when trying to find a normedfield instance +def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do + trace[MDiffElab] m!"Searching a model for: {e}" + if let mkApp3 (.const `Bundle.TotalSpace _) _ F V := e then + if let mkApp12 (.const `TangentSpace _) _k _ _E _ _ _H _ I M _ _ _x := V then + trace[MDiffElab] m!"This is the total space of the tangent bundle of {M}" + let srcIT : Term ← PrettyPrinter.delab I + let resTerm : Term ← `(ModelWithCorners.prod $srcIT ModelWithCorners.tangent $srcIT) + let res ← Term.elabTerm resTerm none + trace[MDiffElab] m!"Found model: {res}" + return res + + trace[MDiffElab] m!"This is a total space with fiber {F}" + if let some (_src, srcI) := baseInfo then + let mut K : Expr := default + let mut normedSpaceInst : Expr := default + let mut Kok : Bool := false + for decl in ← getLocalHyps do + let decltype ← inferType decl >>= instantiateMVars + match decltype with + | mkApp4 (.const `NormedSpace _) K' E _ _ => + if E == F then + K := K' + trace[MDiffElab] m!"{F} is a normed field over {K}" + normedSpaceInst := decl + Kok := true + | _ => pure () + if Kok then break + unless Kok do throwError + m!"Couldn’t find a normed space structure on {F} in local context" + let kT : Term ← PrettyPrinter.delab K + let srcIT : Term ← PrettyPrinter.delab srcI + let FT : Term ← PrettyPrinter.delab F + let iTerm : Term ← `(ModelWithCorners.prod $srcIT 𝓘($kT, $FT)) + let I ← Term.elabTerm iTerm none + trace[MDiffElab] m!"Found model: {I}" + return I + + else + throwError "Having a TotalSpace as source is not yet supported" + let mut H : Expr := default + let mut Hok : Bool := false + let mut K : Expr := default + let mut normedSpaceInst : Expr := default + let mut Kok : Bool := false + for decl in ← getLocalHyps do + let decltype ← inferType decl >>= instantiateMVars + match decltype with + | mkApp4 (.const `ChartedSpace _) H' _ M _ => + if M == e then + H := H' + trace[MDiffElab] m!"H is: {H}" + Hok := true + | mkApp4 (.const `NormedSpace _) K' E _ _ => + if E == e then + K := K' + trace[MDiffElab] m!"Field is: {K}" + normedSpaceInst := decl + Kok := true + | _ => pure () + if Hok || Kok then break + if Kok then + let eT : Term ← PrettyPrinter.delab e + let eK : Term ← PrettyPrinter.delab K + let iTerm : Term ← `(𝓘($eK, $eT)) + let I ← Term.elabTerm iTerm none + trace[MDiffElab] m!"Found model: {I}" + return I + -- let uK ← K.getUniverse + -- let normedFieldK ← synthInstance (.app (.const `NontriviallyNormedField [uK]) K) + -- trace[MDiffElab] m!"NontriviallyNormedField instance is: {normedFieldK}" + -- let ue ← e.getUniverse + -- let normedGroupE ← synthInstance (.app (.const `NormedAddCommGroup [ue]) e) + -- trace[MDiffElab] m!"NormedAddCommGroup instance is: {normedGroupE}" + -- return mkAppN (.const `modelWithCornersSelf [uK, ue]) + -- #[K, normedFieldK, e, normedGroupE, normedSpaceInst] + else if Hok then + for decl in ← getLocalHyps do + let decltype ← inferType decl >>= instantiateMVars + match decltype with + | mkApp7 (.const `ModelWithCorners _) _ _ _ _ _ H' _ => + if H' == H then + trace[MDiffElab] m!"Found model: {decl}" + return decl + | _ => pure () + -- throwError m!"Couldn’t find models with corners with H = {H}" + else + trace[MDiffElab] m!"Hoping {e} is a normed field" + let eT : Term ← PrettyPrinter.delab e + let iTerm : Term ← `(𝓘($eT, $eT)) + let I ← Term.elabTerm iTerm none + trace[MDiffElab] m!"Found model: {I}" + return I + + throwError "Couldn’t find models with corners" + +elab:max "MDifferentiableAt%" t:term:arg : term => do + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] + | _ => throwError m!"Term {e} is not a function." + +elab:max "MDifferentiable%" t:term:arg : term => do + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] + | _ => throwError m!"Term {e} is not a function." + +elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do + let e ← Term.elabTerm t none + let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let ne ← Term.elabTerm nt wtn + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] + | _ => throwError m!"Term {e} is not a function." + +elab:max "ContMDiffAt%" nt:term:arg t:term:arg : term => do + let e ← Term.elabTerm t none + let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let ne ← Term.elabTerm nt wtn + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] + | _ => throwError m!"Term {e} is not a function." + +variable {EM' : Type*} [NormedAddCommGroup EM'] + [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + (f : M → M') (m : M) + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% X) + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% X) m + +/-- info: ContMDiff I (I.prod 𝓘(𝕜, E)) 1 fun m ↦ TotalSpace.mk' E m (X m) : Prop -/ +#guard_msgs in +#check ContMDiff% 1 (T% X) + +/-- info: ContMDiffAt I (I.prod 𝓘(𝕜, E)) 1 (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ +#guard_msgs in +#check ContMDiffAt% 1 (T% X) m + +/-- info: MDifferentiableAt I I' f : M → Prop -/ +#guard_msgs in +#check MDifferentiableAt% f + +/-- info: MDifferentiableAt I I' f m : Prop -/ +#guard_msgs in +#check MDifferentiableAt% f m + +variable (g : E → E') +-- set_option trace.MDiffElab true in + +/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') g : E → Prop -/ +#guard_msgs in +#check MDifferentiableAt% g + +variable (h : 𝕜 → E') + +/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) 𝓘(𝕜, E') h : 𝕜 → Prop -/ +#guard_msgs in +#check MDifferentiableAt% h + +variable (h' : M → 𝕜) + +/-- info: MDifferentiableAt I 𝓘(𝕜, 𝕜) h' : M → Prop -/ +#guard_msgs in +#check MDifferentiableAt% h' + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% σ) + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop +-/ +#guard_msgs in +#check MDifferentiableAt% (T% σ') + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a ↦ TotalSpace.mk' E' a (s a) : E → Prop +-/ +#guard_msgs in +#check MDifferentiableAt% (T% s) + +end diff --git a/Mathlib/Geometry/Manifold/Traces.lean b/Mathlib/Geometry/Manifold/Traces.lean new file mode 100644 index 00000000000000..fd93658d1c0db3 --- /dev/null +++ b/Mathlib/Geometry/Manifold/Traces.lean @@ -0,0 +1,16 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ + +import Lean +/-! +# Traces for differential geometry elaborators + +TODO: add a more complete doc-string + +-/ +open Lean +initialize registerTraceClass `TotalSpaceMk +initialize registerTraceClass `MDiffElab From 52a89f0da0f087d1b0f96927c11af8da23924fd8 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 4 Jul 2025 19:09:49 +0200 Subject: [PATCH 141/601] Use new elaborators in CovariantDerivative --- .../VectorBundle/CovariantDerivative.lean | 87 +++++++++---------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c6790130466347..a1cb70a3e5a091 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -11,6 +11,7 @@ import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket +import Mathlib.Geometry.Manifold.Elaborators /-! # Covariant derivatives @@ -56,7 +57,7 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @[simp] theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : - MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ x)) e ↔ + MDifferentiableAt% (T% σ) e ↔ DifferentiableAt 𝕜 σ e := by simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] @@ -86,9 +87,9 @@ variable {I F V x} in if one is differentiable at `x` then so is the other. Issue: EventuallyEq does not work for dependent functions. -/ lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ₁ : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ₁ : MDifferentiableAt% (T% σ) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := by + MDifferentiableAt% (T% σ') x := by apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ -- TODO: split off a lemma? apply Set.EqOn.eventuallyEq_of_mem _ hs @@ -102,8 +103,8 @@ variable {I F V x} in one is differentiable at `x` iff the other is. -/ lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ : ∀ x ∈ s, σ x = σ' x) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x ↔ - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x := + MDifferentiableAt% (T% σ) x ↔ + MDifferentiableAt% (T% σ') x := ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ @@ -175,12 +176,12 @@ structure CovariantDerivative where smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜), toFun (f • X) σ = f • toFun X σ addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x : M), - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x - → MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x + MDifferentiableAt% (T% σ) x + → MDifferentiableAt% (T% σ') x → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x - → MDifferentiableAt I 𝓘(𝕜) f x + MDifferentiableAt% (T% σ) x + → MDifferentiableAt% f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) f x (X x)) • σ x smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), toFun X (a • σ) = a • toFun X σ @@ -193,10 +194,10 @@ This is a class so typeclass inference can deduce this automatically. -/ class IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) where regularity : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x), - ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (fun x ↦ TotalSpace.mk' F x (σ x)) → + ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (T% σ) → -- TODO: this condition does not typecheck! -- ContMDiff I I.tangent k (fun x ↦ (X x : TangentBundle I M)) → - ContMDiff I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (cov.toFun X σ x)) + ContMDiff I (I.prod 𝓘(𝕜, F)) k (T% (cov.toFun X σ)) -- future: if g is a C^k metric, the LC connection is of class C^k ? @@ -221,7 +222,7 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] @[simp] lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by ext x - have : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (0 : V x)) x := by + have : MDifferentiableAt% (T% fun x ↦ (0 : V x)) x := by exact (contMDiff_zeroSection 𝕜 V).mdifferentiableAt le_rfl have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this simpa using this @@ -328,7 +329,7 @@ lemma convexCombination'_isRegular {ι : Type*} {s : Finset ι} [Nonempty s] unfold convexCombination' dsimp have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n - fun x ↦ TotalSpace.mk' F x ((f i • (cov i) X σ) x) := by + (T% (f i • (cov i) X σ)) := by apply contMDiff_smul_section (hf' i hi) exact IsCkConnection.regularity X σ hX (self := hcov i hi) simp only [Finset.sum_apply, Pi.smul_apply'] @@ -371,7 +372,7 @@ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') (⊤ : ℕ specialize hX x -- TODO: use contMDiffOn instead, to get something like -- have hX' : ContMDiffOn 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (∞ + 1) - -- (fun x ↦ TotalSpace.mk' E' x (σ x)) (trivializationAt x).baseSet := hX.contMDiffOn + -- (T% σ) (trivializationAt x).baseSet := hX.contMDiffOn -- then want a version contMDiffOn_totalSpace rw [contMDiffAt_totalSpace] at hX ⊢ simp only [Trivial.fiberBundle_trivializationAt', Trivial.trivialization_apply] @@ -493,7 +494,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ [VectorBundle ℝ F V] in lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ : MDifferentiableAt% (T% σ) x) (f : SmoothBumpFunction I x) : cov X ((f : M → ℝ) • σ) x = cov X σ x := by rw [cov.leibniz _ _ _ _ hσ] @@ -511,7 +512,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ : MDifferentiableAt% (T% σ) x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : cov X σ x = cov X σ' x := by -- Choose a smooth bump function ψ with support around `x` contained in `s` @@ -548,8 +549,8 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in lemma differenceAux_smul_eq (cov cov' : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hf : MDifferentiableAt I 𝓘(ℝ) f x) : + (hσ : MDifferentiableAt% (T% σ) x) + (hf : MDifferentiableAt% f x) : differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= calc _ _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl @@ -572,8 +573,8 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x₀) - (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x₀) + (hσ : MDifferentiableAt% (T% σ) x₀) + (hσ' : MDifferentiableAt% (T% σ') x₀) (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) : differenceAux cov cov' X σ x₀ = differenceAux cov cov' X' σ' x₀ := by trans cov.differenceAux cov' X' σ x₀ @@ -647,9 +648,9 @@ This is a vector bundle analogue of `contMDiff_of_tsupport`: the total space of but we only consider sections of the form `ψ s`. -/ lemma _root_.contMDiff_section_of_smul_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] {s : Π (x : M), V x} {ψ : SmoothBumpFunction I x} {t : Set M} - (hs : ContMDiffOn I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) t) + (hs : ContMDiffOn I (I.prod 𝓘(ℝ, F)) n (T% s) t) (ht : IsOpen t) (ht' : tsupport ψ ⊆ t) (hn : n ≤ ∞) : - ContMDiff I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by + ContMDiff I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) := by apply contMDiff_of_contMDiffOn_union_of_isOpen (contMDiffOn_smul_section (ψ.contMDiff.of_le hn).contMDiffOn hs) ?_ ?_ ht (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) @@ -667,15 +668,15 @@ but we only consider sections of the form `ψ s`. -/ lemma _root_.contMDiff_section_of_smul_smoothBumpFunction' [T2Space M] [IsManifold I ∞ M] {s : Π (x : M), V x} {ψ : SmoothBumpFunction I x} (hn : n ≤ ∞) (hs : ∀ x ∈ tsupport ψ, - ContMDiffAt I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by + ContMDiffAt I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) := by -- apply contMDiff_of_smul_smoothBumpFunction (s := s) (hn := hn) --?_ ?_ ?_ ?_ sorry omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := by + ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% extend I F σ₀) := by letI t := trivializationAt F V x letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x @@ -689,7 +690,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDifferentiable I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (extend I F σ₀ x)) := + MDifferentiable% (T% extend I F σ₀) := contMDiff_extend σ₀ |>.mdifferentiable (by simp) /-- The difference of two covariant derivatives, as a tensorial map -/ @@ -801,8 +802,7 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), ∀ X : (x : E) → TangentSpace 𝓘(ℝ, E) x, ∀ σ : (x : E) → Trivial E E' x, ∀ x : E, - MDifferentiableAt 𝓘(ℝ, E) (𝓘(ℝ, E).prod 𝓘(ℝ, E')) - (fun x' ↦ TotalSpace.mk' E' x' (σ x')) x → + MDifferentiableAt% (T% σ) x → cov X σ x = (CovariantDerivative.of_endomorphism A) X σ x := by use cov.endomorph_of_trivial_aux''' intro X σ x hσ @@ -847,10 +847,10 @@ variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} lemma proj_mderiv {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) - (hX : MDifferentiableAt I I.tangent (fun x ↦ TotalSpace.mk' E x (X x)) x) - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) : + (hX : MDifferentiableAt% (T% X) x) + (hσ : MDifferentiableAt% (T% σ) x) : cov X σ x = cov.proj (σ x) - (mfderiv I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x (X x)) := by + (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x (X x)) := by sorry end horiz @@ -886,7 +886,6 @@ variable (X) in lemma torsion_zero : torsion cov 0 X = 0 := by ext x simp [torsion] - sorry -- missing lemma? variable (X) in @[simp] @@ -894,8 +893,8 @@ lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_ze variable (Y) in lemma torsion_add_left [CompleteSpace E] - (hX : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X x))) - (hX' : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X' x))) : + (hX : MDifferentiable% (T% X)) + (hX' : MDifferentiable% (T% X')) : torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by ext x simp [torsion, cov.addX] @@ -903,30 +902,30 @@ lemma torsion_add_left [CompleteSpace E] module lemma torsion_add_right [CompleteSpace E] - (hX : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X x))) - (hX' : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X' x))) : + (hX : MDifferentiable% (T% X)) + (hX' : MDifferentiable% (T% X')) : torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module -- TODO: prove (for sections in any vector bundle); follow-up to 24932 -lemma _root_.VectorField.mlieBracket_fun_smul_left' {f : M → ℝ} (hf : MDifferentiableAt I 𝓘(ℝ) f x) +lemma _root_.VectorField.mlieBracket_fun_smul_left' {f : M → ℝ} (hf : MDifferentiableAt% f x) {V W : Π x : M, TangentSpace I x} - (hV : MDifferentiableAt I I.tangent (fun x ↦ TotalSpace.mk' E x (V x)) x) : + (hV : MDifferentiableAt% (T% V) x) : VectorField.mlieBracket I (fun y ↦ f y • V y) W x = - (mfderiv I 𝓘(ℝ) f x) (W x) • (V x) + (f x) • VectorField.mlieBracket I V W x := by sorry -- TODO: prove (for sections in any vector bundle); follow-up to 24932 -lemma _root_.VectorField.mlieBracket_smul_left' {f : M → ℝ} (hf : MDifferentiableAt I 𝓘(ℝ) f x) +lemma _root_.VectorField.mlieBracket_smul_left' {f : M → ℝ} (hf : MDifferentiableAt% f x) {V W : Π x : M, TangentSpace I x} - (hV : MDifferentiableAt I I.tangent (fun x ↦ TotalSpace.mk' E x (V x)) x) : + (hV : MDifferentiableAt% (T% V) x) : VectorField.mlieBracket I (f • V) W x = - (mfderiv I 𝓘(ℝ) f x) (W x) • (V x) + (f x) • VectorField.mlieBracket I V W x := by sorry variable (Y) in -lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable I 𝓘(ℝ) f) - (hX : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (X x))) : +lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) + (hX : MDifferentiable% (T% X)) : torsion cov (f • X) Y = f • torsion cov X Y := by simp only [torsion, cov.smulX] ext x @@ -936,8 +935,8 @@ lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable abel variable (X) in -lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable I 𝓘(ℝ) f) - (hY : MDifferentiable I I.tangent (fun x ↦ TotalSpace.mk' E x (Y x))) : +lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) + (hY : MDifferentiable% (T% Y)) : torsion cov X (f • Y) = f • torsion cov X Y := by rw [torsion_antisymm, torsion_smul_left X hf hY, torsion_antisymm X]; module From f1c254c2361b68bb39a6516b547083c01df0dde6 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 17:17:42 +0200 Subject: [PATCH 142/601] chore: more API about mpullback_smul --- .../Manifold/VectorField/Pullback.lean | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean index a00fc0f0f7fc96..0edb14690bd527 100644 --- a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean +++ b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean @@ -105,15 +105,23 @@ def mpullback (f : M → M') (V : Π (x : M'), TangentSpace I' x) (x : M) : lemma mpullbackWithin_apply : mpullbackWithin I I' f V s x = (mfderivWithin I I' f s x).inverse (V (f x)) := rfl -lemma mpullbackWithin_smul_apply : +lemma mpullbackWithin_const_smul_apply : mpullbackWithin I I' f (c • V) s x = c • mpullbackWithin I I' f V s x := by simp [mpullbackWithin_apply] -lemma mpullbackWithin_smul : +lemma mpullbackWithin_smul_apply {g : M' → 𝕜} : + mpullbackWithin I I' f (g • V) s x = g (f x) • mpullbackWithin I I' f V s x := by + simp [mpullbackWithin_apply] + +lemma mpullbackWithin_const_smul : mpullbackWithin I I' f (c • V) s = c • mpullbackWithin I I' f V s := by ext x simp [mpullbackWithin_apply] +lemma mpullbackWithin_smul {g : M' → 𝕜} : + mpullbackWithin I I' f (g • V) s = (g ∘ f) • mpullbackWithin I I' f V s := by + ext; simp [mpullbackWithin_apply] + lemma mpullbackWithin_add_apply : mpullbackWithin I I' f (V + V₁) s x = mpullbackWithin I I' f V s x + mpullbackWithin I I' f V₁ s x := by @@ -146,15 +154,24 @@ lemma mpullbackWithin_id {V : Π (x : M), TangentSpace I x} (h : UniqueMDiffWith lemma mpullback_apply : mpullback I I' f V x = (mfderiv I I' f x).inverse (V (f x)) := rfl -lemma mpullback_smul_apply : +lemma mpullback_const_smul_apply : mpullback I I' f (c • V) x = c • mpullback I I' f V x := by simp [mpullback] -lemma mpullback_smul : +lemma mpullback_const_smul : mpullback I I' f (c • V) = c • mpullback I I' f V := by ext x simp [mpullback_apply] +lemma mpullback_smul_apply {g : M' → 𝕜} : + mpullback I I' f (g • V) x = g (f x) • mpullback I I' f V x := by + simp [mpullback] + +lemma mpullback_smul {g : M' → 𝕜} : + mpullback I I' f (g • V) = (g ∘ f) • mpullback I I' f V := by + ext x + simp [mpullback_apply] + lemma mpullback_add_apply : mpullback I I' f (V + V₁) x = mpullback I I' f V x + mpullback I I' f V₁ x := by simp [mpullback_apply] From f24e90b6766d845ceb53f91894bcf29c4e612dde Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 17:19:06 +0200 Subject: [PATCH 143/601] WIP: product rule for Lie brackets on manifolds -- copy-pasted from #26743 --- .../Manifold/VectorField/LieBracket.lean | 82 +++++++++++++++---- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 6f1cc43364347d..737f3fd6005173 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -282,35 +282,89 @@ lemma _root_.MDifferentiableWithinAt.differentiableWithinAt_mpullbackWithin_vect exact ((contMDiff_snd_tangentBundle_modelSpace E 𝓘(𝕜, E)).contMDiffAt.mdifferentiableAt le_rfl).comp_mdifferentiableWithinAt _ this -lemma mlieBracketWithin_smul_left +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. Version within a set. +-/ +lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinAt I 𝓘(𝕜) f s x) + (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) + (hs : UniqueMDiffWithinAt I s x) : + mlieBracketWithin I V (f • W) s x = + (mfderivWithin I 𝓘(𝕜) f s x) (V x) • (W x) + (f x) • mlieBracketWithin I V W s x := by + simp only [mlieBracketWithin] + rw [mpullbackWithin_smul] + set V' := (mpullbackWithin 𝓘(𝕜, E) I (↑(extChartAt I x).symm) V (range I)) + set W' := (mpullbackWithin 𝓘(𝕜, E) I (↑(extChartAt I x).symm) W (range I)) + -- idea: rewrite by lieBracketWithin_smul_right + -- recognise the terms on the rhs, done + -- let aux := lieBracketWithin_smul_right (V := V') (W := W') + --simp [mfderivWithin_eq_fderivWithin] + sorry + +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. +-/ +lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDifferentiableAt I 𝓘(𝕜) f x) + (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : + mlieBracket I V (f • W) x = + (mfderiv I 𝓘(𝕜) f x) (V x) • (W x) + (f x) • mlieBracket I V W x := by + rw [← mdifferentiableWithinAt_univ] at hf hW + rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] + exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I) + +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M → 𝕜`, we have `[f • V, W] = -(df W) • V + f • [V, W]`. Version within a set. +-/ +lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDifferentiableWithinAt I 𝓘(𝕜) f s x) + (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) + (hs : UniqueMDiffWithinAt I s x) : + mlieBracketWithin I (f • V) W s x = + -(mfderivWithin I 𝓘(𝕜) f s x) (W x) • (V x) + (f x) • mlieBracketWithin I V W s x := by + rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_smul_right hf hV (V := W) hs, + mlieBracketWithin_swap] + simp; abel + +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M → 𝕜`, we have `[f • V, W] = -(df W) • V + f • [V, W]`. +-/ +lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDifferentiableAt I 𝓘(𝕜) f x) + (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) : + mlieBracket I (f • V) W x = + -(mfderiv I 𝓘(𝕜) f x) (W x) • (V x) + (f x) • mlieBracket I V W x := by + rw [← mdifferentiableWithinAt_univ] at hf hV + rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] + exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I) + +lemma mlieBracketWithin_const_smul_left (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (c • V) W s x = c • mlieBracketWithin I V W s x := by - simp only [mlieBracketWithin_apply] - rw [← ContinuousLinearMap.map_smul, mpullbackWithin_smul, lieBracketWithin_smul_left] - · exact hV.differentiableWithinAt_mpullbackWithin_vectorField - · exact uniqueMDiffWithinAt_iff_inter_range.1 hs + have aux := mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs + simp [mfderivWithin_const] at aux + convert aux -lemma mlieBracket_smul_left +lemma mlieBracket_const_smul_left (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) : mlieBracket I (c • V) W x = c • mlieBracket I V W x := by simp only [← mlieBracketWithin_univ] at hV ⊢ - exact mlieBracketWithin_smul_left hV (uniqueMDiffWithinAt_univ _) + exact mlieBracketWithin_const_smul_left hV (uniqueMDiffWithinAt_univ _) -lemma mlieBracketWithin_smul_right +lemma mlieBracketWithin_const_smul_right (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (c • W) s x = c • mlieBracketWithin I V W s x := by - simp only [mlieBracketWithin_apply] - rw [← ContinuousLinearMap.map_smul, mpullbackWithin_smul, lieBracketWithin_smul_right] - · exact hW.differentiableWithinAt_mpullbackWithin_vectorField - · exact uniqueMDiffWithinAt_iff_inter_range.1 hs + have aux := mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs + simp [mfderivWithin_const] at aux + convert aux -lemma mlieBracket_smul_right +lemma mlieBracket_const_smul_right (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : mlieBracket I V (c • W) x = c • mlieBracket I V W x := by simp only [← mlieBracketWithin_univ] at hW ⊢ - exact mlieBracketWithin_smul_right hW (uniqueMDiffWithinAt_univ _) + exact mlieBracketWithin_const_smul_right hW (uniqueMDiffWithinAt_univ _) lemma mlieBracketWithin_add_left (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) From 585a99b34674bb378e78e2175e0a8690de198c81 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 17:30:09 +0200 Subject: [PATCH 144/601] Update CovariantDerivatives accordingly --- .../VectorBundle/CovariantDerivative.lean | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index a1cb70a3e5a091..8ff5715a9e6922 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -907,22 +907,6 @@ lemma torsion_add_right [CompleteSpace E] torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module --- TODO: prove (for sections in any vector bundle); follow-up to 24932 -lemma _root_.VectorField.mlieBracket_fun_smul_left' {f : M → ℝ} (hf : MDifferentiableAt% f x) - {V W : Π x : M, TangentSpace I x} - (hV : MDifferentiableAt% (T% V) x) : - VectorField.mlieBracket I (fun y ↦ f y • V y) W x = - - (mfderiv I 𝓘(ℝ) f x) (W x) • (V x) + (f x) • VectorField.mlieBracket I V W x := by - sorry - --- TODO: prove (for sections in any vector bundle); follow-up to 24932 -lemma _root_.VectorField.mlieBracket_smul_left' {f : M → ℝ} (hf : MDifferentiableAt% f x) - {V W : Π x : M, TangentSpace I x} - (hV : MDifferentiableAt% (T% V) x) : - VectorField.mlieBracket I (f • V) W x = - - (mfderiv I 𝓘(ℝ) f x) (W x) • (V x) + (f x) • VectorField.mlieBracket I V W x := by - sorry - variable (Y) in lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) (hX : MDifferentiable% (T% X)) : @@ -930,7 +914,7 @@ lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% simp only [torsion, cov.smulX] ext x simp [cov.leibniz Y X f x (hX x) (hf x)] - rw [VectorField.mlieBracket_smul_left' (hf x) (hX x)] + rw [VectorField.mlieBracket_smul_left (hf x) (hX x)] simp [bar, smul_sub] abel From dade3c9b6b0904e22996041588c8d239106e9180 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 18:00:29 +0200 Subject: [PATCH 145/601] feat: tensoriality criterion for two variables --- .../Manifold/VectorBundle/Tensoriality.lean | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 432f3412416831..9ea4d9fb33b796 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -163,6 +163,64 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi apply b.localFrame_repr_congr assumption +include I in +omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in +lemma tensoriality_criterion₂' [FiberBundle F V] [VectorBundle ℝ F V] + [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] + [FiberBundle F' V'] [VectorBundle ℝ F' V'] + {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + {σ σ' τ τ' : Π x : M, V x} + (hσσ' : σ x = σ' x) + (hττ' : τ x = τ' x) + (φ_smul : ∀ f : M → ℝ, ∀ σ τ, φ (f • σ) τ x = f x • φ σ τ x) + (φ_add : ∀ σ σ' τ, φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ f : M → ℝ, ∀ σ τ, φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ σ τ τ', φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by + trans φ σ' τ x + · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ + change φ1 σ x = φ1 σ' x + exact tensoriality_criterion' I F V F' V' hσσ' (by simp [φ_smul, φ1]) (by simp [φ_add, φ1]) + · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X + change φ1 τ x = φ1 τ' x + exact tensoriality_criterion' I F V F' V' hττ' (by simp [τ_smul, φ1]) (by simp [τ_add, φ1]) + +include I in +omit [IsManifold I 1 M] in +lemma tensoriality_criterion₂ [ContMDiffVectorBundle 1 F V I] [IsManifold I ∞ M] + [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] + [FiberBundle F' V'] [VectorBundle ℝ F' V'] + {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + {σ σ' τ τ' : Π x : M, V x} + (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (hτ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ x)) x) + (hτ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ' x)) x) + (hσσ' : σ x = σ' x) + (hττ' : τ x = τ' x) + (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt I 𝓘(ℝ) f x → + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → + φ (f • σ) τ x = f x • φ σ τ x) + (φ_add : ∀ {σ σ' τ}, + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt I 𝓘(ℝ) f x → + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ x)) x → + φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ {σ τ τ'}, + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ x)) x → + MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ' x)) x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by + trans φ σ' τ x + · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ + change φ1 σ x = φ1 σ' x + apply tensoriality_criterion I F V F' V' hσ hσ' hσσ' + exacts [fun f σ hf hσ ↦ φ_smul hf hσ, fun σ σ' hσ hσ' ↦ φ_add hσ hσ'] + · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X + change φ1 τ x = φ1 τ' x + apply tensoriality_criterion I F V F' V' hτ hτ' hττ' + exacts [fun f τ hf hτ ↦ τ_smul hf hτ, fun τ τ' hτ hτ' ↦ τ_add hτ hτ'] + /- include I in lemma tensoriality_criterion'' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] From be3b7024c98c74426f84d281562e496230ddebd0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 20:14:10 +0200 Subject: [PATCH 146/601] Progress: torsion is tensorial --- .../VectorBundle/CovariantDerivative.lean | 63 ++++++++++++++++--- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 8ff5715a9e6922..b0ee2c4252a4e8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -891,15 +891,30 @@ variable (X) in @[simp] lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp +variable (Y) in +lemma torsion_add_left_apply [CompleteSpace E] {x : M} + (hX : MDifferentiableAt% (T% X) x) + (hX' : MDifferentiableAt% (T% X') x) : + torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by + simp [torsion, cov.addX] + rw [cov.addσ _ X X' _ hX hX', VectorField.mlieBracket_add_left hX hX'] + module + variable (Y) in lemma torsion_add_left [CompleteSpace E] (hX : MDifferentiable% (T% X)) (hX' : MDifferentiable% (T% X')) : torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by ext x - simp [torsion, cov.addX] - rw [cov.addσ _ X X' _ (hX x) (hX' x), VectorField.mlieBracket_add_left (hX x) (hX' x)] - module + exact cov.torsion_add_left_apply _ (hX x) (hX' x) + +lemma torsion_add_right_apply [CompleteSpace E] {x : M} + (hX : MDifferentiableAt% (T% X) x) + (hX' : MDifferentiableAt% (T% X') x) : + torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by + rw [torsion_antisymm] + sorry -- rw [cov.torsion_add_left_apply Y hX hX'] + --, torsion_add_left_apply _ hX hX', torsion_antisymm X, torsion_antisymm X']; module lemma torsion_add_right [CompleteSpace E] (hX : MDifferentiable% (T% X)) @@ -907,16 +922,22 @@ lemma torsion_add_right [CompleteSpace E] torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module +variable (Y) in +lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) + (hX : MDifferentiableAt% (T% X) x) : + torsion cov (f • X) Y x = f x • torsion cov X Y x := by + simp only [torsion, cov.smulX] + sorry /- rw [cov.leibniz Y X f x hX hf] + rw [VectorField.mlieBracket_smul_left hf hX] + simp [bar, smul_sub] + abel -/ + variable (Y) in lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) (hX : MDifferentiable% (T% X)) : torsion cov (f • X) Y = f • torsion cov X Y := by - simp only [torsion, cov.smulX] ext x - simp [cov.leibniz Y X f x (hX x) (hf x)] - rw [VectorField.mlieBracket_smul_left (hf x) (hX x)] - simp [bar, smul_sub] - abel + exact cov.torsion_smul_left_apply _ (hf x) (hX x) variable (X) in lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) @@ -924,7 +945,31 @@ lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable torsion cov X (f • Y) = f • torsion cov X Y := by rw [torsion_antisymm, torsion_smul_left X hf hY, torsion_antisymm X]; module --- finally, conclude that torsion is tensorial +variable (X) in +lemma torsion_smul_right_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) + (hX : MDifferentiableAt% (T% Y) x) : + torsion cov X (f • Y) x = f x • torsion cov X Y x := by + sorry + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in +/-- The torsion of a covariant derivative is tensorial: +the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ +def torsion_tensorial [T2Space M] [IsManifold I ∞ M] + [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] + {X X' Y Y' : Π x : M, TangentSpace I x} {x₀ : M} + (hX : MDifferentiableAt% (T% X) x₀) (hX' : MDifferentiableAt% (T% X') x₀) + (hY : MDifferentiableAt% (T% Y) x₀) (hY' : MDifferentiableAt% (T% Y') x₀) + (hXX' : X x₀ = X' x₀) (hYY' : Y x₀ = Y' x₀) : + (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by + apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' + · intro f σ τ hf hσ + exact cov.torsion_smul_left_apply _ hf hσ + · intro σ σ' τ hσ hσ' + exact cov.torsion_add_left_apply _ hσ hσ' + · intros f σ σ' hf hσ' + exact cov.torsion_smul_right_apply _ hf hσ' + · intro σ τ τ' hτ hτ' + exact cov.torsion_add_right_apply hτ hτ' variable (cov) in /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ From 9e95e65416dd5189888abc1948e61df08f7dea7f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 20:28:32 +0200 Subject: [PATCH 147/601] chore(Tensoriality): use the new elaborator a bit --- Mathlib/Geometry/Manifold/Elaborators.lean | 1 - .../Manifold/VectorBundle/Tensoriality.lean | 43 ++++++++++--------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index a8ad2baf32fa74..85d9717e46f19b 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -9,7 +9,6 @@ import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.Traces diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 9ea4d9fb33b796..acbebda49297f3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -7,6 +7,7 @@ import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.MFDeriv.Basic import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.Elaborators /-! # The tensoriality criterion @@ -44,19 +45,19 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [IsManifold I ∞ M] {φ : (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' : Π x : M, V x} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (hσ : MDifferentiableAt% (T% σ) x) + (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (T% σ') x) (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDifferentiableAt I 𝓘(ℝ) f x → - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDifferentiableAt% f x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x → φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by have locality {σ σ'} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (hσ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ' : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : φ σ x = φ σ' x := by obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by @@ -72,7 +73,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F classical have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) - (hσ : ∀ i, MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ i x)) x): + (hσ : ∀ i, MDifferentiableAt% (T% σ i) x): φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by induction s using Finset.induction_on with | empty => @@ -93,10 +94,10 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) let c := Basis.localFrame_repr t b - have hs (i) : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (s i x)) x:= + have hs (i) : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (s i x)) x:= (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl have hc {σ : (x : M) → V x} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) (i) : + (hσ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x) (i) : MDifferentiableAt I 𝓘(ℝ, ℝ) ((c i) σ) x := mdifferentiableAt_localFrame_repr x_mem b hσ i have hφ {σ : (x : M) → V x} @@ -191,25 +192,25 @@ lemma tensoriality_criterion₂ [ContMDiffVectorBundle 1 F V I] [IsManifold I [FiberBundle F' V'] [VectorBundle ℝ F' V'] {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' τ τ' : Π x : M, V x} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x) - (hτ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ x)) x) - (hτ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ' x)) x) + (hσ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x) + (hσ' : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (hτ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ x)) x) + (hτ' : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ' x)) x) (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt I 𝓘(ℝ) f x → - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → φ (f • σ) τ x = f x • φ σ τ x) (φ_add : ∀ {σ σ' τ}, - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x → - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ' x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt I 𝓘(ℝ) f x → - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ x)) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ {σ τ τ'}, - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ x)) x → - MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (τ' x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ x)) x → + MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ' x)) x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by trans φ σ' τ x · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ From 841b6a47d72884beeaf4e908b3ad1b27a6726d08 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 21:04:08 +0200 Subject: [PATCH 148/601] Use more --- .../Manifold/VectorBundle/Tensoriality.lean | 52 +++++++------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index acbebda49297f3..a965169d13f68c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -44,20 +44,13 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] [IsManifold I ∞ M] {φ : (Π x : M, V x) → (Π x, V' x)} {x} - {σ σ' : Π x : M, V x} - (hσ : MDifferentiableAt% (T% σ) x) - (hσ' : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (T% σ') x) + {σ σ' : Π x : M, V x} (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDifferentiableAt% f x → - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x → - φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by - have locality {σ σ'} - (hσ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hσ' : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x) + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDifferentiableAt% f x → MDifferentiableAt% (T% σ) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x → + φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by + have locality {σ σ'} (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : φ σ x = φ σ' x := by obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by @@ -78,7 +71,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] induction s using Finset.induction_on with | empty => simp only [Finset.sum_empty] - have h₁ : MDifferentiableAt I 𝓘(ℝ) (fun x' : M ↦ (0 : ℝ)) x := by + have h₁ : MDifferentiableAt% (fun x' : M ↦ (0 : ℝ)) x := by exact contMDiffAt_const.mdifferentiableAt le_rfl rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl] rw [φ_smul] @@ -94,14 +87,13 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) let c := Basis.localFrame_repr t b - have hs (i) : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (s i x)) x:= - (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl - have hc {σ : (x : M) → V x} - (hσ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x) (i) : - MDifferentiableAt I 𝓘(ℝ, ℝ) ((c i) σ) x := + have hs (i) : MDifferentiableAt% (T% s i) x:= + (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl + have hc {σ : (x : M) → V x} (hσ : MDifferentiableAt% (T% σ) x) (i) : + MDifferentiableAt% ((c i) σ) x := mdifferentiableAt_localFrame_repr x_mem b hσ i have hφ {σ : (x : M) → V x} - (hσ : MDifferentiableAt I (I.prod 𝓘(ℝ, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) x) : + (hσ : MDifferentiableAt% (T% σ) x) : φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by exact locality hσ @@ -192,25 +184,17 @@ lemma tensoriality_criterion₂ [ContMDiffVectorBundle 1 F V I] [IsManifold I [FiberBundle F' V'] [VectorBundle ℝ F' V'] {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' τ τ' : Π x : M, V x} - (hσ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x) - (hσ' : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x) - (hτ : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ x)) x) - (hτ' : MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ' x)) x) + (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) + (hτ : MDifferentiableAt% (T% τ) x) (hτ' : MDifferentiableAt% (T% τ') x) (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) - (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt I 𝓘(ℝ) f x → - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → + (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt% f x → MDifferentiableAt% (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (φ_add : ∀ {σ σ' τ}, - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ x)) x → - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (σ' x)) x → + (φ_add : ∀ {σ σ' τ}, MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt I 𝓘(ℝ) f x → - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ x)) x → + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt% f x → MDifferentiableAt% (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ x)) x → - MDifferentiableAt% (fun x ↦ TotalSpace.mk' F x (τ' x)) x → + (τ_add : ∀ {σ τ τ'}, MDifferentiableAt% (T% τ) x → MDifferentiableAt% (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by trans φ σ' τ x · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ From 81a676bbb9ea6ab18bd3d6c2ac8387a8b8bc1a3f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 21:10:03 +0200 Subject: [PATCH 149/601] Fix the build --- Mathlib/Geometry/Manifold/GroupLieAlgebra.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean index 6d279a49fca338..0d785c53bc790a 100644 --- a/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean +++ b/Mathlib/Geometry/Manifold/GroupLieAlgebra.lean @@ -247,7 +247,7 @@ noncomputable instance instLieAlgebraAddGroupLieAlgebra [LieAddGroup I (minSmoothness 𝕜 3) G] : LieAlgebra 𝕜 (AddGroupLieAlgebra I G) where lie_smul c v w := by simp only [AddGroupLieAlgebra.bracket_def, addInvariantVectorField_smul] - rw [mlieBracket_smul_right] + rw [mlieBracket_const_smul_right] exact mdifferentiableAt_addInvariantVectorField _ /-- The tangent space at the identity of a Lie group is a Lie algebra, for the bracket @@ -255,7 +255,7 @@ given by the Lie bracket of invariant vector fields. -/ noncomputable instance instLieAlgebraGroupLieAlgebra : LieAlgebra 𝕜 (GroupLieAlgebra I G) where lie_smul c v w := by simp only [GroupLieAlgebra.bracket_def, mulInvariantVectorField_smul] - rw [mlieBracket_smul_right] + rw [mlieBracket_const_smul_right] exact mdifferentiableAt_mulInvariantVectorField _ end LieGroup From 17e1fb8dbdb1bc25625ee445534f6d2f9db22cbd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 4 Jul 2025 23:44:36 +0200 Subject: [PATCH 150/601] Fix comments; prove a few leftover sorries --- .../VectorBundle/CovariantDerivative.lean | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 4f89ad4bb9ed3e..36600600369d1e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -307,7 +307,7 @@ noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' /-- The trivial connection on the trivial bundle is smooth -/ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') (⊤ : ℕ∞) where regularity X σ hX /-hσ-/ := by - -- except for locla trivialisations, contDiff_infty_iff_fderiv covers this well + -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well simp only [trivial] -- use a local trivialisation intro x @@ -854,9 +854,9 @@ lemma torsion_add_right_apply [CompleteSpace E] {x : M} (hX : MDifferentiableAt% (T% X) x) (hX' : MDifferentiableAt% (T% X') x) : torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by - rw [torsion_antisymm] - sorry -- rw [cov.torsion_add_left_apply Y hX hX'] - --, torsion_add_left_apply _ hX hX', torsion_antisymm X, torsion_antisymm X']; module + rw [torsion_antisymm, Pi.neg_apply, + cov.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] + simp; abel lemma torsion_add_right [CompleteSpace E] (hX : MDifferentiable% (T% X)) @@ -868,11 +868,10 @@ variable (Y) in lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) (hX : MDifferentiableAt% (T% X) x) : torsion cov (f • X) Y x = f x • torsion cov X Y x := by - simp only [torsion, cov.smulX] - sorry /- rw [cov.leibniz Y X f x hX hf] - rw [VectorField.mlieBracket_smul_left hf hX] + simp only [torsion, cov.smulX, Pi.sub_apply, Pi.smul_apply'] + rw [cov.leibniz Y X f x hX hf, VectorField.mlieBracket_smul_left hf hX] simp [bar, smul_sub] - abel -/ + abel variable (Y) in lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) @@ -881,17 +880,19 @@ lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% ext x exact cov.torsion_smul_left_apply _ (hf x) (hX x) -variable (X) in -lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) - (hY : MDifferentiable% (T% Y)) : - torsion cov X (f • Y) = f • torsion cov X Y := by - rw [torsion_antisymm, torsion_smul_left X hf hY, torsion_antisymm X]; module - variable (X) in lemma torsion_smul_right_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) (hX : MDifferentiableAt% (T% Y) x) : torsion cov X (f • Y) x = f x • torsion cov X Y x := by - sorry + rw [torsion_antisymm, Pi.neg_apply, torsion_smul_left_apply X hf hX, torsion_antisymm X] + simp + +variable (X) in +lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) + (hY : MDifferentiable% (T% Y)) : + torsion cov X (f • Y) = f • torsion cov X Y := by + ext x + apply cov.torsion_smul_right_apply _ (hf x) (hY x) omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- The torsion of a covariant derivative is tensorial: @@ -919,17 +920,17 @@ def IsTorsionFree : Prop := torsion cov = 0 lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] --- lemma: the trivial connection is torsion free +-- lemma the trivial connection on a normed space is torsion-free +-- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry --- API for the trivial bundle (does some of this exist already?) --- there is a single trivialisation, whose baseSet is univ +-- lemma: tangent bundle of E is trivial -> there exists a single trivialisation with baseSet univ -- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, -- w.r.t. to this trivialisation -- add lemmas: globalFrame is contMDiff globally -- proof of above lemma: write sections s and t in the global frame above -- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) --- compute: their Lie bracket is zero (intuitively, as their flows commute) +-- compute: their Lie bracket is zero -- compute: the other two terms cancel, done end torsion From bf0e2e6e962913d4e54af4528aea8e412970c2e8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 5 Jul 2025 00:23:45 +0200 Subject: [PATCH 151/601] fix: definition of smooth connection And perform some small code clean-ups: use the coeFun instance, make two arguments implicit which deserve to be. --- .../VectorBundle/CovariantDerivative.lean | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 36600600369d1e..9180490901f03a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -128,21 +128,6 @@ structure CovariantDerivative where smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), toFun X (a • σ) = a • toFun X σ -variable {I F V} -/-- -A covariant derivative ∇ is called of class `C^k` iff, -whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. -This is a class so typeclass inference can deduce this automatically. --/ -class IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) where - regularity : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x), - ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (T% σ) → - -- TODO: this condition does not typecheck! - -- ContMDiff I I.tangent k (fun x ↦ (X x : TangentBundle I M)) → - ContMDiff I (I.prod 𝓘(𝕜, F)) k (T% (cov.toFun X σ)) - --- future: if g is a C^k metric, the LC connection is of class C^k ? - namespace CovariantDerivative attribute [coe] toFun @@ -152,6 +137,20 @@ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := ⟨fun e ↦ e.toFun⟩ +variable {I F V} +/-- +A covariant derivative ∇ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class _root_.IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where + regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, + ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → + ContMDiff I (I.prod 𝓘(𝕜, F)) k (T% (cov X σ)) + +-- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection +-- is of class C^k (up to off-by-one errors) + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @[simp] @@ -250,30 +249,30 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma convexCombination_isRegular (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} - (hf : ContMDiff I 𝓘(𝕜) n f) +lemma convexCombination_isRegular [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) + {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : IsCkConnection cov n) (hcov' : IsCkConnection cov' n) : IsCkConnection (convexCombination cov cov' f) n where - regularity X σ hX /-hσ-/ := by + regularity {X σ} hX hσ := by apply contMDiff_add_section - · exact contMDiff_smul_section hf <| hcov.regularity X σ hX - · exact contMDiff_smul_section (contMDiff_const.sub hf) <| hcov'.regularity X σ hX + · exact contMDiff_smul_section hf <| hcov.regularity hX hσ + · exact contMDiff_smul_section (contMDiff_const.sub hf) <| hcov'.regularity hX hσ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in /-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma convexCombination'_isRegular {ι : Type*} {s : Finset ι} [Nonempty s] +lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, IsCkConnection (cov i) n) : IsCkConnection (convexCombination' cov hf) n where - regularity X σ hX /-hσ-/ := by + regularity {X σ} hX hσ := by unfold convexCombination' dsimp have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n (T% (f i • (cov i) X σ)) := by apply contMDiff_smul_section (hf' i hi) - exact IsCkConnection.regularity X σ hX (self := hcov i hi) + exact IsCkConnection.regularity hX hσ (self := hcov i hi) simp only [Finset.sum_apply, Pi.smul_apply'] exact contMDiff_finsum_section (t := fun i ↦ f i • (cov i) X σ) ms @@ -306,7 +305,7 @@ noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' /-- The trivial connection on the trivial bundle is smooth -/ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') (⊤ : ℕ∞) where - regularity X σ hX /-hσ-/ := by + regularity {X σ} hX hσ := by -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well simp only [trivial] -- use a local trivialisation From 7dd939f0abace7650fb38dc9990078b5994414c3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 5 Jul 2025 00:10:03 +0200 Subject: [PATCH 152/601] Start: stub file on the Levi-Civita connection. Contains a rought outline; biggest blocker is how to spell "connection on TM" --- Mathlib.lean | 3 +- .../Manifold/VectorBundle/LeviCivita.lean | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean diff --git a/Mathlib.lean b/Mathlib.lean index db7a09cfb9dc45..1dea0da974607f 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3714,10 +3714,12 @@ import Mathlib.Geometry.Manifold.PoincareConjecture import Mathlib.Geometry.Manifold.Sheaf.Basic import Mathlib.Geometry.Manifold.Sheaf.LocallyRingedSpace import Mathlib.Geometry.Manifold.Sheaf.Smooth +import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear import Mathlib.Geometry.Manifold.VectorBundle.Hom +import Mathlib.Geometry.Manifold.VectorBundle.LeviCivita import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.Pullback @@ -3727,7 +3729,6 @@ import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.VectorField.Pullback -import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.WhitneyEmbedding import Mathlib.Geometry.RingedSpace.Basic import Mathlib.Geometry.RingedSpace.LocallyRingedSpace diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean new file mode 100644 index 00000000000000..fbbc17dc3b03e0 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -0,0 +1,93 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative +import Mathlib.Geometry.Manifold.VectorBundle.Riemannian + +/-! +# The Levi-Civita connection + +This file will define the Levi-Civita connection on any Riemannian manifold. +Details to be written! + +-/ + +open Bundle Filter Function Topology + +open scoped Bundle Manifold ContDiff + +-- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. +variable {n : WithTop ℕ∞} + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I ∞ M] + [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + [IsContMDiffRiemannianBundle I ∞ E (fun (x : M) ↦ TangentSpace I x)] + -- comes in a future PR by sgouezel; don't need this part yet + -- [IsRiemannianManifold I M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] + +local notation "⟪" x ", " y "⟫" => inner ℝ x y + +/-! Compatible connections: a connection on TM is compatible with the metric on M iff +`∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all vector fields X, Y and Z on `M`. +The left hand side is the differential of the function ⟨Y, Z⟩ along the vector field X: +at each point p, let γ(t) be a curve representing the tangent vector X p, +then the LHS is the initial derivative of the function t ↦ ⟨Y(γ(p)), Z(γ p)⟩ at 0. -/ + +variable {X Y Z W : Π x : M, TangentSpace I x} + +-- /-- The scalar product of two vector fields -/ +-- noncomputable def product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ ⟪X x, Y x⟫ +-- smoothness results shown in Riemannian.lean: will omit +variable [IsManifold I ∞ M] +--variable (cov : CovariantDerivative I E (V := TangentBundle I M)) +-- TODO: state "cov is a connection on TM" in a way that type-checks... +-- (cov : CovariantDerivative I E (V := fun x ↦ TangentSpace I x)) does not... + +include I in +variable (Y Z) in +noncomputable def lhs_aux : M → ℝ := fun x ↦ ⟪Y x, Z x⟫ + +variable (X Y Z) in +noncomputable def lhs : M → ℝ := fun x ↦ mfderiv I 𝓘(ℝ) (lhs_aux I Y Z) x (X x) + +-- variable (X Y Z) in +-- noncomputable def rhs : M → ℝ := ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ + +/- + +def CovariantDerivative.IsCompatible (cov) (g) : lhs = rhs on mdiff. functions + +new definition +IsLeviCivitaConnection: IsCompatible \and IsTorsionFree + +uniqueness theorem: any two Levi-Civita connections agree on all mdiff vector fields +(probably not everywhere, as addition rules don't apply to them?) + +-----> helper lemmas +on a metric vector bundle: orthonormal frame (continuous setting at first), +prove these are continuous +(and smooth if the metric is smooth) + +lemma: = for all Y implies X and X' are equal +(-> use for uniqueness of LC connection) + +compute: a symmetric connection satisfies xxx + a LC connection satisfies ... + deduce the final equation characterising it + +corollary: uniqueness + +-- A choice of Levi-Civita connection on TM: this is unique up to the value on non-differentiable vector fields. +-- If you know the Levi-Civita connection already, you can use IsLeviCivitaConnection instead. +def LeviCivitaConnection := sorry + +this is the existence part, I presume + +lemma : IsLeviCivitaConnection (LeviCivitaConnection) := sorry + +-/ From 17794b31518f071f2d8d6b3b6f6cc790aa4d6044 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 6 Jul 2025 16:10:21 +0200 Subject: [PATCH 153/601] Blocker resolved; state my strategy in Lean --- .../Manifold/VectorBundle/LeviCivita.lean | 135 ++++++++++++------ 1 file changed, 88 insertions(+), 47 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index fbbc17dc3b03e0..d53cde373a6d8d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative +import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Riemannian /-! @@ -12,6 +13,12 @@ import Mathlib.Geometry.Manifold.VectorBundle.Riemannian This file will define the Levi-Civita connection on any Riemannian manifold. Details to be written! + + + +TODO: more generally, define a notion of metric connections (e.g., those whose parallel transport +is an isometry) and prove the Levi-Civita connection is a metric connection + -/ open Bundle Filter Function Topology @@ -34,60 +41,94 @@ local notation "⟪" x ", " y "⟫" => inner ℝ x y /-! Compatible connections: a connection on TM is compatible with the metric on M iff `∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all vector fields X, Y and Z on `M`. -The left hand side is the differential of the function ⟨Y, Z⟩ along the vector field X: -at each point p, let γ(t) be a curve representing the tangent vector X p, -then the LHS is the initial derivative of the function t ↦ ⟨Y(γ(p)), Z(γ p)⟩ at 0. -/ +The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: +the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ variable {X Y Z W : Π x : M, TangentSpace I x} --- /-- The scalar product of two vector fields -/ --- noncomputable def product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ ⟪X x, Y x⟫ --- smoothness results shown in Riemannian.lean: will omit -variable [IsManifold I ∞ M] ---variable (cov : CovariantDerivative I E (V := TangentBundle I M)) --- TODO: state "cov is a connection on TM" in a way that type-checks... --- (cov : CovariantDerivative I E (V := fun x ↦ TangentSpace I x)) does not... - -include I in -variable (Y Z) in -noncomputable def lhs_aux : M → ℝ := fun x ↦ ⟪Y x, Z x⟫ - -variable (X Y Z) in -noncomputable def lhs : M → ℝ := fun x ↦ mfderiv I 𝓘(ℝ) (lhs_aux I Y Z) x (X x) - --- variable (X Y Z) in --- noncomputable def rhs : M → ℝ := ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ - -/- - -def CovariantDerivative.IsCompatible (cov) (g) : lhs = rhs on mdiff. functions - -new definition -IsLeviCivitaConnection: IsCompatible \and IsTorsionFree - -uniqueness theorem: any two Levi-Civita connections agree on all mdiff vector fields -(probably not everywhere, as addition rules don't apply to them?) +/-- The scalar product of two vector fields -/ +noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ ⟪X x, Y x⟫ +-- Riemannian.lean shows that `product` is C^k if X and Y are ------> helper lemmas -on a metric vector bundle: orthonormal frame (continuous setting at first), -prove these are continuous -(and smooth if the metric is smooth) +namespace CovariantDerivative -lemma: = for all Y implies X and X' are equal -(-> use for uniqueness of LC connection) +-- Let `cov` be a covariant derivative on `TM`. +-- TODO: include in cheat sheet! +variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) -compute: a symmetric connection satisfies xxx - a LC connection satisfies ... - deduce the final equation characterising it +-- TODO: make g part of the notation! +def IsCompatible : Prop := + ∀ X Y Z : Π x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! + ∀ x : M, + mfderiv I 𝓘(ℝ) (product I Y Z) x (X x) = ⟪cov X Y x, Z x⟫ + ⟪Y x, cov X Z x⟫ -corollary: uniqueness +-- TODO: make g part of the notation! +/-- A covariant derivative on `TM` is called the **Levi-Civita connection** for a Riemannian metric +`g` on `M` iff it is torsion-free and compatible with `g`. -/ +def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree --- A choice of Levi-Civita connection on TM: this is unique up to the value on non-differentiable vector fields. --- If you know the Levi-Civita connection already, you can use IsLeviCivitaConnection instead. -def LeviCivitaConnection := sorry - -this is the existence part, I presume +-- This is mild defeq abuse, right? +variable (X Y Z) in +noncomputable abbrev rhs1 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Y Z) x (X x)) +variable (X Y Z) in +noncomputable abbrev rhs2 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Z X) x (Y x)) +variable (X Y Z) in +noncomputable abbrev rhs3 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I X Y) x (Z x)) -lemma : IsLeviCivitaConnection (LeviCivitaConnection) := sorry +-- XXX: inlining even rhs1 makes things not typecheck any more! --/ +-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection. +variable (X Y Z) in +noncomputable def LC_uniqueness_aux : M → ℝ := 1 / 2 * ( + rhs1 I X Y Z + rhs2 I X Y Z + rhs3 I X Y Z + - product I Y (VectorField.mlieBracket I X Z) + - product I Z (VectorField.mlieBracket I X Y) + + product I X (VectorField.mlieBracket I Z Y) + ) + +-- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? +variable (X Y Z) in +/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term +⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ +lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : + product I (cov X Y) Z = LC_uniqueness_aux I X Y Z := by + sorry + +variable {I} in +/-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all +vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ +lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} + (h : ∀ Z : Π x : M, TangentSpace I x, product I X Z = product I X' Z) : X = X' := by + -- any vector bundle with a bundle metric has local orthonormal frames (not just a local frame) + -- -> apply Gram-Schmidt to a local frame; prove orthonormality w.r.t. bundle metric + -- prove: local orthonormal frame is C^k when the bundle metric is + -- use this to prove this lemma + sorry + +/-- The Levi-Civita connection on `(M, g)` is uniquely determined, +at least on differentiable vector fields. -/ +-- (probably not everywhere, as addition rules apply only for differentiable vector fields?) +theorem isLeviCivita_uniqueness {cov cov' : CovariantDerivative I E (TangentSpace I : M → Type _)} + (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) : + -- almost, only agree on smooth functions + cov = cov' := by + ext X σ x + apply congrFun + apply congr_of_forall_product fun Z ↦ ?_ + trans LC_uniqueness_aux I X σ Z + · exact cov.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov + · exact (cov'.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov').symm + +-- TODO: make g part of the notation! +variable (M) in +/-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: +this is unique up to the value on non-differentiable vector fields. +If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ +def LeviCivitaConnection : CovariantDerivative I E (TangentSpace I : M → Type _) := + -- This is the existence part of the proof: take the formula derived above + -- and prove it satisfies all the conditions. + sorry + +lemma foo : (LeviCivitaConnection I M).IsLeviCivitaConnection := sorry + +end CovariantDerivative From f11933abad75805fa63aeb17c6a27fe3b0b027ba Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 6 Jul 2025 18:18:26 +0200 Subject: [PATCH 154/601] More detailed plan for the existence part of the LC connection --- .../VectorBundle/CovariantDerivative.lean | 29 ++++++-- .../Manifold/VectorBundle/LeviCivita.lean | 70 +++++++++++++++++-- 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 9180490901f03a..df5c768d932f20 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -118,16 +118,37 @@ structure CovariantDerivative where smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜), toFun (f • X) σ = f • toFun X σ addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x : M), - MDifferentiableAt% (T% σ) x - → MDifferentiableAt% (T% σ') x + MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), - MDifferentiableAt% (T% σ) x - → MDifferentiableAt% f x + MDifferentiableAt% (T% σ) x → MDifferentiableAt% f x → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) f x (X x)) • σ x smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), toFun X (a • σ) = a • toFun X σ +structure IsCovariantDerivativeOn + (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (s : Set M) : Prop where + -- all the same axioms as CovariantDerivative, but restricted to the set U + addX : ∀ (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x), + ∀ x ∈ s, f (X + X') σ x = f X σ x + f X' σ x + smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜), + ∀ x ∈ s, f (g • X) σ x = g x • f X σ x + addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x), ∀ x ∈ s, + MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x + → f X (σ + σ') x = f X σ x + f X σ' x + leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜), ∀ x ∈ s, + MDifferentiableAt% (T% σ) x → MDifferentiableAt% g x + → f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x + smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), ∀ x ∈ s, + f X (a • σ) x = a • f X σ x + +-- generalise all the lemmas to IsCovariantDerivativeOn + +-- lemma: CovariantDerivative.isCovariantDerivateOn (for any open set) +-- lemma: if f satisfies IsCovariantDerivativeOn univ, it defines a covariant derivative +-- lemma: IsCovariantDerivativeOn.iUnion +-- corollary: if f satisfies `IsCovariantDerivativeOn Ui` for an open cover Ui, it defines a covariant derivative + namespace CovariantDerivative attribute [coe] toFun diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index d53cde373a6d8d..ee3b2c6635a850 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -77,21 +77,31 @@ noncomputable abbrev rhs3 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product -- XXX: inlining even rhs1 makes things not typecheck any more! --- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection. variable (X Y Z) in -noncomputable def LC_uniqueness_aux : M → ℝ := 1 / 2 * ( +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If ∇ is a Levi-Civita connection on `TM`, then +`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ +noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( rhs1 I X Y Z + rhs2 I X Y Z + rhs3 I X Y Z - product I Y (VectorField.mlieBracket I X Z) - product I Z (VectorField.mlieBracket I X Y) + product I X (VectorField.mlieBracket I Z Y) ) +lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) : + leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by + sorry -- easy computation + +lemma leviCivita_rhs_smul (f : M → ℝ) (Z' : Π x : M, TangentSpace I x) : + leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by + sorry -- easy computation + -- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? variable (X Y Z) in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : - product I (cov X Y) Z = LC_uniqueness_aux I X Y Z := by + product I (cov X Y) Z = leviCivita_rhs I X Y Z := by sorry variable {I} in @@ -115,10 +125,57 @@ theorem isLeviCivita_uniqueness {cov cov' : CovariantDerivative I E (TangentSpac ext X σ x apply congrFun apply congr_of_forall_product fun Z ↦ ?_ - trans LC_uniqueness_aux I X σ Z + trans leviCivita_rhs I X σ Z · exact cov.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov · exact (cov'.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov').symm +variable (X Y) in +noncomputable def existence_candidate_aux [FiniteDimensional ℝ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : + (x : M) → TangentSpace I x := fun x ↦ + -- Choose a trivialisation of TM near x. + letI b := Basis.ofVectorSpace ℝ E + --letI t := trivializationAt E (TangentSpace I : M → Type _) x + -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g + -- TODO: this is only a local frame; not orthonormal yet! placeholder definition! + letI frame := b.localFrame e + -- The coefficient of the desired tangent vector ∇ X Y x w.r.t. s i + -- is given by leviCivita_rhs X Y s i. + ∑ i, ((leviCivita_rhs I X Y (frame i)) x) • (frame i x) + +variable (M) in +-- TODO: make g part of the notation! +/-- Given two vector fields X and Y on TM, compute +the candidate definition for the Levi-Civita connection on `TM`. -/ +noncomputable def existence_candidate [FiniteDimensional ℝ E] : + (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := + fun X Y x ↦ + -- -- Choose a trivialisation of TM near x. + -- letI b := Basis.ofVectorSpace ℝ E + letI t := trivializationAt E (TangentSpace I : M → Type _) x + -- -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g + -- -- TODO: this is only a local frame; not orthonormal yet! placeholder definition! + -- letI frame := b.localFrame t + -- -- The coefficient of the desired tangent vector ∇ X Y x w.r.t. s i + -- -- is given by leviCivita_rhs X Y s i. + -- ∑ i, ((leviCivita_rhs I X Y (frame i)) x) • (frame i x) + existence_candidate_aux I X Y t x + +variable (X Y) in +-- The above definition behaves well: for each compatible trivialisation e, +-- using e on e.baseSet yields the same result as above. +lemma foo [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) + [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) : + existence_candidate I M X Y x = existence_candidate_aux I X Y e x := sorry + +-- The candidate definition is a covariant derivative on each local frame's domain. +lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] + (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] : + IsCovariantDerivativeOn I E (TangentSpace I) (existence_candidate I M) e.baseSet := by + sorry + +-- deduce: this defines a covariant derivative + -- TODO: make g part of the notation! variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: @@ -127,8 +184,11 @@ If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnect def LeviCivitaConnection : CovariantDerivative I E (TangentSpace I : M → Type _) := -- This is the existence part of the proof: take the formula derived above -- and prove it satisfies all the conditions. + + -- use isCovariantDerivativeOn_existence_candidate plus (future) API lemmas about + -- IsCovariantDerivativeOn sorry -lemma foo : (LeviCivitaConnection I M).IsLeviCivitaConnection := sorry +lemma bar : (LeviCivitaConnection I M).IsLeviCivitaConnection := sorry end CovariantDerivative From 5b27158afe120c839ab1d84c7e4f9c57a9635d3b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 6 Jul 2025 18:38:11 +0200 Subject: [PATCH 155/601] A bit of computation --- .../Manifold/VectorBundle/LeviCivita.lean | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index ee3b2c6635a850..f87a9fdf9d3bbc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -44,7 +44,7 @@ local notation "⟪" x ", " y "⟫" => inner ℝ x y The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ -variable {X Y Z W : Π x : M, TangentSpace I x} +variable {X X' Y Y' Z Z' : Π x : M, TangentSpace I x} /-- The scalar product of two vector fields -/ noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ ⟪X x, Y x⟫ @@ -75,6 +75,28 @@ noncomputable abbrev rhs2 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product variable (X Y Z) in noncomputable abbrev rhs3 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I X Y) x (Z x)) +variable (X Y Y') in +lemma product_add : product I X (Y + Y') = product I X Y + product I X Y' := sorry + +@[simp] +lemma product_add_left_apply (x : M) : product I (X + X') Y x = product I X Y x + product I X' Y x := sorry + +@[simp] +lemma product_add_right_apply (x : M) : product I X (Y + Y') x = product I X Y x + product I X Y' x := sorry + +variable (X Y Z Z') in +lemma rhs1_add : rhs1 I X Y (Z + Z') = rhs1 I X Y Z + rhs1 I X Y Z' := by + ext x + simp only [rhs1] + -- only holds given enough smoothness! + sorry + +variable (X Y Z Z') in +lemma rhs2_add : rhs2 I X Y (Z + Z') = rhs2 I X Y Z + rhs2 I X Y Z' := sorry + +variable (X Y Z Z') in +lemma rhs3_add : rhs3 I X Y (Z + Z') = rhs3 I X Y Z + rhs3 I X Y Z' := sorry + -- XXX: inlining even rhs1 makes things not typecheck any more! variable (X Y Z) in @@ -88,9 +110,21 @@ noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( + product I X (VectorField.mlieBracket I Z Y) ) -lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) : +lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by - sorry -- easy computation + -- A bit too painful, and have missing differentiability assumptions. + simp only [leviCivita_rhs] + set A : M → ℝ := (1 : M → ℝ) / 2 + rw [← left_distrib] + apply congrArg + simp only [rhs1_add, rhs2_add, rhs3_add] + ext x + have scifi1 : VectorField.mlieBracket I X (Z + Z') = + VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := sorry + have scifi2 : VectorField.mlieBracket I (Z + Z') Y = + VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z' Y := sorry + simp [scifi1, scifi2] + module lemma leviCivita_rhs_smul (f : M → ℝ) (Z' : Π x : M, TangentSpace I x) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by From 1709ded7c7275763237f162f1b2f192d55d1214e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 6 Jul 2025 19:27:09 +0200 Subject: [PATCH 156/601] Small progress --- .../Manifold/VectorBundle/LeviCivita.lean | 82 ++++++++++++++----- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index f87a9fdf9d3bbc..fdcdf2a3962aae 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -69,15 +69,21 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree -- This is mild defeq abuse, right? variable (X Y Z) in -noncomputable abbrev rhs1 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Y Z) x (X x)) -variable (X Y Z) in -noncomputable abbrev rhs2 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Z X) x (Y x)) -variable (X Y Z) in -noncomputable abbrev rhs3 : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I X Y) x (Z x)) +noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Y Z) x (X x)) variable (X Y Y') in lemma product_add : product I X (Y + Y') = product I X Y + product I X Y' := sorry +variable (X Y) in +lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by + ext x + simp [product, real_inner_smul_left] + +variable (X Y) in +lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by + ext x + simp [product, real_inner_smul_right] + @[simp] lemma product_add_left_apply (x : M) : product I (X + X') Y x = product I X Y x + product I X' Y x := sorry @@ -85,17 +91,34 @@ lemma product_add_left_apply (x : M) : product I (X + X') Y x = product I X Y x lemma product_add_right_apply (x : M) : product I X (Y + Y') x = product I X Y x + product I X Y' x := sorry variable (X Y Z Z') in -lemma rhs1_add : rhs1 I X Y (Z + Z') = rhs1 I X Y Z + rhs1 I X Y Z' := by +lemma rhs_aux_addZ : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by ext x - simp only [rhs1] + simp only [rhs_aux] -- only holds given enough smoothness! sorry -variable (X Y Z Z') in -lemma rhs2_add : rhs2 I X Y (Z + Z') = rhs2 I X Y Z + rhs2 I X Y Z' := sorry +variable (X X' Y Z) in +lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by + sorry + +variable (X Y Y' Z) in +lemma rhs_aux_addY : rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by + sorry + +variable (X Y Z) in +lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by + ext x + simp only [rhs_aux] + -- only holds given enough smoothness! + sorry + +variable (X Y Z) in +lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by + sorry variable (X Y Z Z') in -lemma rhs3_add : rhs3 I X Y (Z + Z') = rhs3 I X Y Z + rhs3 I X Y Z' := sorry +lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by + sorry -- XXX: inlining even rhs1 makes things not typecheck any more! @@ -104,30 +127,51 @@ variable (X Y Z) in If ∇ is a Levi-Civita connection on `TM`, then `⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( - rhs1 I X Y Z + rhs2 I X Y Z + rhs3 I X Y Z + rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y - product I Y (VectorField.mlieBracket I X Z) - product I Z (VectorField.mlieBracket I X Y) + product I X (VectorField.mlieBracket I Z Y) ) -lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] : +lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] + (hZ : MDifferentiable% (T% Z)) (hZ' : MDifferentiable% (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by -- A bit too painful, and have missing differentiability assumptions. simp only [leviCivita_rhs] set A : M → ℝ := (1 : M → ℝ) / 2 rw [← left_distrib] apply congrArg - simp only [rhs1_add, rhs2_add, rhs3_add] ext x - have scifi1 : VectorField.mlieBracket I X (Z + Z') = - VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := sorry - have scifi2 : VectorField.mlieBracket I (Z + Z') Y = - VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z' Y := sorry - simp [scifi1, scifi2] + have h1 : VectorField.mlieBracket I X (Z + Z') = + VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := by + ext x + simp [VectorField.mlieBracket_add_right (V := X) (hZ x) (hZ' x)] + have h2 : VectorField.mlieBracket I (Z + Z') Y = + VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z' Y := by + ext x + simp [VectorField.mlieBracket_add_left (W := Y) (hZ x) (hZ' x)] + simp [h1, h2, rhs_aux_addX, rhs_aux_addY, rhs_aux_addZ] module -lemma leviCivita_rhs_smul (f : M → ℝ) (Z' : Π x : M, TangentSpace I x) : +lemma leviCivita_rhs_smul [CompleteSpace E] + (f : M → ℝ) (Z' : Π x : M, TangentSpace I x) (hf : MDifferentiable% f) (hZ : MDifferentiable% (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by + simp only [leviCivita_rhs] + simp [rhs_aux_smulX, rhs_aux_smulY, rhs_aux_smulZ] + ext x + simp only [Pi.mul_apply, Pi.inv_apply, Pi.ofNat_apply, Pi.add_apply, Pi.sub_apply] + -- Only kind of true: get extra mfderiv's, which will cancel in the end... + have h1 : VectorField.mlieBracket I X (f • Z) = + f • VectorField.mlieBracket I X Z := by + ext x + rw [VectorField.mlieBracket_smul_right (hf x) (hZ x)]; simp; sorry + have h2 : VectorField.mlieBracket I (f • Z) Y = + f • VectorField.mlieBracket I Z Y := by + ext x + rw [VectorField.mlieBracket_smul_left (hf x) (hZ x)]; simp; sorry + simp [h1, h2] + rw [product_smul_left, product_smul_right] + simp; abel_nf sorry -- easy computation -- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? From dc50174abdb374cbae2798c99b2e21a5e75b99f7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 6 Jul 2025 23:24:15 +0200 Subject: [PATCH 157/601] Very basic API for local connections --- .../VectorBundle/CovariantDerivative.lean | 100 ++++++++++++++++-- 1 file changed, 91 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index df5c768d932f20..0fb050327ee0c1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -126,28 +126,56 @@ structure CovariantDerivative where smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), toFun X (a • σ) = a • toFun X σ +variable {I} in structure IsCovariantDerivativeOn (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (s : Set M) : Prop where - -- all the same axioms as CovariantDerivative, but restricted to the set U + -- All the same axioms as CovariantDerivative, but restricted to the set s. addX : ∀ (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x), ∀ x ∈ s, f (X + X') σ x = f X σ x + f X' σ x smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜), ∀ x ∈ s, f (g • X) σ x = g x • f X σ x - addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x), ∀ x ∈ s, + addσ : ∀ (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x}, ∀ x ∈ s, MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x → f X (σ + σ') x = f X σ x + f X σ' x - leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜), ∀ x ∈ s, + leibniz : ∀ (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {g : M → 𝕜}, ∀ x ∈ s, MDifferentiableAt% (T% σ) x → MDifferentiableAt% g x → f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), ∀ x ∈ s, f X (a • σ) x = a • f X σ x --- generalise all the lemmas to IsCovariantDerivativeOn +variable {I F V} --- lemma: CovariantDerivative.isCovariantDerivateOn (for any open set) --- lemma: if f satisfies IsCovariantDerivativeOn univ, it defines a covariant derivative --- lemma: IsCovariantDerivativeOn.iUnion --- corollary: if f satisfies `IsCovariantDerivativeOn Ui` for an open cover Ui, it defines a covariant derivative +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +lemma IsCovariantDerivativeOn.mono + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s t : Set M} + (hf : IsCovariantDerivativeOn F V f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F V f s where + addX X X' σ x hx := hf.addX X X' σ x (hst hx) + smulX X σ f x hx := hf.smulX X σ f x (hst hx) + addσ X {_σ _σ'} x hx hσ hσ' := hf.addσ X x (hst hx) hσ hσ' + leibniz X {_ _} _ hx hσ hf' := hf.leibniz X _ (hst hx) hσ hf' + smul_const_σ X σ a x hx := hf.smul_const_σ X σ a x (hst hx) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +lemma IsCovariantDerivativeOn.iUnion {ι : Type*} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : ι → Set M} + (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) : IsCovariantDerivativeOn F V f (⋃ i, s i) where + addX X X' σ x hx := by + obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx + exact (hf i).addX _ _ _ _ hxsi + smulX X σ f x hx := by + obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx + exact (hf i).smulX _ _ _ _ hxsi + addσ X σ σ' x hx hσ hσ' := by + obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx + exact (hf i).addσ _ _ hxsi hσ hσ' + leibniz X σ f x hx hσ hf' := by + obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx + exact (hf i).leibniz _ _ hxsi hσ hf' + smul_const_σ X σ a x hx := by + obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx + exact (hf i).smul_const_σ _ _ _ _ hxsi namespace CovariantDerivative @@ -158,7 +186,61 @@ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := ⟨fun e ↦ e.toFun⟩ -variable {I F V} +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +lemma isCovariantDerivativeOn_univ (cov : CovariantDerivative I F V) : + IsCovariantDerivativeOn F V cov Set.univ where + addX X X' σ x _ := by simp [cov.addX] + smulX X σ f x _ := by simp [cov.smulX] + addσ X σ σ' x _ hσ hσ' := cov.addσ _ _ _ _ hσ hσ' + leibniz X σ f x _ hσ hf := cov.leibniz X _ _ _ hσ hf + smul_const_σ X σ a x _ := by simp [cov.smul_const_σ X σ a] + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +lemma isCovariantDerivativeOn (cov : CovariantDerivative I F V) {s : Set M} : + IsCovariantDerivativeOn F V cov s := by + apply (cov.isCovariantDerivativeOn_univ).mono (fun ⦃a⦄ a ↦ trivial) + +/-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant on `Set.univ`, it is a covariant derivative. -/ +def of_isCovariantDerivativeOn_univ + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : IsCovariantDerivativeOn F V f Set.univ) : CovariantDerivative I F V where + toFun := f + addX X X' σ := by ext; simp [hf.addX X X' σ] + smulX X σ g := by ext; simp [hf.smulX X σ] + addσ X σ σ' x hσ hf' := hf.addσ _ _ trivial hσ hf' + leibniz X σ f x hσ hf' := hf.leibniz X x trivial hσ hf' + smul_const_σ X σ a := by ext; simp [hf.smul_const_σ X σ a] + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +@[simp] +lemma of_isCovariantDerivativeOn_univ_coe + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : IsCovariantDerivativeOn F V f Set.univ) : + of_isCovariantDerivativeOn_univ hf = f := rfl + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +/-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant derivative on each set in an open cover, +it is a covariant derivative. -/ +def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) (hs : ⋃ i, s i = Set.univ) : + CovariantDerivative I F V := + of_isCovariantDerivativeOn_univ (hs ▸ IsCovariantDerivativeOn.iUnion hf) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +@[simp] +lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set M} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) (hs : ⋃ i, s i = Set.univ) : + of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl + +-- TODO: generalise all the lemmas below to IsCovariantDerivativeOn + /-- A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. From d46c57dd93a57b6c5d9b5dc917d1fe920b5662cd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 6 Jul 2025 23:58:23 +0200 Subject: [PATCH 158/601] Further computation: too painful, needs refactoring --- .../VectorBundle/CovariantDerivative.lean | 16 +++++ .../Manifold/VectorBundle/LeviCivita.lean | 72 ++++++++++++------- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 0fb050327ee0c1..1bfb8e3162f979 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1022,6 +1022,22 @@ def IsTorsionFree : Prop := torsion cov = 0 lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] +-- This should be obvious, I'm doing something wrong. +lemma isTorsionFree_iff : IsTorsionFree cov ↔ + ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by + simp [IsTorsionFree] + constructor + · intro h + intro X Y + have : torsion cov X Y = 0 := sorry + rw [torsion] at this + sorry + · intro h + ext X Y x + specialize h X Y + apply congr_fun + simp_all [torsion] + -- lemma the trivial connection on a normed space is torsion-free -- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index fdcdf2a3962aae..a175ca27fba508 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -71,6 +71,51 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree variable (X Y Z) in noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Y Z) x (X x)) +-- XXX: inlining rhs_aux makes things not typecheck any more! + +variable (X Y Z) in +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If ∇ is a Levi-Civita connection on `TM`, then +`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ +noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( + rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y + - product I Y (VectorField.mlieBracket I X Z) + - product I Z (VectorField.mlieBracket I X Y) + + product I X (VectorField.mlieBracket I Z Y) + ) + +variable (X Y Z) in +lemma aux (h : cov.IsLeviCivitaConnection) (x : M) : rhs_aux I X Y Z x = + ⟪cov X Y x, Z x⟫ + ⟪Y x, cov Z X x⟫ + product I Y (VectorField.mlieBracket I X Z) x := by + unfold rhs_aux + have : ⟪Y x, cov X Z x⟫ - ⟪Y x, cov Z X x⟫ = product I Y (VectorField.mlieBracket I X Z) x := by + have := h.2 + rw [isTorsionFree_iff] at this + specialize this X Y + simp only [product] + trans ⟪Y x, cov X Z x - cov Z X x⟫ + · sorry -- product is linear... + sorry -- congr_fun/congr_arg + have : ⟪Y x, cov X Z x⟫ = ⟪Y x, cov Z X x⟫ + product I Y (VectorField.mlieBracket I X Z) x := by + sorry + trans ⟪cov X Y x, Z x⟫ + ⟪Y x, cov X Z x⟫ + · apply h.1 X Y Z + · simp [this, add_assoc] + +-- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? +variable (X Y Z) in +/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term +⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ +lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : + product I (cov X Y) Z = leviCivita_rhs I X Y Z := by + have eq1 (x) := aux I X Y Z cov h x + have eq2 (x) := aux I Y Z X cov h x + have eq3 (x) := aux I Z X Y cov h x + -- add (I) + (II) and subtract (III) + + -- solve for product I (cov X Y) Z + sorry + variable (X Y Y') in lemma product_add : product I X (Y + Y') = product I X Y + product I X Y' := sorry @@ -120,19 +165,6 @@ variable (X Y Z Z') in lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by sorry --- XXX: inlining even rhs1 makes things not typecheck any more! - -variable (X Y Z) in -/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: -If ∇ is a Levi-Civita connection on `TM`, then -`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ -noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( - rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y - - product I Y (VectorField.mlieBracket I X Z) - - product I Z (VectorField.mlieBracket I X Y) - + product I X (VectorField.mlieBracket I Z Y) - ) - lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] (hZ : MDifferentiable% (T% Z)) (hZ' : MDifferentiable% (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by @@ -153,8 +185,8 @@ lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] simp [h1, h2, rhs_aux_addX, rhs_aux_addY, rhs_aux_addZ] module -lemma leviCivita_rhs_smul [CompleteSpace E] - (f : M → ℝ) (Z' : Π x : M, TangentSpace I x) (hf : MDifferentiable% f) (hZ : MDifferentiable% (T% Z)) : +lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} + (hf : MDifferentiable% f) (hZ : MDifferentiable% (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs] simp [rhs_aux_smulX, rhs_aux_smulY, rhs_aux_smulZ] @@ -174,14 +206,6 @@ lemma leviCivita_rhs_smul [CompleteSpace E] simp; abel_nf sorry -- easy computation --- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? -variable (X Y Z) in -/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term -⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ -lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : - product I (cov X Y) Z = leviCivita_rhs I X Y Z := by - sorry - variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ @@ -249,7 +273,7 @@ lemma foo [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn I E (TangentSpace I) (existence_candidate I M) e.baseSet := by + IsCovariantDerivativeOn E (TangentSpace I) (existence_candidate I M) e.baseSet := by sorry -- deduce: this defines a covariant derivative From 0543ca89a94f7be52ee175505b64c1615abb5e66 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 11:59:58 +0200 Subject: [PATCH 159/601] Clean-up: re-purpose notation <, > for the pairing of vector fields --- .../Manifold/VectorBundle/LeviCivita.lean | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index a175ca27fba508..061cee97c605d0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -37,8 +37,6 @@ variable {n : WithTop ℕ∞} variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] -local notation "⟪" x ", " y "⟫" => inner ℝ x y - /-! Compatible connections: a connection on TM is compatible with the metric on M iff `∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all vector fields X, Y and Z on `M`. The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: @@ -47,9 +45,11 @@ the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ variable {X X' Y Y' Z Z' : Π x : M, TangentSpace I x} /-- The scalar product of two vector fields -/ -noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ ⟪X x, Y x⟫ +noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ inner ℝ (X x) (Y x) -- Riemannian.lean shows that `product` is C^k if X and Y are +local notation "⟪" X ", " Y "⟫" => product I X Y + namespace CovariantDerivative -- Let `cov` be a covariant derivative on `TM`. @@ -60,7 +60,7 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) def IsCompatible : Prop := ∀ X Y Z : Π x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! ∀ x : M, - mfderiv I 𝓘(ℝ) (product I Y Z) x (X x) = ⟪cov X Y x, Z x⟫ + ⟪Y x, cov X Z x⟫ + mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x) = ⟪cov X Y, Z⟫ x + ⟪Y, cov X Z⟫ x -- TODO: make g part of the notation! /-- A covariant derivative on `TM` is called the **Levi-Civita connection** for a Riemannian metric @@ -69,7 +69,7 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree -- This is mild defeq abuse, right? variable (X Y Z) in -noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) (product I Y Z) x (X x)) +noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x)) -- XXX: inlining rhs_aux makes things not typecheck any more! @@ -79,35 +79,36 @@ If ∇ is a Levi-Civita connection on `TM`, then `⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y - - product I Y (VectorField.mlieBracket I X Z) - - product I Z (VectorField.mlieBracket I X Y) - + product I X (VectorField.mlieBracket I Z Y) + - ⟪Y ,(VectorField.mlieBracket I X Z)⟫ + - ⟪Z, (VectorField.mlieBracket I X Y)⟫ + + ⟪X, (VectorField.mlieBracket I Z Y)⟫ ) variable (X Y Z) in -lemma aux (h : cov.IsLeviCivitaConnection) (x : M) : rhs_aux I X Y Z x = - ⟪cov X Y x, Z x⟫ + ⟪Y x, cov Z X x⟫ + product I Y (VectorField.mlieBracket I X Z) x := by +lemma aux (h : cov.IsLeviCivitaConnection) (x : M) : rhs_aux I X Y Z = + ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by unfold rhs_aux - have : ⟪Y x, cov X Z x⟫ - ⟪Y x, cov Z X x⟫ = product I Y (VectorField.mlieBracket I X Z) x := by + have : ⟪Y, cov X Z⟫ - ⟪Y, cov Z X⟫ = ⟪Y, VectorField.mlieBracket I X Z⟫ := by + ext x have := h.2 rw [isTorsionFree_iff] at this specialize this X Y simp only [product] - trans ⟪Y x, cov X Z x - cov Z X x⟫ + sorry /-trans ⟪Y x, cov X Z x - cov Z X x⟫ · sorry -- product is linear... - sorry -- congr_fun/congr_arg - have : ⟪Y x, cov X Z x⟫ = ⟪Y x, cov Z X x⟫ + product I Y (VectorField.mlieBracket I X Z) x := by - sorry - trans ⟪cov X Y x, Z x⟫ + ⟪Y x, cov X Z x⟫ - · apply h.1 X Y Z - · simp [this, add_assoc] + sorry -- congr_fun/congr_arg -/ + --have : ⟪Y x, cov X Z x⟫ = ⟪Y x, cov Z X x⟫ + product I Y (VectorField.mlieBracket I X Z) x := by + -- sorry + trans ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ + · sorry -- apply h.1 X Y Z + · sorry -- simp [this, add_assoc] -- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? variable (X Y Z) in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : - product I (cov X Y) Z = leviCivita_rhs I X Y Z := by + ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by have eq1 (x) := aux I X Y Z cov h x have eq2 (x) := aux I Y Z X cov h x have eq3 (x) := aux I Z X Y cov h x @@ -210,7 +211,7 @@ variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} - (h : ∀ Z : Π x : M, TangentSpace I x, product I X Z = product I X' Z) : X = X' := by + (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by -- any vector bundle with a bundle metric has local orthonormal frames (not just a local frame) -- -> apply Gram-Schmidt to a local frame; prove orthonormality w.r.t. bundle metric -- prove: local orthonormal frame is C^k when the bundle metric is From 5e0a4964b2cd4c110f9a0920e6aef16444a261bc Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 12:36:48 +0200 Subject: [PATCH 160/601] Progress on LeviCivita computation --- .../Manifold/VectorBundle/LeviCivita.lean | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 061cee97c605d0..2c2427c70eadb5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -50,6 +50,15 @@ noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := f local notation "⟪" X ", " Y "⟫" => product I X Y +variable (X) in +@[simp] +lemma product_zero_right : ⟪X, 0⟫ = 0 := sorry + +@[simp] +lemma product_zero_left : ⟪0, X⟫ = 0 := sorry + +lemma product_sub_right : ⟪X, Y - Z⟫ = ⟪X, Y⟫ - ⟪X, Z⟫ := sorry + namespace CovariantDerivative -- Let `cov` be a covariant derivative on `TM`. @@ -85,23 +94,14 @@ noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( ) variable (X Y Z) in -lemma aux (h : cov.IsLeviCivitaConnection) (x : M) : rhs_aux I X Y Z = +lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by - unfold rhs_aux - have : ⟪Y, cov X Z⟫ - ⟪Y, cov Z X⟫ = ⟪Y, VectorField.mlieBracket I X Z⟫ := by - ext x - have := h.2 - rw [isTorsionFree_iff] at this - specialize this X Y - simp only [product] - sorry /-trans ⟪Y x, cov X Z x - cov Z X x⟫ - · sorry -- product is linear... - sorry -- congr_fun/congr_arg -/ - --have : ⟪Y x, cov X Z x⟫ = ⟪Y x, cov Z X x⟫ + product I Y (VectorField.mlieBracket I X Z) x := by - -- sorry + have : ⟪Y, cov X Z - cov Z X⟫ = ⟪Y, VectorField.mlieBracket I X Z⟫ := by + simp [isTorsionFree_iff.mp h.2 X Z] trans ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ - · sorry -- apply h.1 X Y Z - · sorry -- simp [this, add_assoc] + · ext x + exact h.1 X Y Z x + · simp [← this, product_sub_right] -- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? variable (X Y Z) in @@ -109,12 +109,12 @@ variable (X Y Z) in ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by - have eq1 (x) := aux I X Y Z cov h x - have eq2 (x) := aux I Y Z X cov h x - have eq3 (x) := aux I Z X Y cov h x + have eq1 := aux I X Y Z cov h + have eq2 := aux I Y Z X cov h + have eq3 := aux I Z X Y cov h -- add (I) + (II) and subtract (III) - -- solve for product I (cov X Y) Z + -- solve for ⟪cov X Y, Z⟫ sorry variable (X Y Y') in From 74aca18cca32ed6e6d451411186c064e128b791d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 14:11:33 +0200 Subject: [PATCH 161/601] chore(MDifferentiableAt): align names with ContMDiffAt --- .../VectorBundle/MDifferentiable.lean | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 76e95f4f72d661..2c3807fc674023 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -80,16 +80,16 @@ theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] - [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] + [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] --- TODO: compare with ContMDiffWithinAt.change_section_trivialization - -lemma MDifferentiableWithinAt.coordChange +-- FIXME: should this (and ContMDiffWithinAt.change_section_trivialization) +-- be named `coordChange` instead? +lemma MDifferentiableWithinAt.change_section_trivialization {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) - (hf : MDifferentiableWithinAt IM IB (fun x ↦ (f x).proj) s x₀) + (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) (he'f : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀) : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ := by have : ∀ᶠ x in 𝓝[s] x₀, (e (f x)).2 = e'.coordChangeL 𝕜 e (f x).proj (e' (f x)).2 := by @@ -107,23 +107,25 @@ lemma MDifferentiableWithinAt.coordChange exact bar.clm_apply he'f rw [e'.coordChangeL_apply e ⟨he'x₀, hex₀⟩, e'.symm_proj_apply (f x₀) he'x₀] -theorem mdifferentiableWithinAt_coordChange +theorem mdifferentiableWithinAt_change_section_trivialization {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) - (hf : MDifferentiableWithinAt IM IB (fun x ↦ (f x).proj) s x₀) : + (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ ↔ MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := - ⟨hf.coordChange IB e he'x₀ hex₀, hf.coordChange IB e' hex₀ he'x₀⟩ + ⟨hf.change_section_trivialization IB e he'x₀ hex₀, + hf.change_section_trivialization IB e' hex₀ he'x₀⟩ -theorem mdifferentiableAt_change_triv +theorem mdifferentiableAt_change_section_trivialization {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {x₀ : M} (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) (hf : MDifferentiableAt IM IB (fun x ↦ (f x).proj) x₀) : MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) x₀ ↔ MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) x₀ := by - simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_coordChange IB hex₀ he'x₀ hf + simpa [← mdifferentiableWithinAt_univ] using + mdifferentiableWithinAt_change_section_trivialization IB hex₀ he'x₀ hf /-- Characterization of differentiable functions into a vector bundle in terms of any trivialization. Version at a point within at set. -/ @@ -138,7 +140,8 @@ theorem Trivialization.mdifferentiableWithinAt_totalSpace_iff rw [mdifferentiableWithinAt_totalSpace] apply and_congr_right intro hf - rw [mdifferentiableWithinAt_coordChange IB hex₀ (FiberBundle.mem_baseSet_trivializationAt' _) hf] + rw [mdifferentiableWithinAt_change_section_trivialization IB hex₀ + (FiberBundle.mem_baseSet_trivializationAt' _) hf] /-- Characterization of differentiable functions into a vector bundle in terms of any trivialization. Version at a point. -/ @@ -153,7 +156,8 @@ theorem Trivialization.mdifferentiableAt_totalSpace_iff rw [mdifferentiableAt_totalSpace] apply and_congr_right intro hf - rw [mdifferentiableAt_change_triv IB hex₀ (FiberBundle.mem_baseSet_trivializationAt' _) hf] + rw [mdifferentiableAt_change_section_trivialization IB hex₀ + (FiberBundle.mem_baseSet_trivializationAt' _) hf] /-- Characterization of differentiable sections a vector bundle in terms of any trivialization. Version at a point within at set. -/ From c35ba365c6accc9375032b048a0d5538934ff692 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 14:47:12 +0200 Subject: [PATCH 162/601] chore(VectorBundle/Basic): minor clean-ups and polish --- .../Geometry/Manifold/VectorBundle/Basic.lean | 17 +++++++++-------- .../Manifold/VectorBundle/MDifferentiable.lean | 5 ++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 703dcdc2e0e317..b34ab63263b878 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -176,7 +176,8 @@ bundle at all, just that it is a fiber bundle over a charted base space. namespace Bundle -/-- Characterization of `C^n` functions into a vector bundle. -/ +/-- Characterization of `C^n` functions into a vector bundle. +Version at a point within a set. -/ theorem contMDiffWithinAt_totalSpace {f : M → TotalSpace F E} {s : Set M} {x₀ : M} : ContMDiffWithinAt IM (IB.prod 𝓘(𝕜, F)) n f s x₀ ↔ ContMDiffWithinAt IM IB n (fun x => (f x).proj) s x₀ ∧ @@ -197,7 +198,7 @@ theorem contMDiffWithinAt_totalSpace {f : M → TotalSpace F E} {s : Set M} {x exact hx · simp only [mfld_simps] -/-- Characterization of `C^n` functions into a vector bundle. -/ +/-- Characterization of `C^n` functions into a vector bundle. Version at a point. -/ theorem contMDiffAt_totalSpace {f : M → TotalSpace F E} {x₀ : M} : ContMDiffAt IM (IB.prod 𝓘(𝕜, F)) n f x₀ ↔ ContMDiffAt IM IB n (fun x ↦ (f x).proj) x₀ ∧ @@ -216,7 +217,6 @@ theorem contMDiffAt_section {s : ∀ x, E x} (x₀ : B) : ContMDiffAt IB 𝓘(𝕜, F) n (fun x ↦ (trivializationAt F E x₀ ⟨x, s x⟩).2) x₀ := by simp_rw [contMDiffAt_totalSpace, and_iff_right_iff_imp]; intro; exact contMDiffAt_id - variable (E) theorem contMDiff_proj : ContMDiff (IB.prod 𝓘(𝕜, F)) IB n (π F E) := fun x ↦ by @@ -226,21 +226,22 @@ theorem contMDiff_proj : ContMDiff (IB.prod 𝓘(𝕜, F)) IB n (π F E) := fun theorem contMDiffOn_proj {s : Set (TotalSpace F E)} : ContMDiffOn (IB.prod 𝓘(𝕜, F)) IB n (π F E) s := - (Bundle.contMDiff_proj E).contMDiffOn + (contMDiff_proj E).contMDiffOn theorem contMDiffAt_proj {p : TotalSpace F E} : ContMDiffAt (IB.prod 𝓘(𝕜, F)) IB n (π F E) p := - (Bundle.contMDiff_proj E).contMDiffAt + (contMDiff_proj E).contMDiffAt theorem contMDiffWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace F E} : ContMDiffWithinAt (IB.prod 𝓘(𝕜, F)) IB n (π F E) s p := - (Bundle.contMDiffAt_proj E).contMDiffWithinAt + (contMDiffAt_proj E).contMDiffWithinAt variable (𝕜) [∀ x, AddCommMonoid (E x)] variable [∀ x, Module 𝕜 (E x)] [VectorBundle 𝕜 F E] -theorem contMDiff_zeroSection : ContMDiff IB (IB.prod 𝓘(𝕜, F)) n (zeroSection F E) := fun x ↦ by +theorem contMDiff_zeroSection : ContMDiff IB (IB.prod 𝓘(𝕜, F)) n (zeroSection F E) := by + intro x unfold zeroSection - rw [Bundle.contMDiffAt_section] + rw [contMDiffAt_section] apply (contMDiffAt_const (c := 0)).congr_of_eventuallyEq filter_upwards [(trivializationAt F E x).open_baseSet.mem_nhds (mem_baseSet_trivializationAt F E x)] with y hy diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 2c3807fc674023..bc9ea587a29f66 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -34,7 +34,8 @@ variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup F] [NormedSpace 𝕜 variable [TopologicalSpace B] [ChartedSpace HB B] [FiberBundle F E] -/-- Characterization of differentiable functions into a vector bundle. -/ +/-- Characterization of differentiable functions into a vector bundle. +Version at a point within a set -/ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M} {x₀ : M} : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ MDifferentiableWithinAt IM IB (fun x => (f x).proj) s x₀ ∧ @@ -56,6 +57,8 @@ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M exact hx · simp only [mfld_simps] +/-- Characterization of differentiable functions into a vector bundle. +Version at a point -/ theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ From a4dece24c3cc74233621633bc4e7284e4f6d69bd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 14:50:13 +0200 Subject: [PATCH 163/601] feat: copy some MDifferentiableAt API --- .../VectorBundle/MDifferentiable.lean | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index bc9ea587a29f66..a48bfda54ad485 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -82,6 +82,53 @@ theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ +namespace Bundle + +variable (E) {IB} + +theorem mdifferentiable_proj : MDifferentiable (IB.prod 𝓘(𝕜, F)) IB (π F E) := fun x ↦ by + have : MDifferentiableAt (IB.prod 𝓘(𝕜, F)) (IB.prod 𝓘(𝕜, F)) id x := mdifferentiableAt_id + rw [mdifferentiableAt_totalSpace] at this + exact this.1 + +theorem mdifferentiableOn_proj {s : Set (TotalSpace F E)} : + MDifferentiableOn (IB.prod 𝓘(𝕜, F)) IB (π F E) s := + (mdifferentiable_proj E).mdifferentiableOn + +theorem mdifferentiableAt_proj {p : TotalSpace F E} : + MDifferentiableAt (IB.prod 𝓘(𝕜, F)) IB (π F E) p := + (mdifferentiable_proj E).mdifferentiableAt + +theorem mdifferentiableWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace F E} : + MDifferentiableWithinAt (IB.prod 𝓘(𝕜, F)) IB (π F E) s p := + (mdifferentiableAt_proj E).mdifferentiableWithinAt + +variable (𝕜) [∀ x, AddCommMonoid (E x)] +variable [∀ x, Module 𝕜 (E x)] [VectorBundle 𝕜 F E] + +theorem mdifferentiable_zeroSection : MDifferentiable IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) := by + intro x + unfold zeroSection + rw [mdifferentiableAt_section] + apply (mdifferentiableAt_const (c := 0)).congr_of_eventuallyEq + filter_upwards [(trivializationAt F E x).open_baseSet.mem_nhds + (mem_baseSet_trivializationAt F E x)] with y hy + using congr_arg Prod.snd <| (trivializationAt F E x).zeroSection 𝕜 hy + +theorem mdifferentiableOn_zeroSection {t : Set B} : + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) t := + (mdifferentiable_zeroSection _ _).mdifferentiableOn + +theorem mdifferentiableAt_zeroSection {x : B} : + MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) x := + (mdifferentiable_zeroSection _ _).mdifferentiableAt + +theorem mdifferentiableWithinAt_zeroSection {t : Set B} {x : B} : + MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) t x := + (mdifferentiable_zeroSection _ _ x).mdifferentiableWithinAt + +end Bundle + variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] From c56d34e6480b132ae368046b705c68f6ce1e62da Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 15:11:21 +0200 Subject: [PATCH 164/601] chore: add API for coordChange being mdifferentiable This matches the file on ContMDiff and hopefully allows golfing the subsequent proofs. --- .../VectorBundle/MDifferentiable.lean | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index a48bfda54ad485..e79bd3b18378a4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -129,6 +129,99 @@ theorem mdifferentiableWithinAt_zeroSection {t : Set B} {x : B} : end Bundle +section coordChange + +variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] +variable (e e' : Trivialization F (π F E)) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] + [VectorBundle 𝕜 F E] [ContMDiffVectorBundle n F E IB] (hn : 1 ≤ n) +variable {IB} + +include hn in +theorem mdifferentiableOn_coordChangeL : + MDifferentiableOn IB 𝓘(𝕜, F →L[𝕜] F) (fun b : B => (e.coordChangeL 𝕜 e' b : F →L[𝕜] F)) + (e.baseSet ∩ e'.baseSet) := + (contMDiffOn_coordChangeL e e').mdifferentiableOn (n := n) (hn := by simp [hn]) + +include hn in +theorem mdifferentiableOn_symm_coordChangeL : + MDifferentiableOn IB 𝓘(𝕜, F →L[𝕜] F) (fun b : B => ((e.coordChangeL 𝕜 e' b).symm : F →L[𝕜] F)) + (e.baseSet ∩ e'.baseSet) := by + rw [inter_comm] + refine (mdifferentiableOn_coordChangeL e' e hn).congr fun b hb ↦ ?_ + rw [e.symm_coordChangeL e' hb] + +variable {e e'} + +theorem mdifferentiableAt_coordChangeL {x : B} + (h : x ∈ e.baseSet) (h' : x ∈ e'.baseSet) (hn : 1 ≤ n) : + MDifferentiableAt IB 𝓘(𝕜, F →L[𝕜] F) (fun b : B => (e.coordChangeL 𝕜 e' b : F →L[𝕜] F)) x := + (mdifferentiableOn_coordChangeL e e' hn).mdifferentiableAt <| + (e.open_baseSet.inter e'.open_baseSet).mem_nhds ⟨h, h'⟩ + +variable {s : Set M} {f : M → B} {g : M → F} {x : M} + +protected theorem MDifferentiableWithinAt.coordChangeL (hf : MDifferentiableWithinAt IM IB f s x) + (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) (hn : 1 ≤ n) : + MDifferentiableWithinAt IM 𝓘(𝕜, F →L[𝕜] F) + (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) s x := + (mdifferentiableAt_coordChangeL he he' hn).comp_mdifferentiableWithinAt _ hf + +include hn in +protected nonrec theorem MDifferentiableAt.coordChangeL + (hf : MDifferentiableAt IM IB f x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : + MDifferentiableAt IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) x := + MDifferentiableWithinAt.coordChangeL hf he he' hn + -- TODO: why no dot notation? + +include hn in +protected theorem MDifferentiableOn.coordChangeL + (hf : MDifferentiableOn IM IB f s) (he : MapsTo f s e.baseSet) (he' : MapsTo f s e'.baseSet) : + MDifferentiableOn IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) s := + fun x hx ↦ (hf x hx).coordChangeL (he hx) (he' hx) hn + +include hn in +protected theorem MDifferentiable.coordChangeL + (hf : MDifferentiable IM IB f) (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : + MDifferentiable IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) := fun x ↦ + (hf x).coordChangeL hn (he x) (he' x) + +include hn in +protected theorem MDifferentiableWithinAt.coordChange + (hf : MDifferentiableWithinAt IM IB f s x) (hg : MDifferentiableWithinAt IM 𝓘(𝕜, F) g s x) + (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : + MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) s x := by + refine ((hf.coordChangeL he he' hn).clm_apply hg).congr_of_eventuallyEq ?_ ?_ + · have : e.baseSet ∩ e'.baseSet ∈ 𝓝 (f x) := + (e.open_baseSet.inter e'.open_baseSet).mem_nhds ⟨he, he'⟩ + filter_upwards [hf.continuousWithinAt this] with y hy + exact (Trivialization.coordChangeL_apply' e e' hy (g y)).symm + · exact (Trivialization.coordChangeL_apply' e e' ⟨he, he'⟩ (g x)).symm + +include hn in +protected nonrec theorem MDifferentiableAt.coordChange + (hf : MDifferentiableAt IM IB f x) (hg : MDifferentiableAt IM 𝓘(𝕜, F) g x) + (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : + MDifferentiableAt IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) x := + MDifferentiableWithinAt.coordChange hn hf hg he he' -- TODO: why no dot notation? + +include hn in +protected theorem MDifferentiableOn.coordChange + (hf : MDifferentiableOn IM IB f s) (hg : MDifferentiableOn IM 𝓘(𝕜, F) g s) + (he : MapsTo f s e.baseSet) (he' : MapsTo f s e'.baseSet) : + MDifferentiableOn IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) s := fun x hx ↦ + (hf x hx).coordChange hn (hg x hx) (he hx) (he' hx) + +include hn in +protected theorem MDifferentiable.coordChange + (hf : MDifferentiable IM IB f) (hg : MDifferentiable IM 𝓘(𝕜, F) g) + (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : + MDifferentiable IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) := fun x ↦ + (hf x).coordChange hn (hg x) (he x) (he' x) + +variable (e e') + +end coordChange + variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] From 41c5f598870ead90d3a4a76c802ffc2ea127c7dd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 15:46:00 +0200 Subject: [PATCH 165/601] chore: golf using the new API; synchronise names --- .../VectorBundle/MDifferentiable.lean | 59 ++++++++----------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index e79bd3b18378a4..d6308dc97db1e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -218,8 +218,6 @@ protected theorem MDifferentiable.coordChange MDifferentiable IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) := fun x ↦ (hf x).coordChange hn (hg x) (he x) (he' x) -variable (e e') - end coordChange variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] @@ -229,53 +227,46 @@ variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] -- be named `coordChange` instead? lemma MDifferentiableWithinAt.change_section_trivialization {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] - (e' : Trivialization F TotalSpace.proj) [MemTrivializationAtlas e'] + {e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} - (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) - (he'f : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀) : - MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ := by - have : ∀ᶠ x in 𝓝[s] x₀, (e (f x)).2 = e'.coordChangeL 𝕜 e (f x).proj (e' (f x)).2 := by - have mem : ∀ᶠ x in 𝓝[s] x₀, (f x).proj ∈ e'.baseSet ∩ e.baseSet := by - exact hf.continuousWithinAt <| - (e'.open_baseSet.eventually_mem he'x₀).and (e.open_baseSet.eventually_mem hex₀) - filter_upwards [mem] with x hx - rw [e'.coordChangeL_apply e hx, e'.symm_proj_apply (f x) hx.1] - apply Filter.EventuallyEq.mdifferentiableWithinAt_iff this ?_ |>.1 - · let c := Trivialization.coordChangeL 𝕜 e' e - have bar : MDifferentiableWithinAt IM 𝓘(𝕜, F →L[𝕜] F) - (fun x : M ↦ (c (f x).proj : F →L[𝕜] F)) s x₀ := by - exact contMDiffAt_coordChangeL he'x₀ hex₀ |>.mdifferentiableAt le_rfl - |>.comp_mdifferentiableWithinAt x₀ hf - exact bar.clm_apply he'f - rw [e'.coordChangeL_apply e ⟨he'x₀, hex₀⟩, e'.symm_proj_apply (f x₀) he'x₀] - -theorem mdifferentiableWithinAt_change_section_trivialization + (he'f : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀) + (he : f x₀ ∈ e.source) (he' : f x₀ ∈ e'.source) : + MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := by + rw [Trivialization.mem_source] at he he' + refine (hf.coordChange le_rfl he'f he he').congr_of_eventuallyEq ?_ ?_ + · filter_upwards [hf.continuousWithinAt (e.open_baseSet.mem_nhds he)] with y hy + rw [Function.comp_apply, e.coordChange_apply_snd e' hy] + · rw [Function.comp_apply, e.coordChange_apply_snd _ he] + +theorem Trivialization.mdifferentiableWithinAt_snd_comp_iff₂ {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} - (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) + (hex₀ : f x₀ ∈ e.source) (he'x₀ : f x₀ ∈ e'.source) (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ ↔ MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := - ⟨hf.change_section_trivialization IB e he'x₀ hex₀, - hf.change_section_trivialization IB e' hex₀ he'x₀⟩ + ⟨(hf.change_section_trivialization IB · hex₀ he'x₀), + (hf.change_section_trivialization IB · he'x₀ hex₀)⟩ + +variable (e e') theorem mdifferentiableAt_change_section_trivialization {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {x₀ : M} - (hex₀ : (f x₀).proj ∈ e.baseSet) (he'x₀ : (f x₀).proj ∈ e'.baseSet) + (he : f x₀ ∈ e.source) (he' : f x₀ ∈ e'.source) (hf : MDifferentiableAt IM IB (fun x ↦ (f x).proj) x₀) : MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) x₀ ↔ MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) x₀ := by simpa [← mdifferentiableWithinAt_univ] using - mdifferentiableWithinAt_change_section_trivialization IB hex₀ he'x₀ hf + e.mdifferentiableWithinAt_snd_comp_iff₂ IB he he' hf /-- Characterization of differentiable functions into a vector bundle in terms of any trivialization. Version at a point within at set. -/ theorem Trivialization.mdifferentiableWithinAt_totalSpace_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (f : M → TotalSpace F E) {s : Set M} {x₀ : M} - (hex₀ : (f x₀).proj ∈ e.baseSet) : + (he : f x₀ ∈ e.source) : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ MDifferentiableWithinAt IM IB (fun x => (f x).proj) s x₀ ∧ MDifferentiableWithinAt IM 𝓘(𝕜, F) @@ -283,15 +274,15 @@ theorem Trivialization.mdifferentiableWithinAt_totalSpace_iff rw [mdifferentiableWithinAt_totalSpace] apply and_congr_right intro hf - rw [mdifferentiableWithinAt_change_section_trivialization IB hex₀ - (FiberBundle.mem_baseSet_trivializationAt' _) hf] + rw [Trivialization.mdifferentiableWithinAt_snd_comp_iff₂ IB + (FiberBundle.mem_trivializationAt_proj_source) he hf] /-- Characterization of differentiable functions into a vector bundle in terms of any trivialization. Version at a point. -/ theorem Trivialization.mdifferentiableAt_totalSpace_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (f : M → TotalSpace F E) {x₀ : M} - (hex₀ : (f x₀).proj ∈ e.baseSet) : + (he : f x₀ ∈ e.source) : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ MDifferentiableAt IM 𝓘(𝕜, F) @@ -299,8 +290,8 @@ theorem Trivialization.mdifferentiableAt_totalSpace_iff rw [mdifferentiableAt_totalSpace] apply and_congr_right intro hf - rw [mdifferentiableAt_change_section_trivialization IB hex₀ - (FiberBundle.mem_baseSet_trivializationAt' _) hf] + rw [mdifferentiableAt_change_section_trivialization IB + (FiberBundle.mem_trivializationAt_proj_source) he hf] /-- Characterization of differentiable sections a vector bundle in terms of any trivialization. Version at a point within at set. -/ @@ -313,7 +304,7 @@ theorem Trivialization.mdifferentiableWithinAt_section_iff rw [e.mdifferentiableWithinAt_totalSpace_iff IB] · change MDifferentiableWithinAt IB IB id u b₀ ∧ _ ↔ _ simp [mdifferentiableWithinAt_id] - simp [hex₀] + exact (coe_mem_source e).mpr hex₀ /-- Characterization of differentiable functions into a vector bundle in terms of any trivialization. Version at a point. -/ From fc16f7282d7f1ea5aaa9006f45b24d5cf21021ac Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 15:59:30 +0200 Subject: [PATCH 166/601] Synchronise more names --- Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index d6308dc97db1e1..a7d02f49028507 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -251,7 +251,7 @@ theorem Trivialization.mdifferentiableWithinAt_snd_comp_iff₂ variable (e e') -theorem mdifferentiableAt_change_section_trivialization +theorem Trivialization.mdifferentiableAt_snd_comp_iff₂ {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {x₀ : M} (he : f x₀ ∈ e.source) (he' : f x₀ ∈ e'.source) @@ -290,7 +290,7 @@ theorem Trivialization.mdifferentiableAt_totalSpace_iff rw [mdifferentiableAt_totalSpace] apply and_congr_right intro hf - rw [mdifferentiableAt_change_section_trivialization IB + rw [Trivialization.mdifferentiableAt_snd_comp_iff₂ IB (FiberBundle.mem_trivializationAt_proj_source) he hf] /-- Characterization of differentiable sections a vector bundle in terms From 57fa539b72b3ef8a3ce9d4c76d32d116e6c566eb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 17:42:07 +0200 Subject: [PATCH 167/601] Fix build --- .../VectorBundle/CovariantDerivative.lean | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1bfb8e3162f979..6012cbae8ff8d9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -63,16 +63,6 @@ theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) ( attribute [simp] mdifferentiableAt_iff_differentiableAt --- XXX: make a better version of fderiv_const_smul'', with field coefficients instead! -theorem fderiv_section_smul {𝕜 E E' : Type*} [NontriviallyNormedField 𝕜] - [NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - (σ : (x : E) → Trivial E E' x) (a : 𝕜) (x : E) : - fderiv 𝕜 (a • σ) x = a • fderiv 𝕜 σ x := by - obtain (rfl | ha) := eq_or_ne a 0 - · simp - · have : Invertible a := invertibleOfNonzero ha - exact fderiv_const_smul'' .. - lemma FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) [TopologicalSpace B] [TopologicalSpace F] (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] @@ -357,9 +347,9 @@ lemma convexCombination_isRegular [IsManifold I 1 M] (cov cov' : CovariantDeriva (hcov : IsCkConnection cov n) (hcov' : IsCkConnection cov' n) : IsCkConnection (convexCombination cov cov' f) n where regularity {X σ} hX hσ := by - apply contMDiff_add_section - · exact contMDiff_smul_section hf <| hcov.regularity hX hσ - · exact contMDiff_smul_section (contMDiff_const.sub hf) <| hcov'.regularity hX hσ + apply ContMDiff.add_section + · exact hf.smul_section <| hcov.regularity hX hσ + · exact (contMDiff_const.sub hf).smul_section <| hcov'.regularity hX hσ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @@ -374,10 +364,9 @@ lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset dsimp have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n (T% (f i • (cov i) X σ)) := by - apply contMDiff_smul_section (hf' i hi) - exact IsCkConnection.regularity hX hσ (self := hcov i hi) + apply (hf' i hi).smul_section <| IsCkConnection.regularity hX hσ (self := hcov i hi) simp only [Finset.sum_apply, Pi.smul_apply'] - exact contMDiff_finsum_section (t := fun i ↦ f i • (cov i) X σ) ms + exact .sum_section (t := fun i ↦ f i • (cov i) X σ) ms -- Future: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) @@ -396,7 +385,7 @@ noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' rw [fderiv_add hσ hσ'] rfl - smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] + smul_const_σ X σ a := by ext; simp [fderiv_const_smul_of_field a] leibniz X σ f x hσ hf := by have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := fderiv_smul (by simp_all) (by simp_all) @@ -445,11 +434,10 @@ noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' simp [fderiv_add hσ hσ'] abel - smul_const_σ X σ a := by ext; simp [fderiv_section_smul σ a] + smul_const_σ X σ a := by ext; simp [fderiv_const_smul_of_field a] leibniz X σ f x hσ hf := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ rw [mdifferentiableAt_iff_differentiableAt] at hf - -- have h : DifferentiableAt 𝕜 (f • σ) x := hf.smul hσ have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := fderiv_smul (by simp_all) (by simp_all) simp [this, bar] @@ -696,7 +684,7 @@ lemma _root_.contMDiff_section_of_smul_smoothBumpFunction [T2Space M] [IsManifol (ht : IsOpen t) (ht' : tsupport ψ ⊆ t) (hn : n ≤ ∞) : ContMDiff I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) := by apply contMDiff_of_contMDiffOn_union_of_isOpen - (contMDiffOn_smul_section (ψ.contMDiff.of_le hn).contMDiffOn hs) ?_ ?_ ht + ((ψ.contMDiff.of_le hn).contMDiffOn.smul_section hs) ?_ ?_ ht (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) · apply ((contMDiff_zeroSection _ _).contMDiffOn (s := (tsupport ψ)ᶜ)).congr intro y hy @@ -796,7 +784,7 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime simp [A, B] module map_smul' a v := by - simp [fderiv_section_smul, cov.smul_const_σ] + simp [fderiv_const_smul_of_field, cov.smul_const_σ] module @[simps!] From a051cb9083b6ae9ae91255dacd42705b0f665cf0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 18:37:02 +0200 Subject: [PATCH 168/601] chore: some more API for product of sections --- .../Manifold/VectorBundle/LeviCivita.lean | 72 ++++++++++++------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 2c2427c70eadb5..b61db2da7a0de8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -45,19 +45,62 @@ the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ variable {X X' Y Y' Z Z' : Π x : M, TangentSpace I x} /-- The scalar product of two vector fields -/ -noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := fun x ↦ inner ℝ (X x) (Y x) +noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := + fun x ↦ inner ℝ (X x) (Y x) -- Riemannian.lean shows that `product` is C^k if X and Y are local notation "⟪" X ", " Y "⟫" => product I X Y +section product + +omit [IsManifold I ∞ M] + +variable (X Y) in +lemma product_swap : ⟪Y, X⟫ = ⟪X, Y⟫ := by + ext x + apply real_inner_comm + variable (X) in @[simp] -lemma product_zero_right : ⟪X, 0⟫ = 0 := sorry +lemma product_zero_left : ⟪0, X⟫ = 0 := by + ext x + simp [product] @[simp] -lemma product_zero_left : ⟪0, X⟫ = 0 := sorry +lemma product_zero_right : ⟪X, 0⟫ = 0 := by rw [product_swap, product_zero_left] + +variable (X X' Y) in +lemma product_add_left : ⟪X + X', Y⟫ = ⟪X, Y⟫ + ⟪X', Y⟫ := by + ext x + simp [product, InnerProductSpace.add_left] + +variable (X Y Y') in +lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by + rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] + +-- product_neg_left,right + +variable (X X' Y) in +lemma product_sub_left : ⟪X - X', Y⟫ = ⟪X, Y⟫ - ⟪X', Y⟫ := by + ext x + simp [product, inner_sub_left] + +variable (X Y Y') in +lemma product_sub_right : ⟪X, Y - Y'⟫ = ⟪X, Y⟫ - ⟪X, Y'⟫ := by + ext x + simp [product, inner_sub_right] + +variable (X Y) in +lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by + ext x + simp [product, real_inner_smul_left] -lemma product_sub_right : ⟪X, Y - Z⟫ = ⟪X, Y⟫ - ⟪X, Z⟫ := sorry +variable (X Y) in +lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by + ext x + simp [product, real_inner_smul_right] + +end product namespace CovariantDerivative @@ -117,25 +160,6 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : -- solve for ⟪cov X Y, Z⟫ sorry -variable (X Y Y') in -lemma product_add : product I X (Y + Y') = product I X Y + product I X Y' := sorry - -variable (X Y) in -lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by - ext x - simp [product, real_inner_smul_left] - -variable (X Y) in -lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by - ext x - simp [product, real_inner_smul_right] - -@[simp] -lemma product_add_left_apply (x : M) : product I (X + X') Y x = product I X Y x + product I X' Y x := sorry - -@[simp] -lemma product_add_right_apply (x : M) : product I X (Y + Y') x = product I X Y x + product I X Y' x := sorry - variable (X Y Z Z') in lemma rhs_aux_addZ : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by ext x @@ -184,7 +208,7 @@ lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] ext x simp [VectorField.mlieBracket_add_left (W := Y) (hZ x) (hZ' x)] simp [h1, h2, rhs_aux_addX, rhs_aux_addY, rhs_aux_addZ] - module + sorry -- module lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} (hf : MDifferentiable% f) (hZ : MDifferentiable% (T% Z)) : From 212de17bf1dab79d432444d164cb152cebe53cc9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 7 Jul 2025 18:47:21 +0200 Subject: [PATCH 169/601] Progress on LC connection --- .../Manifold/VectorBundle/LeviCivita.lean | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index b61db2da7a0de8..4f00da2bcce900 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -155,25 +155,37 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : have eq1 := aux I X Y Z cov h have eq2 := aux I Y Z X cov h have eq3 := aux I Z X Y cov h - -- add (I) + (II) and subtract (III) - - -- solve for ⟪cov X Y, Z⟫ + have : rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y = + 2 * ⟪cov X Y, Z⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ + + ⟪Z, VectorField.mlieBracket I X Y⟫ - ⟪X, VectorField.mlieBracket I Z Y⟫ := by + rw [eq1, eq2, eq3] + sorry -- should be obvious now + -- add (I) + (II) and subtract (III) + -- solve for ⟪cov X Y, Z⟫ and obtain the claim sorry variable (X Y Z Z') in lemma rhs_aux_addZ : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by + have : ⟪Y, Z + Z'⟫ = ⟪Y, Z⟫ + ⟪Y, Z'⟫ := sorry + unfold rhs_aux ext x - simp only [rhs_aux] - -- only holds given enough smoothness! + -- have aux := mfderiv_congr this + --simp_rw [this] + ext x + --simp only [rhs_aux] + dsimp + -- prove: product is smooth enough, so we can apply mfderiv_add (and product_add_right)... + -- rw [← mfderiv_add] + -- simp_rw [product_add_right] sorry variable (X X' Y Z) in lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by - sorry + sorry -- hopefully similar to rhs_aux_addZ variable (X Y Y' Z) in lemma rhs_aux_addY : rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by - sorry + sorry -- hopefully similar to rhs_aux_addZ variable (X Y Z) in lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by From 82a722b57858d8a97650b24b7de99331c1fee2a8 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 7 Jul 2025 21:19:07 +0200 Subject: [PATCH 170/601] Fix regularity elaboration in ContMDiff% --- Mathlib/Geometry/Manifold/Elaborators.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 85d9717e46f19b..49ea0f137862bb 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -235,7 +235,7 @@ elab:max "MDifferentiable%" t:term:arg : term => do elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTerm nt wtn + let ne ← Term.elabTermEnsuringType nt wtn let etype ← inferType e >>= instantiateMVars match etype with | .forallE _ src tgt _ => @@ -247,7 +247,7 @@ elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do elab:max "ContMDiffAt%" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTerm nt wtn + let ne ← Term.elabTermEnsuringType nt wtn let etype ← inferType e >>= instantiateMVars match etype with | .forallE _ src tgt _ => From 7c25ac42b566327002f2a67318b5a9c07be01934 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 09:52:10 +0200 Subject: [PATCH 171/601] chore: add new notation for elaborators --- Mathlib/Geometry/Manifold/Elaborators.lean | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 49ea0f137862bb..2d0f00d5101e96 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -212,6 +212,37 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM throwError "Couldn’t find models with corners" +-- TODO: scope all these elaborators to the `Manifold` namespace + +-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, +-- trying to determine `I` and `J` from the local context. +-- The argument x can be omitted. +elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do + let es ← Term.elabTerm s none + let ef ← Term.elabTerm f none + let etype ← inferType ef >>= instantiateMVars + let _estype ← inferType ef >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + -- TODO: check that `estype` and src are compatible/the same! + return ← mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] + | _ => throwError m!"Term {ef} is not a function." + +-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, +-- trying to determine `I` and `J` from the local context. +elab:max "MDiffAt" t:term:arg : term => do + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] + | _ => throwError m!"Term {e} is not a function." + +-- FIXME: remove in favour of MDiffAt (once that one is scoped) elab:max "MDifferentiableAt%" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars @@ -222,6 +253,34 @@ elab:max "MDifferentiableAt%" t:term:arg : term => do return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] | _ => throwError m!"Term {e} is not a function." +-- `MDiff[s] f` elaborates to `MDifferentiableOn I J f`, trying to determine `I` and `J` from the +-- local context. +elab:max "MDiff[" s:term:arg "]" t:term:arg : term => do + let es ← Term.elabTerm s none + let et ← Term.elabTerm t none + let _estype ← inferType es >>= instantiateMVars + let etype ← inferType et >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + -- TODO: check that `estype` and src are compatible/the same! + return ← mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] + | _ => throwError m!"Term {et} is not a function." + +-- `MDiff f` elaborates to `MDifferentiable I J f`, +-- trying to determine `I` and `J` from the local context. +elab:max "MDiff" t:term:arg : term => do + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] + | _ => throwError m!"Term {e} is not a function." + +-- TODO: remove in favour of MDiff elab:max "MDifferentiable%" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars @@ -232,6 +291,65 @@ elab:max "MDifferentiable%" t:term:arg : term => do return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] | _ => throwError m!"Term {e} is not a function." +-- `CMDiffAt[s] n f` elaborates to `ContMDiffWithinAt I J n f s` +elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do + let es ← Term.elabTerm s none + let ef ← Term.elabTerm f none + let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let ne ← Term.elabTerm nt wtn + let _estype ← inferType es >>= instantiateMVars + let eftype ← inferType ef >>= instantiateMVars + match eftype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + -- TODO: check `estype` and src are compatible + return ← mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] + | _ => throwError m!"Term {ef} is not a function." + +-- `CMDiffAt n f` elaborates to `ContMDiffAt I J n f s` +elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do + let e ← Term.elabTerm t none + let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let ne ← Term.elabTerm nt wtn + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] + | _ => throwError m!"Term {e} is not a function." + +-- `CMDiff[s] n f` elaborates to `ContMDiffOn I J n f s` +elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do + let es ← Term.elabTerm s none + let ef ← Term.elabTerm f none + let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let ne ← Term.elabTerm nt wtn + let _estype ← inferType es >>= instantiateMVars + let eftype ← inferType ef >>= instantiateMVars + match eftype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + -- TODO: check `estype` and src are compatible + return ← mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] + | _ => throwError m!"Term {ef} is not a function." + +-- `CMDiff n f` elaborates to `ContMDiff I J n f` +elab:max "CMDiff" nt:term:arg t:term:arg : term => do + let e ← Term.elabTerm t none + let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let ne ← Term.elabTerm nt wtn + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] + | _ => throwError m!"Term {e} is not a function." + +-- TODO: remove in favour of CMDiff elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none @@ -244,6 +362,7 @@ elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." +-- TODO: remove in favour of CMDiffAt elab:max "ContMDiffAt%" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none From 48d67bfb88a1641f665d7c50379578f202f108c2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 09:59:21 +0200 Subject: [PATCH 172/601] chore: move elaborator tests to a dedicated file And add many more tests for the MDifferentiableAt elaborators. --- Mathlib/Geometry/Manifold/Elaborators.lean | 76 +---- .../DifferentialGeometry/Elaborators.lean | 301 ++++++++++++++++++ 2 files changed, 306 insertions(+), 71 deletions(-) create mode 100644 MathlibTest/DifferentialGeometry/Elaborators.lean diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 2d0f00d5101e96..647f210269a160 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -94,27 +94,7 @@ elab "T%" t:term : term => do | _ => pure () return e -variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} - -/-- info: fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V -/ -#guard_msgs in -#check T% σ - -/-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ -#guard_msgs in -#check T% σ' - -/-- info: fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E') -/ -#guard_msgs in -#check T% s - -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] - -/-- info: fun m ↦ TotalSpace.mk' E m (X m) : M → TotalSpace E (TangentSpace I) -/ -#guard_msgs in -#check T% X - -example : (fun m ↦ (X m : TangentBundle I M)) = (fun m ↦ TotalSpace.mk' E m (X m)) := rfl +-- Tests in MathlibTest/DifferentialGeometry/Elaborators.lean. -- FIXME: better failure when trying to find a normedfield instance def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do @@ -375,18 +355,15 @@ elab:max "ContMDiffAt%" nt:term:arg t:term:arg : term => do return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." +variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + variable {EM' : Type*} [NormedAddCommGroup EM'] [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] (f : M → M') (m : M) -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% X) - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% X) m +-- Other tests in MathlibTest/DifferentialGeomtry/Elaborators. /-- info: ContMDiff I (I.prod 𝓘(𝕜, E)) 1 fun m ↦ TotalSpace.mk' E m (X m) : Prop -/ #guard_msgs in @@ -396,47 +373,4 @@ variable {EM' : Type*} [NormedAddCommGroup EM'] #guard_msgs in #check ContMDiffAt% 1 (T% X) m -/-- info: MDifferentiableAt I I' f : M → Prop -/ -#guard_msgs in -#check MDifferentiableAt% f - -/-- info: MDifferentiableAt I I' f m : Prop -/ -#guard_msgs in -#check MDifferentiableAt% f m - -variable (g : E → E') --- set_option trace.MDiffElab true in - -/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') g : E → Prop -/ -#guard_msgs in -#check MDifferentiableAt% g - -variable (h : 𝕜 → E') - -/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) 𝓘(𝕜, E') h : 𝕜 → Prop -/ -#guard_msgs in -#check MDifferentiableAt% h - -variable (h' : M → 𝕜) - -/-- info: MDifferentiableAt I 𝓘(𝕜, 𝕜) h' : M → Prop -/ -#guard_msgs in -#check MDifferentiableAt% h' - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% σ) - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop --/ -#guard_msgs in -#check MDifferentiableAt% (T% σ') - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a ↦ TotalSpace.mk' E' a (s a) : E → Prop --/ -#guard_msgs in -#check MDifferentiableAt% (T% s) - end diff --git a/MathlibTest/DifferentialGeometry/Elaborators.lean b/MathlibTest/DifferentialGeometry/Elaborators.lean new file mode 100644 index 00000000000000..352b7873e7a6f0 --- /dev/null +++ b/MathlibTest/DifferentialGeometry/Elaborators.lean @@ -0,0 +1,301 @@ +import Mathlib.Geometry.Manifold.Elaborators + +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +import Mathlib.Geometry.Manifold.VectorBundle.Tangent +import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorField.LieBracket + +set_option pp.unicode.fun true + +open Bundle Filter Function Topology + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +section + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] + -- `V` vector bundle + +-- Tests for the T% elaborator, inserting calls to TotalSpace.mk' automatically. +section TotalSpace + +variable {σ : Π x : M, V x} + {σ' : (x : E) → Trivial E E' x} {σ'' : (y : E) → Trivial E E' y} {s : E → E'} + +/-- info: fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V -/ +#guard_msgs in +#check T% σ + +-- Note how the name of the bound variable `x` resp. `y` is preserved. +/-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% σ' + +/-- info: fun y ↦ TotalSpace.mk' E' y (σ'' y) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% σ'' + +/-- info: fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% s + +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + +/-- info: fun m ↦ TotalSpace.mk' E m (X m) : M → TotalSpace E (TangentSpace I) -/ +#guard_msgs in +#check T% X + +example : (fun m ↦ (X m : TangentBundle I M)) = (fun m ↦ TotalSpace.mk' E m (X m)) := rfl + +end TotalSpace + +-- Elaborators for MDifferentiable{WithinAt,At,On}. +section differentiability + +-- Start with some basic tests: a simple function, both in applied and unapplied form. +variable {EM' : Type*} [NormedAddCommGroup EM'] + [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +-- General case: a function between two manifolds. +variable {f : M → M'} {s : Set M} {m : M} + +/-- info: MDifferentiableWithinAt I I' f s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] f + +/-- info: MDifferentiableWithinAt I I' f s m : Prop -/ +#guard_msgs in +#check MDiffAt[s] f m + +/-- info: MDifferentiableAt I I' f : M → Prop -/ +#guard_msgs in +#check MDiffAt f + +/-- info: MDifferentiableAt I I' f m : Prop -/ +#guard_msgs in +#check MDiffAt f m + +/-- info: MDifferentiableOn I I' f s : Prop -/ +#guard_msgs in +#check MDiff[s] f + +-- XXX: is this expected behaviour or should it be a bug? +/-- +error: Function expected at + MDifferentiableOn I I' f s +but this term has type + Prop + +Note: Expected a function because this term is being applied to the argument + m +-/ +#guard_msgs in +#check MDiff[s] f m + +/-- info: MDifferentiable I I' f : Prop -/ +#guard_msgs in +#check MDiff f + +/-- +error: Function expected at + MDifferentiable I I' f +but this term has type + Prop + +Note: Expected a function because this term is being applied to the argument + m +-/ +#guard_msgs in +#check MDiff f m + +-- Function from a manifold into a normed space. +variable {g : M → E} + +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) g s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] g +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) g s m : Prop -/ +#guard_msgs in +#check MDiffAt[s] g m +/-- info: MDifferentiableAt I 𝓘(𝕜, E) g : M → Prop -/ +#guard_msgs in +#check MDiffAt g +/-- info: MDifferentiableAt I 𝓘(𝕜, E) g m : Prop -/ +#guard_msgs in +#check MDiffAt g m +/-- info: MDifferentiableOn I 𝓘(𝕜, E) g s : Prop -/ +#guard_msgs in +#check MDiff[s] g +-- TODO: fix and enable! #check MDiff[s] g m +/-- info: MDifferentiable I 𝓘(𝕜, E) g : Prop -/ +#guard_msgs in +#check MDiff g +-- TODO: fix and enable! #check MDiff g m + +-- From a manifold into a field. +variable {h : M → 𝕜} + +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, 𝕜) h s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] h +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, 𝕜) h s m : Prop -/ +#guard_msgs in +#check MDiffAt[s] h m +/-- info: MDifferentiableAt I 𝓘(𝕜, 𝕜) h : M → Prop -/ +#guard_msgs in +#check MDiffAt h +/-- info: MDifferentiableAt I 𝓘(𝕜, 𝕜) h m : Prop -/ +#guard_msgs in +#check MDiffAt h m +/-- info: MDifferentiableOn I 𝓘(𝕜, 𝕜) h s : Prop -/ +#guard_msgs in +#check MDiff[s] h +-- TODO: fix and enable! #check MDiff[s] h m +/-- info: MDifferentiable I 𝓘(𝕜, 𝕜) h : Prop -/ +#guard_msgs in +#check MDiff h +-- TODO: fix and enable! #check MDiff h m + +-- The following tests are more spotty, as most code paths are already covered above. +-- Add further details as necessary. + +-- From a normed space into a manifold. +variable {f : E → M'} {s : Set E} {x : E} +/-- info: MDifferentiableWithinAt 𝓘(𝕜, E) I' f s : E → Prop -/ +#guard_msgs in +#check MDiffAt[s] f +/-- info: MDifferentiableAt 𝓘(𝕜, E) I' f x : Prop -/ +#guard_msgs in +#check MDiffAt f x +-- TODO: fix and enable! #check MDiff[s] f x +/-- info: MDifferentiable 𝓘(𝕜, E) I' f : Prop -/ +#guard_msgs in +#check MDiff f +-- TODO: should this error? if not, fix and enable! #check MDiff f x +-- same! #check MDifferentiable% f x + +-- Between normed spaces. +variable {f : E → E'} {s : Set E} {x : E} + +/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') f x : Prop -/ +#guard_msgs in +#check MDiffAt f x +/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') f : E → Prop -/ +#guard_msgs in +#check MDiffAt f +-- should this error or not? #check MDiff[s] f x +/-- info: MDifferentiableWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E') f s : E → Prop -/ +#guard_msgs in +#check MDiffAt[s] f +/-- info: MDifferentiableOn 𝓘(𝕜, E) 𝓘(𝕜, E') f s : Prop -/ +#guard_msgs in +#check MDiff[s] f + + +-- Normed space to a field. +variable {f : E → 𝕜} {s : Set E} {x : E} + +/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, 𝕜) f x : Prop -/ +#guard_msgs in +#check MDiffAt f x + +-- Field into a manifold. +variable {f : 𝕜 → M'} {u : Set 𝕜} {a : 𝕜} +/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) I' f a : Prop -/ +#guard_msgs in +#check MDiffAt f a +/-- info: MDifferentiableOn 𝓘(𝕜, 𝕜) I' f u : Prop -/ +#guard_msgs in +#check MDiff[u] f + +-- Field into a normed space. +variable {f : 𝕜 → E'} {u : Set 𝕜} {a : 𝕜} +/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) 𝓘(𝕜, E') f a : Prop -/ +#guard_msgs in +#check MDiffAt f a +/-- info: MDifferentiableOn 𝓘(𝕜, 𝕜) 𝓘(𝕜, E') f u : Prop -/ +#guard_msgs in +#check MDiff[u] f + +-- On a field. +variable {f : 𝕜 → 𝕜} {u : Set 𝕜} {a : 𝕜} +/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) 𝓘(𝕜, 𝕜) f a : Prop -/ +#guard_msgs in +#check MDiffAt f a +/-- info: MDifferentiableOn 𝓘(𝕜, 𝕜) 𝓘(𝕜, 𝕜) f u : Prop -/ +#guard_msgs in +#check MDiff[u] f + +-- This elaborator can be combined with the total space elaborator. +-- XXX: these tests might be incomplete; extend as needed! + +variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ +#guard_msgs in +#check MDiffAt (T% X) + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ +#guard_msgs in +#check MDiffAt (T% σ) + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop +-/ +#guard_msgs in +#check MDiffAt (T% σ') + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a ↦ TotalSpace.mk' E' a (s a) : E → Prop +-/ +#guard_msgs in +#check MDifferentiableAt% (T% s) +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% X) m + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% X) + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% X) m + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ +#guard_msgs in +#check MDifferentiableAt% (T% σ) + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop +-/ +#guard_msgs in +#check MDifferentiableAt% (T% σ') + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a ↦ TotalSpace.mk' E' a (s a) : E → Prop +-/ +#guard_msgs in +#check MDifferentiableAt% (T% s) + +end differentiability From 6653960a33a79500bf8a3ffcc27f6956e034466b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 10:45:24 +0200 Subject: [PATCH 173/601] chore: minimize imports for diffgeo elaborators --- Mathlib/Geometry/Manifold/Elaborators.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 647f210269a160..b804c60567c492 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -3,13 +3,9 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.VectorBundle.Tangent -import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.Traces /-! From 9edd54faba21d76f7ece6bcbf5ada2f84b07cb98 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 11:01:29 +0200 Subject: [PATCH 174/601] chore: use new elaborators in LocalFrame --- .../Manifold/VectorBundle/LocalFrame.lean | 90 +++++++------------ 1 file changed, 34 insertions(+), 56 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 530fab83024a98..4bafb08e1851c9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -6,6 +6,7 @@ Authors: Patrick Massot, Michael Rothgang import Mathlib.Geometry.Manifold.Algebra.Monoid import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +import Mathlib.Geometry.Manifold.Elaborators /-! # Local frames in a vector bundle @@ -102,8 +103,7 @@ is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_localFrame_baseSet (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n - (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) e.baseSet := by + CMDiff[e.baseSet] n (T% b.localFrame e i) := by rw [contMDiffOn_section_of_mem_baseSet₀] apply (contMDiffOn_const (c := b i)).congr intro y hy @@ -113,8 +113,7 @@ omit [IsManifold I 0 M] in lemma _root_.contMDiffAt_localFrame_of_mem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) {x : M} (hx : x ∈ e.baseSet) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n - (fun x ↦ TotalSpace.mk' F x (b.localFrame e i x)) x := + CMDiffAt n (T% b.localFrame e i) x := (contMDiffOn_localFrame_baseSet n e b i).contMDiffAt <| e.open_baseSet.mem_nhds hx @[simp] @@ -131,7 +130,6 @@ lemma localFrame_apply_of_notMem b.localFrame e i x = 0 := by simp [localFrame, hx] - lemma localFrame_toBasis_at_coe (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] @@ -240,14 +238,14 @@ near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x := by + (hs : CMDiffAt k (T% s) x) (i : ι) : + CMDiffAt k (b.localFrame_repr e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical -- step 1: on e.baseSet, can compute the coefficient very well let aux := fun x ↦ b.repr (e (s x)).2 i -- Since e.baseSet is open, this is sufficient. - suffices ContMDiffAt I 𝓘(𝕜) k aux x by + suffices CMDiffAt k aux x by apply this.congr_of_eventuallyEq ?_ apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy @@ -255,7 +253,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 simp only [aux] -- step 2: `s` read in trivialization `e` is `C^k` - have h₁ : ContMDiffAt I 𝓘(𝕜, F) k (fun x ↦ (e (s x)).2) x := by + have h₁ : CMDiffAt k (fun x ↦ (e (s x)).2) x := by exact contMDiffAt_section_of_mem_baseSet hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i @@ -278,8 +276,7 @@ in the local frame induced by `e` -/ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} [ContMDiffVectorBundle k F V I] (ht : IsOpen t) (ht' : t ⊆ e.baseSet) - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : - ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := + (hs : CMDiff[t] k (T% s)) (i : ι) : CMDiff[t] k (b.localFrame_repr e i s) := fun _ hx ↦ (contMDiffAt_localFrame_repr (ht' hx) b (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt @@ -288,8 +285,7 @@ omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in induced by `e` -/ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) (i : ι) : - ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := + (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : CMDiff[e.baseSet] k (b.localFrame_repr e i s) := contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ omit [IsManifold I 0 M] in @@ -298,14 +294,12 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {x' : M} (hx : x' ∈ e.baseSet) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ - ∀ i, ContMDiffAt I 𝓘(𝕜) k (b.localFrame_repr e i s) x' := by + CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_repr e i s) x' := by refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ - have this (i) : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k (fun x ↦ - TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + have this (i) : CMDiffAt k (T% ((b.localFrame_repr e i) s • b.localFrame e i)) x' := (hi i).smul_section (contMDiffAt_localFrame_of_mem k e b i hx) - have almost : ContMDiffAt I (I.prod 𝓘(𝕜, F)) k - (fun x ↦ TotalSpace.mk' F x (∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + have almost : CMDiffAt k + (T% (fun x ↦ ∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := .sum_section fun i _ ↦ this i apply almost.congr_of_eventuallyEq ?_ obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) @@ -317,15 +311,12 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ - ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) t := by + CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_repr e i s) := by refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ - have this (i) : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ - TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) t := + have this (i) : CMDiff[t] k (T% ((b.localFrame_repr e i) s • b.localFrame e i)) := (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' - have almost : ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (rhs x)) t := - .sum_section fun i _ ↦ this i + have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i apply almost.congr intro y hy congr @@ -336,8 +327,7 @@ omit [IsManifold I 0 M] in coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ - ∀ i, ContMDiffOn I 𝓘(𝕜) k (b.localFrame_repr e i s) e.baseSet := by + CMDiff[e.baseSet] k (T% s) ↔ ∀ i, CMDiff[e.baseSet] k (b.localFrame_repr e i s) := by rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] -- Differentiability of a section can be checked in terms of its local frame coefficients @@ -348,16 +338,14 @@ omit [IsManifold I 0 M] in near `x` induced by `e` and `b` -/ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] - (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) - {s : Π x : M, V x} - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x) - (i : ι) : MDifferentiableAt I 𝓘(𝕜) (b.localFrame_repr e i s) x := by + (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDiffAt (T% s) x) (i : ι) : + MDiffAt (b.localFrame_repr e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical -- step 1: on e.baseSet, can compute the coefficient very well let aux := fun x ↦ b.repr (e (s x)).2 i -- Since e.baseSet is open, this is sufficient. - suffices MDifferentiableAt I 𝓘(𝕜) aux x by + suffices MDiffAt aux x by apply this.congr_of_eventuallyEq apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy @@ -365,8 +353,7 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac simp only [aux] -- step 2: `s` read in trivialization `e` is differentiable - have h₁ : MDifferentiableAt I 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) x := by - exact e.mdifferentiableAt_section_iff I s hxe |>.1 hs + have h₁ : MDiffAt (fun x ↦ (e (s x)).2) x := e.mdifferentiableAt_section_iff I s hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i let basl : F →ₗ[𝕜] 𝕜 := { @@ -387,9 +374,8 @@ omit [IsManifold I 0 M] in in the local frame induced by `e` -/ lemma mdifferentiableOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) [ContMDiffVectorBundle 1 F V I] {s : Π x : M, V x} {t : Set M} - (ht : IsOpen t) (ht' : t ⊆ e.baseSet) - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) t) (i : ι) : - MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) t := + (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : MDiff[t] (T% s)) (i : ι) : + MDiff[t] (b.localFrame_repr e i s) := fun _ hx ↦ (mdifferentiableAt_localFrame_repr (ht' hx) b (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt @@ -398,9 +384,8 @@ omit [IsManifold I 0 M] in local frame induced by `e` -/ lemma mdifferentiableOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet) - (i : ι) : - MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := + (hs : MDiff[e.baseSet] (T% s)) (i : ι) : + MDiff[e.baseSet] (b.localFrame_repr e i s) := mdifferentiableOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ omit [IsManifold I 0 M] in @@ -409,15 +394,13 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x' ↔ - ∀ i, MDifferentiableAt I 𝓘(𝕜) (b.localFrame_repr e i s) x' := by + MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_repr e i s) x' := by refine ⟨fun h i ↦ mdifferentiableAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ - have this (i) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ - TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + have this (i) : MDiffAt (T% (b.localFrame_repr e i) s • b.localFrame e i) x' := mdifferentiableAt_smul_section (hi i) ((contMDiffAt_localFrame_of_mem 1 e b i hx).mdifferentiableAt le_rfl) - have almost : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + have almost : MDiffAt + (T% (fun x ↦ ∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := mdifferentiableAt_finsum_section fun i ↦ this i apply almost.congr_of_eventuallyEq ?_ obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) @@ -429,16 +412,13 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) t ↔ - ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) t := by + MDiff[t] (T% s) ↔ ∀ i, MDiff[t] (b.localFrame_repr e i s) := by refine ⟨fun h i ↦ mdifferentiableOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ - have this (i) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ - TotalSpace.mk' F x ((b.localFrame_repr e i) s x • b.localFrame e i x)) t := + have this (i) : MDiff[t] (T% ((b.localFrame_repr e i) s • b.localFrame e i)) := mdifferentiableOn_smul_section (hi i) <| ((b.contMDiffOn_localFrame_baseSet 1 e i).mono ht').mdifferentiableOn le_rfl let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' - have almost : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (rhs x)) t := - mdifferentiableOn_finsum_section fun i ↦ this i + have almost : MDiff[t] (T% rhs) := mdifferentiableOn_finsum_section fun i ↦ this i apply almost.congr intro y hy congr @@ -450,8 +430,7 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ - ∀ i, MDifferentiableOn I 𝓘(𝕜) (b.localFrame_repr e i s) e.baseSet := by + MDiff[e.baseSet] (T% s) ↔ ∀ i, MDiff[e.baseSet] (b.localFrame_repr e i s) := by rw [mdifferentiableOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] end MDifferentiable @@ -537,8 +516,7 @@ variable (F) in omit [IsManifold I 0 M] in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] {x : M} (hx : x ∈ e.baseSet) (v : V x) [ContMDiffVectorBundle ∞ F V I] : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) ∞ - (fun x' ↦ TotalSpace.mk' F x' (localExtensionOn b e x v x')) e.baseSet := by + CMDiff[e.baseSet] ∞ (T% (localExtensionOn b e x v)) := by -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are -- constant, hence smoothness follows. rw [contMDiffOn_baseSet_iff_localFrame_repr b] From 761ee76c3f7cba3a071517f82fbf27f88021ee1e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 11:07:18 +0200 Subject: [PATCH 175/601] chore(Tensoriality,LeviCivita): use new elaborator notation --- .../Manifold/VectorBundle/LeviCivita.lean | 5 ++- .../Manifold/VectorBundle/Tensoriality.lean | 32 +++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 4f00da2bcce900..1dc05aaedcc275 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -171,7 +171,6 @@ lemma rhs_aux_addZ : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' ext x -- have aux := mfderiv_congr this --simp_rw [this] - ext x --simp only [rhs_aux] dsimp -- prove: product is smooth enough, so we can apply mfderiv_add (and product_add_right)... @@ -203,7 +202,7 @@ lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I sorry lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] - (hZ : MDifferentiable% (T% Z)) (hZ' : MDifferentiable% (T% Z')) : + (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by -- A bit too painful, and have missing differentiability assumptions. simp only [leviCivita_rhs] @@ -223,7 +222,7 @@ lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] sorry -- module lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} - (hf : MDifferentiable% f) (hZ : MDifferentiable% (T% Z)) : + (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs] simp [rhs_aux_smulX, rhs_aux_smulY, rhs_aux_smulZ] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index a965169d13f68c..f1ccf5da2a5aac 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -44,13 +44,13 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] [IsManifold I ∞ M] {φ : (Π x : M, V x) → (Π x, V' x)} {x} - {σ σ' : Π x : M, V x} (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) + {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDifferentiableAt% f x → MDifferentiableAt% (T% σ) x → + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x → + (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by - have locality {σ σ'} (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) + have locality {σ σ'} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : φ σ x = φ σ' x := by obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by @@ -66,12 +66,12 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F classical have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) - (hσ : ∀ i, MDifferentiableAt% (T% σ i) x): + (hσ : ∀ i, MDiffAt (T% σ i) x): φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by induction s using Finset.induction_on with | empty => simp only [Finset.sum_empty] - have h₁ : MDifferentiableAt% (fun x' : M ↦ (0 : ℝ)) x := by + have h₁ : MDiffAt (fun x' : M ↦ (0 : ℝ)) x := by exact contMDiffAt_const.mdifferentiableAt le_rfl rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl] rw [φ_smul] @@ -87,13 +87,13 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) let c := Basis.localFrame_repr t b - have hs (i) : MDifferentiableAt% (T% s i) x:= + have hs (i) : MDiffAt (T% s i) x:= (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl - have hc {σ : (x : M) → V x} (hσ : MDifferentiableAt% (T% σ) x) (i) : - MDifferentiableAt% ((c i) σ) x := + have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : + MDiffAt ((c i) σ) x := mdifferentiableAt_localFrame_repr x_mem b hσ i have hφ {σ : (x : M) → V x} - (hσ : MDifferentiableAt% (T% σ) x) : + (hσ : MDiffAt (T% σ) x) : φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by exact locality hσ @@ -184,17 +184,17 @@ lemma tensoriality_criterion₂ [ContMDiffVectorBundle 1 F V I] [IsManifold I [FiberBundle F' V'] [VectorBundle ℝ F' V'] {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' τ τ' : Π x : M, V x} - (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) - (hτ : MDifferentiableAt% (T% τ) x) (hτ' : MDifferentiableAt% (T% τ') x) + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) + (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) - (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt% f x → MDifferentiableAt% (T% σ) x → + (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (φ_add : ∀ {σ σ' τ}, MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x → + (φ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDifferentiableAt% f x → MDifferentiableAt% (T% τ) x → + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDifferentiableAt% (T% τ) x → MDifferentiableAt% (T% τ') x → + (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by trans φ σ' τ x · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ From 1d997ecce03586af5e5d5db8b769c8f8325cab04 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 8 Jul 2025 13:00:55 +0200 Subject: [PATCH 176/601] Propagate elaborators fixes --- Mathlib/Geometry/Manifold/Elaborators.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index b804c60567c492..dd200c080719da 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -287,7 +287,7 @@ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTerm nt wtn + let ne ← Term.elabTermEnsuringType nt wtn let etype ← inferType e >>= instantiateMVars match etype with | .forallE _ src tgt _ => @@ -301,7 +301,7 @@ elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTerm nt wtn + let ne ← Term.elabTermEnsuringType nt wtn let _estype ← inferType es >>= instantiateMVars let eftype ← inferType ef >>= instantiateMVars match eftype with From 0e73b26640143c4bfce408a56c1cecb6f4b73594 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 8 Jul 2025 14:19:57 +0200 Subject: [PATCH 177/601] CovariantDerivative refactor --- .../VectorBundle/CovariantDerivative.lean | 428 ++++++++++-------- 1 file changed, 246 insertions(+), 182 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 6012cbae8ff8d9..c42e8dd7e0ba6a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -20,7 +20,7 @@ TODO: add a more complete doc-string -/ -open Bundle Filter Function Topology +open Bundle Filter Function Topology Set open scoped Bundle Manifold ContDiff @@ -100,38 +100,29 @@ lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s end prerequisites -@[ext] -structure CovariantDerivative where - toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) - addX : ∀ (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x), - toFun (X + X') σ = toFun X σ + toFun X' σ - smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜), - toFun (f • X) σ = f • toFun X σ - addσ : ∀ (X : Π x : M, TangentSpace I x) (σ σ' : Π x : M, V x) (x : M), - MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x - → toFun X (σ + σ') x = toFun X σ x + toFun X σ' x - leibniz : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → 𝕜) (x : M), - MDifferentiableAt% (T% σ) x → MDifferentiableAt% f x - → toFun X (f • σ) x = (f • toFun X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) f x (X x)) • σ x - smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), - toFun X (a • σ) = a • toFun X σ - variable {I} in structure IsCovariantDerivativeOn - (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (s : Set M) : Prop where + (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) + (s : Set M := Set.univ) : Prop where -- All the same axioms as CovariantDerivative, but restricted to the set s. - addX : ∀ (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x), - ∀ x ∈ s, f (X + X') σ x = f X σ x + f X' σ x - smulX : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜), - ∀ x ∈ s, f (g • X) σ x = g x • f X σ x - addσ : ∀ (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x}, ∀ x ∈ s, - MDifferentiableAt% (T% σ) x → MDifferentiableAt% (T% σ') x - → f X (σ + σ') x = f X σ x + f X σ' x - leibniz : ∀ (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {g : M → 𝕜}, ∀ x ∈ s, - MDifferentiableAt% (T% σ) x → MDifferentiableAt% g x - → f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x - smul_const_σ : ∀ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜), ∀ x ∈ s, - f X (a • σ) x = a • f X σ x + addX (f) (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x) {x : M} + (hx : x ∈ s := by trivial) : f (X + X') σ x = f X σ x + f X' σ x + smulX (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜) {x : M} + (hx : x ∈ s := by trivial) : f (g • X) σ x = g x • f X σ x + addσ (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x} + (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) + (hx : x ∈ s := by trivial) : + f X (σ + σ') x = f X σ x + f X σ' x + leibniz (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {g : M → 𝕜} {x} + (hσ : MDifferentiableAt% (T% σ) x) (hg : MDifferentiableAt% g x) (hx : x ∈ s := by trivial): + f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x + smul_const_σ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) {x} + (hx : x ∈ s := by trivial) : f X (a • σ) x = a • f X σ x + +@[ext] +structure CovariantDerivative where + toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) + isCovariantDerivativeOn : IsCovariantDerivativeOn F V toFun Set.univ variable {I F V} @@ -140,11 +131,11 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), lemma IsCovariantDerivativeOn.mono {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s t : Set M} (hf : IsCovariantDerivativeOn F V f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F V f s where - addX X X' σ x hx := hf.addX X X' σ x (hst hx) - smulX X σ f x hx := hf.smulX X σ f x (hst hx) - addσ X {_σ _σ'} x hx hσ hσ' := hf.addσ X x (hst hx) hσ hσ' - leibniz X {_ _} _ hx hσ hf' := hf.leibniz X _ (hst hx) hσ hf' - smul_const_σ X σ a x hx := hf.smul_const_σ X σ a x (hst hx) + addX X X' σ _ hx := hf.addX X X' σ (hst hx) + smulX X σ f _ hx := hf.smulX X σ f (hst hx) + addσ X _ _ _ hσ hσ' hx := hf.addσ X hσ hσ' (hst hx) + leibniz X _ _ _ hσ hf' hx := hf.leibniz X hσ hf' (hst hx) + smul_const_σ X σ a _ hx := hf.smul_const_σ X σ a (hst hx) omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @@ -153,20 +144,19 @@ lemma IsCovariantDerivativeOn.iUnion {ι : Type*} (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) : IsCovariantDerivativeOn F V f (⋃ i, s i) where addX X X' σ x hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addX _ _ _ _ hxsi + exact (hf i).addX .. smulX X σ f x hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smulX _ _ _ _ hxsi - addσ X σ σ' x hx hσ hσ' := by + exact (hf i).smulX .. + addσ X σ σ' x hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addσ _ _ hxsi hσ hσ' - leibniz X σ f x hx hσ hf' := by + exact (hf i).addσ _ hσ hσ' + leibniz X σ f x hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).leibniz _ _ hxsi hσ hf' + exact (hf i).leibniz _ hσ hf' smul_const_σ X σ a x hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smul_const_σ _ _ _ _ hxsi - + exact (hf i).smul_const_σ .. namespace CovariantDerivative attribute [coe] toFun @@ -178,38 +168,9 @@ instance : CoeFun (CovariantDerivative I F V) omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -lemma isCovariantDerivativeOn_univ (cov : CovariantDerivative I F V) : - IsCovariantDerivativeOn F V cov Set.univ where - addX X X' σ x _ := by simp [cov.addX] - smulX X σ f x _ := by simp [cov.smulX] - addσ X σ σ' x _ hσ hσ' := cov.addσ _ _ _ _ hσ hσ' - leibniz X σ f x _ hσ hf := cov.leibniz X _ _ _ hσ hf - smul_const_σ X σ a x _ := by simp [cov.smul_const_σ X σ a] - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -lemma isCovariantDerivativeOn (cov : CovariantDerivative I F V) {s : Set M} : +instance (cov : CovariantDerivative I F V) {s : Set M} : IsCovariantDerivativeOn F V cov s := by - apply (cov.isCovariantDerivativeOn_univ).mono (fun ⦃a⦄ a ↦ trivial) - -/-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant on `Set.univ`, it is a covariant derivative. -/ -def of_isCovariantDerivativeOn_univ - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (hf : IsCovariantDerivativeOn F V f Set.univ) : CovariantDerivative I F V where - toFun := f - addX X X' σ := by ext; simp [hf.addX X X' σ] - smulX X σ g := by ext; simp [hf.smulX X σ] - addσ X σ σ' x hσ hf' := hf.addσ _ _ trivial hσ hf' - leibniz X σ f x hσ hf' := hf.leibniz X x trivial hσ hf' - smul_const_σ X σ a := by ext; simp [hf.smul_const_σ X σ a] - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -@[simp] -lemma of_isCovariantDerivativeOn_univ_coe - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (hf : IsCovariantDerivativeOn F V f Set.univ) : - of_isCovariantDerivativeOn_univ hf = f := rfl + apply cov.isCovariantDerivativeOn.mono (fun ⦃a⦄ a ↦ trivial) omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @@ -219,7 +180,7 @@ def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) (hs : ⋃ i, s i = Set.univ) : CovariantDerivative I F V := - of_isCovariantDerivativeOn_univ (hs ▸ IsCovariantDerivativeOn.iUnion hf) + ⟨f, hs ▸ IsCovariantDerivativeOn.iUnion hf⟩ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @@ -229,8 +190,20 @@ lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) (hs : ⋃ i, s i = Set.univ) : of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl --- TODO: generalise all the lemmas below to IsCovariantDerivativeOn +variable (F) in +/-- +A covariant derivative ∇ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class _root_.ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) + (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) + (u : Set M) where + regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, + CMDiff[u] (k + 1) (T% σ) → CMDiff[u] k (T% X) → + CMDiff[u] k (T% (cov X σ)) +-- TODO: relative the definition below to the above one /-- A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. @@ -238,81 +211,130 @@ This is a class so typeclass inference can deduce this automatically. -/ class _root_.IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - ContMDiff I (I.prod 𝓘(𝕜, F)) (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → - ContMDiff I (I.prod 𝓘(𝕜, F)) k (T% (cov X σ)) + ContMDiff% (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → + ContMDiff% k (T% (cov X σ)) -- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection -- is of class C^k (up to off-by-one errors) +variable {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} + + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +@[simp] +lemma _root_.IsCovariantDerivativeOn.zeroX (hf : IsCovariantDerivativeOn F V f s) + {x : M} (hx : x ∈ s := by trivial) + (σ : Π x : M, V x) : f 0 σ x = 0 := by + simpa using IsCovariantDerivativeOn.addX f hf 0 0 σ hx + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in @[simp] lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = 0 := by - have := cov.addX (0 : (x : M) → TangentSpace I x) (0 : (x : M) → TangentSpace I x) σ - simpa using this + ext x + apply cov.isCovariantDerivativeOn.zeroX omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] +lemma _root_.IsCovariantDerivativeOn.zeroσ (hf : IsCovariantDerivativeOn F V f s) + (X : Π x : M, TangentSpace I x) + {x} (hx : x ∈ s := by trivial) : f X 0 x = 0 := by + have : MDifferentiableAt% (T% fun x ↦ (0 : V x)) x := by -- TODO: fix using upcoming mdiff lemma + exact (contMDiff_zeroSection 𝕜 V).mdifferentiableAt le_rfl + simpa using (hf.addσ X this this : f X (0+0) x = _) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] in + +@[simp] lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by ext x - have : MDifferentiableAt% (T% fun x ↦ (0 : V x)) x := by - exact (contMDiff_zeroSection 𝕜 V).mdifferentiableAt le_rfl - have := cov.addσ X (0 : (x : M) → V x) (0 : (x : M) → V x) x this this - simpa using this + apply cov.isCovariantDerivativeOn.zeroσ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in /-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ -lemma congr_σ (cov : CovariantDerivative I F V) +lemma _root_.IsCovariantDerivativeOn.congr_σ (_hf : IsCovariantDerivativeOn F V f s) (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) (x : M) : - cov X σ x = cov X σ' x := by + f X σ x = f X σ' x := by simp [funext hσ] + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in +/-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ +lemma congr_σ (cov : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) (x : M) : + cov X σ x = cov X σ' x := + cov.isCovariantDerivativeOn.congr_σ X hσ x + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] in +lemma _root_.IsCovariantDerivativeOn.sum_X (hf : IsCovariantDerivativeOn F V f s) + {ι : Type*} {u : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} + {x} (hx : x ∈ s) : + f (∑ i ∈ u, X i) σ x = ∑ i ∈ u, f (X i) σ x := by + classical + have := hf.zeroX hx σ + induction u using Finset.induction_on with + | empty => simp [hf.zeroX hx] + | insert a u ha h => + simp [Finset.sum_insert ha, ← h, hf.addX] + + omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in lemma sum_X (cov : CovariantDerivative I F V) {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by - classical - induction s using Finset.induction_on with - | empty => simp - | insert a s ha h => simp [Finset.sum_insert ha, ← h, cov.addX] + ext x + simpa using cov.isCovariantDerivativeOn.sum_X /-- A convex combination of covariant derivatives is a covariant derivative. -/ @[simps] -def convexCombination (cov cov' : CovariantDerivative I F V) (f : M → 𝕜) : +def _root_.IsCovariantDerivativeOn.convexCombination + {f' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : IsCovariantDerivativeOn F V f s) (hf' : IsCovariantDerivativeOn F V f' s) (g : M → 𝕜) : + IsCovariantDerivativeOn F V (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where + addX X X' σ _ hx := by simp [hf.addX, hf'.addX]; module + smulX X σ φ _ hx := by simp [hf.smulX, hf'.smulX]; module + addσ X σ σ' x hx hσ hσ' := by + simp [hf.addσ X hx hσ hσ', hf'.addσ X hx hσ hσ'] + module + smul_const_σ X {σ a} x hx := by + simp [hf.smul_const_σ, hf'.smul_const_σ] + module + leibniz X σ φ x hσ hφ hx := by + simp [hf.leibniz X hσ hφ, hf'.leibniz X hσ hφ] + module + +/-- A convex combination of covariant derivatives is a covariant derivative. -/ +@[simps] +def convexCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : CovariantDerivative I F V where - toFun X s := (f • (cov X s)) + (1 - f) • (cov' X s) - addX X X' σ := by simp only [cov.addX, cov'.addX]; module - smulX X σ f := by simp only [cov.smulX, cov'.smulX]; module - addσ X σ σ' x hσ hσ' := by - simp [cov.addσ X σ σ' x hσ hσ', cov'.addσ X σ σ' x hσ hσ'] - module - smul_const_σ X {σ a} /-hσ-/ := by - simp [cov.smul_const_σ, cov'.smul_const_σ] - module - leibniz X σ f x hσ hf := by - simp [cov.leibniz X σ f x hσ hf, cov'.leibniz X σ f x hσ hf] - module + toFun := fun X σ ↦ (g • (cov X σ)) + (1 - g) • (cov' X σ) + isCovariantDerivativeOn := + cov.isCovariantDerivativeOn.convexCombination cov'.isCovariantDerivativeOn _ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] - (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : - CovariantDerivative I F V where - toFun X t := ∑ i ∈ s, (f i) • (cov i) X t - addX X X' σ := by +def _root_.IsCovariantDerivativeOn.convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] + {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (h : ∀ i, IsCovariantDerivativeOn F V (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : + IsCovariantDerivativeOn F V (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where + addX X X' σ x hx := by rw [← Finset.sum_add_distrib] congr ext i - simp [(cov i).addX] - smulX X σ g := by + simp [(h i).addX] + smulX X σ g x hx := by rw [Finset.smul_sum] congr ext i - simp [(cov i).smulX] + simp [(h i).smulX] module - addσ X σ σ' x hσ hσ' := by + addσ X σ σ' x hx hσ hσ' := by -- XXX: is this nicer using induction? classical induction s using Finset.induction with @@ -320,14 +342,14 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] | insert a s has h => simp [Finset.sum_insert has] sorry - smul_const_σ X {σ a} /-hσ-/ := by + smul_const_σ X {σ a} x hx := by rw [Finset.smul_sum] congr - ext i x - simp [(cov i).smul_const_σ] + ext i + simp [(h i).smul_const_σ] module - leibniz X σ g x hσ hf := by - calc (∑ i ∈ s, f i • (cov i) X (g • σ)) x + leibniz X σ g x hσ hg hx := by + calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := sorry -- rewrite using (cov i).leibniz @@ -338,11 +360,35 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x := -- use hf and pull out g... sorry + simp + +/-- A finite convex combination of covariant derivatives is a covariant derivative. -/ +def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] + (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : + CovariantDerivative I F V where + toFun X t x := ∑ i ∈ s, (f i x) • (cov i) X t x + isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' + (fun i ↦ (cov i).isCovariantDerivativeOn) hf + +omit [IsManifold I 0 M] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +/-- A convex combination of two `C^k` connections is a `C^k` connection. -/ +lemma ContMDiffCovariantDerivativeOn.convexCombination [IsManifold I 1 M] + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u} {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiffOn I 𝓘(𝕜) n f u) + (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) + (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : + ContMDiffCovariantDerivativeOn F n (fun X σ ↦ (f • (cov X σ)) + (1 - f) • (cov' X σ)) u where + regularity hX hσ := by + apply ContMDiffOn.add_section + · exact hf.smul_section <| Hcov.regularity hX hσ + · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.regularity hX hσ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma convexCombination_isRegular [IsManifold I 1 M] (cov cov' : CovariantDerivative I F V) +lemma _root_.IsCovariantDerivativeOn.convexCombination_isRegular [IsManifold I 1 M] + (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : IsCkConnection cov n) (hcov' : IsCkConnection cov' n) : IsCkConnection (convexCombination cov cov' f) n where @@ -365,7 +411,6 @@ lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n (T% (f i • (cov i) X σ)) := by apply (hf' i hi).smul_section <| IsCkConnection.regularity hX hσ (self := hcov i hi) - simp only [Finset.sum_apply, Pi.smul_apply'] exact .sum_section (t := fun i ↦ f i • (cov i) X σ) ms -- Future: prove a version with a locally finite sum, and deduce that C^k connections always @@ -379,18 +424,19 @@ variable (E E') in noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where toFun X s := fun x ↦ fderiv 𝕜 s x (X x) - addX X X' σ := by ext; simp - smulX X σ c' := by ext; simp - addσ X σ σ' e hσ hσ' := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' - rw [fderiv_add hσ hσ'] - rfl - smul_const_σ X σ a := by ext; simp [fderiv_const_smul_of_field a] - leibniz X σ f x hσ hf := by - have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := - fderiv_smul (by simp_all) (by simp_all) - simp [this, bar] - rfl + isCovariantDerivativeOn := + { addX X X' σ x _ := by simp + smulX X σ c' x _ := by simp + addσ X σ σ' x hσ hσ' hx := by + rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' + rw [fderiv_add hσ hσ'] + rfl + smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] + leibniz X σ f x hσ hf hx := by + have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := + fderiv_smul (by simp_all) (by simp_all) + simp [this, bar] + rfl } -- TODO: does it make sense to speak of analytic connections? if so, change the definition of -- regularity and use ∞ from `open scoped ContDiff` instead. @@ -419,23 +465,22 @@ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') (⊤ : ℕ -- or perhaps a contMDiffOn version of this lemma? sorry -open scoped Classical in -@[simps] -noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : - CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where - toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) - addX X X' σ := by - ext x + +lemma of_endomorophism_isCovariantDerivativeOn (A : E → E →L[𝕜] E' →L[𝕜] E') : + IsCovariantDerivativeOn E' (Bundle.Trivial E E') + (fun (X : Π x : E, TangentSpace 𝓘(𝕜, E) x) (σ : E → E') x ↦ + fderiv 𝕜 σ x (X x) + A x (X x) (σ x)) univ where + addX X X' σ x _ := by by_cases h : DifferentiableAt 𝕜 σ x · simp [map_add]; abel · simp [fderiv_zero_of_not_differentiableAt h] - smulX X σ c' := by ext; simp - addσ X σ σ' e hσ hσ' := by + smulX X σ c' := by simp + addσ X σ σ' x hσ hσ' hx := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' simp [fderiv_add hσ hσ'] abel - smul_const_σ X σ a := by ext; simp [fderiv_const_smul_of_field a] - leibniz X σ f x hσ hf := by + smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] + leibniz X σ f x hσ hf hx := by rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ rw [mdifferentiableAt_iff_differentiableAt] at hf have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := @@ -443,7 +488,10 @@ noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : simp [this, bar] module --- TODO: prove something about the regularity of this connection +noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : + CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where + toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) + isCovariantDerivativeOn := of_endomorophism_isCovariantDerivativeOn A section real @@ -509,16 +557,15 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- `cov X σ x` only depends on `X` via `X x` -/ -lemma congr_X_at (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hXX' : X x = X' x) : +lemma congr_X_at {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + [T2Space M] [IsManifold I ∞ M] {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) + (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hx : x ∈ u) (hXX' : X x = X' x) : cov X σ x = cov X' σ x := by apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' · intro f X - rw [cov.smulX] - rfl + rw [hcov.smulX] · intro X X' - rw [cov.addX] - rfl + rw [hcov.addX] /- TODO: are these lemmas still useful after the general tensoriality lemma? are they worth extracting separately? @@ -566,21 +613,27 @@ lemma congr_σ_of_eventuallyEq /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ -def differenceAux (cov cov' : CovariantDerivative I F V) : +def differenceAux (cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := fun X σ ↦ cov X σ - cov' X σ omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in + [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] + [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] in @[simp] -lemma differenceAux_apply (cov cov' : CovariantDerivative I F V) +lemma differenceAux_apply + (cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) : differenceAux cov cov' X σ = cov X σ - cov' X σ := rfl omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in -lemma differenceAux_smul_eq (cov cov' : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} +lemma _root_.IsCovariantDerivativeOn.differenceAux_smul_eq + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) + (hcov' : IsCovariantDerivativeOn F V cov' u) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) + {x : M} (hx : x ∈ u := by trivial) (hσ : MDifferentiableAt% (T% σ) x) (hf : MDifferentiableAt% f x) : differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= @@ -588,47 +641,54 @@ lemma differenceAux_smul_eq (cov cov' : CovariantDerivative I F V) _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl _ = (f x • cov X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) - (f x • cov' X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by - simp [cov.leibniz X _ _ _ hσ hf, cov'.leibniz X _ _ _ hσ hf] + simp [hcov.leibniz X hσ hf, hcov'.leibniz X hσ hf] _ = f x • cov X σ x - f x • cov' X σ x := by simp _ = f x • (cov X σ x - cov' X σ x) := by simp [smul_sub] _ = _ := rfl omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in -lemma differenceAux_smul_eq' (cov cov' : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) (x : M) : +lemma _root_.IsCovariantDerivativeOn.differenceAux_smul_eq' + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) + (hcov' : IsCovariantDerivativeOn F V cov' u) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) + {x : M} (hx : x ∈ u := by trivial) : differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by - simp [differenceAux, cov.smulX, cov'.smulX, smul_sub] + simp [differenceAux, hcov.smulX, hcov'.smulX, smul_sub] omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ -lemma differenceAux_tensorial (cov cov' : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] +lemma _root_.IsCovariantDerivativeOn.differenceAux_tensorial + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) + (hcov' : IsCovariantDerivativeOn F V cov' u) + [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} (hσ : MDifferentiableAt% (T% σ) x₀) (hσ' : MDifferentiableAt% (T% σ') x₀) - (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) : + (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) (hx : x₀ ∈ u := by trivial) : differenceAux cov cov' X σ x₀ = differenceAux cov cov' X' σ' x₀ := by - trans cov.differenceAux cov' X' σ x₀ - · let φ : (Π x : M, TangentSpace I x) → (Π x, V x) := fun X ↦ cov.differenceAux cov' X σ + trans differenceAux cov cov' X' σ x₀ + · let φ : (Π x : M, TangentSpace I x) → (Π x, V x) := fun X ↦ differenceAux cov cov' X σ change φ X x₀ = φ X' x₀ apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' · intro f X - apply differenceAux_smul_eq' + apply hcov.differenceAux_smul_eq' hcov' · intro X X' unfold φ CovariantDerivative.differenceAux - rw [cov.addX, cov'.addX] - simp + simp only [Pi.sub_apply, hcov.addX, hcov'.addX] abel - · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ cov.differenceAux cov' X' σ + · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ differenceAux cov cov' X' σ change φ σ x₀ = φ σ' x₀ apply tensoriality_criterion (E := E) (I := I) F V F V hσ hσ' hσσ' · intro f σ x hf - exact differenceAux_smul_eq cov cov' X' σ f hf x + exact hcov.differenceAux_smul_eq hcov' X' σ f hx hf x · intro σ σ' hσ hσ' - unfold φ CovariantDerivative.differenceAux + unfold φ differenceAux simp - rw [cov.addσ, cov'.addσ] <;> try assumption + rw [hcov.addσ, hcov'.addσ] <;> try assumption abel -- TODO: either change `localFrame` to make sure it is everywhere smooth @@ -778,13 +838,15 @@ noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDime (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y' (x := x)) x := by - apply cov.addσ + apply cov.isCovariantDerivativeOn.addσ · exact (contMDiff_extend _ _).mdifferentiableAt (n := ∞) (hn := by norm_num) · apply (contMDiff_extend _ _).mdifferentiableAt (n := ∞) (hn := by norm_num) simp [A, B] module map_smul' a v := by - simp [fderiv_const_smul_of_field, cov.smul_const_σ] + have := cov.isCovariantDerivativeOn.smul_const_σ (extend 𝓘(ℝ, E) E X (x := x)) + (extend 𝓘(ℝ, E) E' v (x := x)) a (x := x) + simp [fderiv_const_smul_of_field, difference, this] module @[simps!] @@ -799,7 +861,7 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi toFun X := cov.endomorph_of_trivial_aux' x X map_add' X Y := by ext Z - simp [cov.addX (extend 𝓘(ℝ, E) E X (x := x)) + simp [cov.isCovariantDerivativeOn.addX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E Y (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x))] module map_smul' t X := by @@ -810,8 +872,9 @@ noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDi trans t • (cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) x) - t • (fderiv ℝ (extend 𝓘(ℝ, E) E' Z (x := x)) x) X swap; · module - let h := cov.smulX (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) - simpa using congr_fun h x + have := cov.isCovariantDerivativeOn.smulX + (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) (x := x) + simpa @[simps!] noncomputable def endomorph_of_trivial_aux''' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] @@ -834,19 +897,20 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), ∀ X : (x : E) → TangentSpace 𝓘(ℝ, E) x, ∀ σ : (x : E) → Trivial E E' x, ∀ x : E, - MDifferentiableAt% (T% σ) x → + MDiffAt (T% σ) x → cov X σ x = (CovariantDerivative.of_endomorphism A) X σ x := by use cov.endomorph_of_trivial_aux''' intro X σ x hσ -- TODO: this is unfolding too much; need to fix this manually below... -- think about a better design that actually works... - simp only [of_endomorphism_toFun, endomorph_of_trivial_aux'''_apply_apply] + simp only [of_endomorphism, endomorph_of_trivial_aux'''_apply_apply] rw [← CovariantDerivative.trivial_toFun] have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by -- Do not unfold differenceAux: we use the tensoriality of differenceAux. rw [difference] - apply differenceAux_tensorial cov (trivial E E') hσ ?_ - (extend_apply_self (X x)).symm (extend_apply_self (σ x)).symm + apply cov.isCovariantDerivativeOn.differenceAux_tensorial + (trivial E E').isCovariantDerivativeOn hσ ?_ (extend_apply_self (X x)).symm + (extend_apply_self (σ x)).symm exact ((contMDiff_extend _).contMDiffAt).mdifferentiableAt (by norm_num) have h₂ : cov.difference (trivial E E') x (X x) (σ x) = cov (extend 𝓘(ℝ, E) E (X x)) (extend 𝓘(ℝ, E) E' (σ x)) x @@ -928,8 +992,8 @@ lemma torsion_add_left_apply [CompleteSpace E] {x : M} (hX : MDifferentiableAt% (T% X) x) (hX' : MDifferentiableAt% (T% X') x) : torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by - simp [torsion, cov.addX] - rw [cov.addσ _ X X' _ hX hX', VectorField.mlieBracket_add_left hX hX'] + simp [torsion, cov.isCovariantDerivativeOn.addX X X' (x := x)] + rw [cov.isCovariantDerivativeOn.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] module variable (Y) in @@ -958,8 +1022,8 @@ variable (Y) in lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) (hX : MDifferentiableAt% (T% X) x) : torsion cov (f • X) Y x = f x • torsion cov X Y x := by - simp only [torsion, cov.smulX, Pi.sub_apply, Pi.smul_apply'] - rw [cov.leibniz Y X f x hX hf, VectorField.mlieBracket_smul_left hf hX] + simp only [torsion, cov.isCovariantDerivativeOn.smulX X Y f, Pi.sub_apply] + rw [cov.isCovariantDerivativeOn.leibniz Y hX hf, VectorField.mlieBracket_smul_left hf hX] simp [bar, smul_sub] abel From 3a7288ddb928f5180bf4cd1ff3d68e9f1741b3e7 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 8 Jul 2025 15:02:00 +0200 Subject: [PATCH 178/601] Remove torsion sorry --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c42e8dd7e0ba6a..0b1411f061dc60 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1074,6 +1074,7 @@ def IsTorsionFree : Prop := torsion cov = 0 lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] + -- This should be obvious, I'm doing something wrong. lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by @@ -1081,9 +1082,8 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ constructor · intro h intro X Y - have : torsion cov X Y = 0 := sorry - rw [torsion] at this - sorry + have : torsion cov X Y = 0 := by simp [h] + exact eq_of_sub_eq_zero this · intro h ext X Y x specialize h X Y From 10bbfee365d3f2aa4714d2a24e2b305959908263 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 15:03:50 +0200 Subject: [PATCH 179/601] Tweak comment --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 0b1411f061dc60..a75418ae90307c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1080,9 +1080,9 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by simp [IsTorsionFree] constructor - · intro h - intro X Y + · intro h X Y have : torsion cov X Y = 0 := by simp [h] + -- XXX: abel, ring, module and grind all fail here exact eq_of_sub_eq_zero this · intro h ext X Y x From d2a9693139995f94d1428e4adbad0f61a760335d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 15:08:02 +0200 Subject: [PATCH 180/601] chore: use shorter elaborator notation --- .../VectorBundle/CovariantDerivative.lean | 72 +++++++++---------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index a75418ae90307c..ae4c073ae73978 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -57,7 +57,7 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @[simp] theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : - MDifferentiableAt% (T% σ) e ↔ + MDiffAt (T% σ) e ↔ DifferentiableAt 𝕜 σ e := by simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] @@ -77,9 +77,8 @@ variable {I F V x} in if one is differentiable at `x` then so is the other. Issue: EventuallyEq does not work for dependent functions. -/ lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ₁ : MDifferentiableAt% (T% σ) x) - (hσ₂ : ∀ x ∈ s, σ x = σ' x) : - MDifferentiableAt% (T% σ') x := by + (hσ₁ : MDiffAt (T% σ) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : + MDiffAt (T% σ') x := by apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ -- TODO: split off a lemma? apply Set.EqOn.eventuallyEq_of_mem _ hs @@ -93,8 +92,8 @@ variable {I F V x} in one is differentiable at `x` iff the other is. -/ lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ : ∀ x ∈ s, σ x = σ' x) : - MDifferentiableAt% (T% σ) x ↔ - MDifferentiableAt% (T% σ') x := + MDiffAt (T% σ) x ↔ + MDiffAt (T% σ') x := ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ @@ -110,11 +109,11 @@ structure IsCovariantDerivativeOn smulX (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜) {x : M} (hx : x ∈ s := by trivial) : f (g • X) σ x = g x • f X σ x addσ (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x} - (hσ : MDifferentiableAt% (T% σ) x) (hσ' : MDifferentiableAt% (T% σ') x) + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : f X (σ + σ') x = f X σ x + f X σ' x leibniz (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {g : M → 𝕜} {x} - (hσ : MDifferentiableAt% (T% σ) x) (hg : MDifferentiableAt% g x) (hx : x ∈ s := by trivial): + (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x smul_const_σ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) {x} (hx : x ∈ s := by trivial) : f X (a • σ) x = a • f X σ x @@ -211,7 +210,7 @@ This is a class so typeclass inference can deduce this automatically. -/ class _root_.IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - ContMDiff% (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → + CMDiff (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → ContMDiff% k (T% (cov X σ)) -- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection @@ -241,7 +240,7 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] lemma _root_.IsCovariantDerivativeOn.zeroσ (hf : IsCovariantDerivativeOn F V f s) (X : Π x : M, TangentSpace I x) {x} (hx : x ∈ s := by trivial) : f X 0 x = 0 := by - have : MDifferentiableAt% (T% fun x ↦ (0 : V x)) x := by -- TODO: fix using upcoming mdiff lemma + have : MDiffAt (T% fun x ↦ (0 : V x)) x := by -- TODO: fix using upcoming mdiff lemma exact (contMDiff_zeroSection 𝕜 V).mdifferentiableAt le_rfl simpa using (hf.addσ X this this : f X (0+0) x = _) @@ -375,7 +374,7 @@ omit [IsManifold I 0 M] /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ lemma ContMDiffCovariantDerivativeOn.convexCombination [IsManifold I 1 M] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u} {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiffOn I 𝓘(𝕜) n f u) + {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : ContMDiffCovariantDerivativeOn F n (fun X σ ↦ (f • (cov X σ)) + (1 - f) • (cov' X σ)) u where @@ -573,7 +572,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ [VectorBundle ℝ F V] in lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} - (hσ : MDifferentiableAt% (T% σ) x) + (hσ : MDiffAt (T% σ) x) (f : SmoothBumpFunction I x) : cov X ((f : M → ℝ) • σ) x = cov X σ x := by rw [cov.leibniz _ _ _ _ hσ] @@ -591,7 +590,7 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ lemma congr_σ_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσ : MDifferentiableAt% (T% σ) x) + (hσ : MDiffAt (T% σ) x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : cov X σ x = cov X σ' x := by -- Choose a smooth bump function ψ with support around `x` contained in `s` @@ -634,8 +633,8 @@ lemma _root_.IsCovariantDerivativeOn.differenceAux_smul_eq (hcov' : IsCovariantDerivativeOn F V cov' u) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) - (hσ : MDifferentiableAt% (T% σ) x) - (hf : MDifferentiableAt% f x) : + (hσ : MDiffAt (T% σ) x) + (hf : MDiffAt f x) : differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= calc _ _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl @@ -666,8 +665,8 @@ lemma _root_.IsCovariantDerivativeOn.differenceAux_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} - (hσ : MDifferentiableAt% (T% σ) x₀) - (hσ' : MDifferentiableAt% (T% σ') x₀) + (hσ : MDiffAt (T% σ) x₀) + (hσ' : MDiffAt (T% σ') x₀) (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) (hx : x₀ ∈ u := by trivial) : differenceAux cov cov' X σ x₀ = differenceAux cov cov' X' σ' x₀ := by trans differenceAux cov cov' X' σ x₀ @@ -782,7 +781,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDifferentiable% (T% extend I F σ₀) := + MDiff (T% extend I F σ₀) := contMDiff_extend σ₀ |>.mdifferentiable (by simp) /-- The difference of two covariant derivatives, as a tensorial map -/ @@ -943,8 +942,8 @@ variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} lemma proj_mderiv {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) - (hX : MDifferentiableAt% (T% X) x) - (hσ : MDifferentiableAt% (T% σ) x) : + (hX : MDiffAt (T% X) x) + (hσ : MDiffAt (T% σ) x) : cov X σ x = cov.proj (σ x) (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x (X x)) := by sorry @@ -989,8 +988,8 @@ lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_ze variable (Y) in lemma torsion_add_left_apply [CompleteSpace E] {x : M} - (hX : MDifferentiableAt% (T% X) x) - (hX' : MDifferentiableAt% (T% X') x) : + (hX : MDiffAt (T% X) x) + (hX' : MDiffAt (T% X') x) : torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by simp [torsion, cov.isCovariantDerivativeOn.addX X X' (x := x)] rw [cov.isCovariantDerivativeOn.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] @@ -998,29 +997,27 @@ lemma torsion_add_left_apply [CompleteSpace E] {x : M} variable (Y) in lemma torsion_add_left [CompleteSpace E] - (hX : MDifferentiable% (T% X)) - (hX' : MDifferentiable% (T% X')) : + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by ext x exact cov.torsion_add_left_apply _ (hX x) (hX' x) lemma torsion_add_right_apply [CompleteSpace E] {x : M} - (hX : MDifferentiableAt% (T% X) x) - (hX' : MDifferentiableAt% (T% X') x) : + (hX : MDiffAt (T% X) x) + (hX' : MDiffAt (T% X') x) : torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by rw [torsion_antisymm, Pi.neg_apply, cov.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] simp; abel lemma torsion_add_right [CompleteSpace E] - (hX : MDifferentiable% (T% X)) - (hX' : MDifferentiable% (T% X')) : + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module variable (Y) in -lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) - (hX : MDifferentiableAt% (T% X) x) : +lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDiffAt f x) + (hX : MDiffAt (T% X) x) : torsion cov (f • X) Y x = f x • torsion cov X Y x := by simp only [torsion, cov.isCovariantDerivativeOn.smulX X Y f, Pi.sub_apply] rw [cov.isCovariantDerivativeOn.leibniz Y hX hf, VectorField.mlieBracket_smul_left hf hX] @@ -1028,22 +1025,20 @@ lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MD abel variable (Y) in -lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) - (hX : MDifferentiable% (T% X)) : +lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : torsion cov (f • X) Y = f • torsion cov X Y := by ext x exact cov.torsion_smul_left_apply _ (hf x) (hX x) variable (X) in -lemma torsion_smul_right_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDifferentiableAt% f x) - (hX : MDifferentiableAt% (T% Y) x) : +lemma torsion_smul_right_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDiffAt f x) + (hX : MDiffAt (T% Y) x) : torsion cov X (f • Y) x = f x • torsion cov X Y x := by rw [torsion_antisymm, Pi.neg_apply, torsion_smul_left_apply X hf hX, torsion_antisymm X] simp variable (X) in -lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDifferentiable% f) - (hY : MDifferentiable% (T% Y)) : +lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : torsion cov X (f • Y) = f • torsion cov X Y := by ext x apply cov.torsion_smul_right_apply _ (hf x) (hY x) @@ -1054,8 +1049,8 @@ the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] {X X' Y Y' : Π x : M, TangentSpace I x} {x₀ : M} - (hX : MDifferentiableAt% (T% X) x₀) (hX' : MDifferentiableAt% (T% X') x₀) - (hY : MDifferentiableAt% (T% Y) x₀) (hY' : MDifferentiableAt% (T% Y') x₀) + (hX : MDiffAt (T% X) x₀) (hX' : MDiffAt (T% X') x₀) + (hY : MDiffAt (T% Y) x₀) (hY' : MDiffAt (T% Y') x₀) (hXX' : X x₀ = X' x₀) (hYY' : Y x₀ = Y' x₀) : (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' @@ -1074,7 +1069,6 @@ def IsTorsionFree : Prop := torsion cov = 0 lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] - -- This should be obvious, I'm doing something wrong. lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by From 15e76fc088f44b9fd2da827b15d2887d52cd17d1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 13:56:05 +0200 Subject: [PATCH 181/601] chore(GramSchmidtOrtho): tweak formatting --- .../InnerProductSpace/GramSchmidtOrtho.lean | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 3dddad6ee33f42..948caac5eb0b70 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -16,20 +16,15 @@ and outputs a set of orthogonal vectors which have the same span. ## Main results -- `gramSchmidt` : the Gram-Schmidt process -- `gramSchmidt_orthogonal` : - `gramSchmidt` produces an orthogonal system of vectors. -- `span_gramSchmidt` : - `gramSchmidt` preserves span of vectors. -- `gramSchmidt_ne_zero` : - If the input vectors of `gramSchmidt` are linearly independent, +- `gramSchmidt`: the Gram-Schmidt process +- `gramSchmidt_orthogonal`: `gramSchmidt` produces an orthogonal system of vectors. +- `span_gramSchmidt`: `gramSchmidt` preserves span of vectors. +- `gramSchmidt_ne_zero`: if the input vectors of `gramSchmidt` are linearly independent, then the output vectors are non-zero. -- `gramSchmidt_basis` : - The basis produced by the Gram-Schmidt process when given a basis as input. -- `gramSchmidtNormed` : +- `gramSchmidt_basis`: the basis produced by the Gram-Schmidt process when given a basis as input +- `gramSchmidtNormed`: the normalized `gramSchmidt` (i.e each vector in `gramSchmidtNormed` has unit length.) -- `gramSchmidt_orthonormal` : - `gramSchmidtNormed` produces an orthornormal system of vectors. +- `gramSchmidt_orthonormal`: `gramSchmidtNormed` produces an orthornormal system of vectors. - `gramSchmidtOrthonormalBasis`: orthonormal basis constructed by the Gram-Schmidt process from an indexed set of vectors of the right size -/ @@ -230,8 +225,7 @@ theorem coe_gramSchmidtBasis (b : Basis ι 𝕜 E) : (gramSchmidtBasis b : ι Basis.coe_mk _ _ variable (𝕜) in -/-- the normalized `gramSchmidt` -(i.e each vector in `gramSchmidtNormed` has unit length.) -/ +/-- the normalized `gramSchmidt` (i.e each vector in `gramSchmidtNormed` has unit length.) -/ noncomputable def gramSchmidtNormed (f : ι → E) (n : ι) : E := (‖gramSchmidt 𝕜 f n‖ : 𝕜)⁻¹ • gramSchmidt 𝕜 f n From c12c73c73c192213cac64e0449a092317d8ec150 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 14:19:44 +0200 Subject: [PATCH 182/601] checkpoint --- Mathlib.lean | 1 + .../VectorBundle/OrthonormalFrame.lean | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean diff --git a/Mathlib.lean b/Mathlib.lean index 401c15795ace0c..2ca4f89849963c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3731,6 +3731,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Hom import Mathlib.Geometry.Manifold.VectorBundle.LeviCivita import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Pullback import Mathlib.Geometry.Manifold.VectorBundle.Riemannian import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean new file mode 100644 index 00000000000000..b879ff6c01b9d0 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -0,0 +1,60 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +import Mathlib.Geometry.Manifold.VectorBundle.Riemannian + +/-! +# Existence of orthonormal frames on Riemannian vector bundles + +In this file, we prove that a Riemannian vector bundle has orthonormal frames near each point. +These are constructed by taking any local frame, and applying Gram-Schmidt orthonormalisation +to it (point-wise). If the bundle metric is `C^k`, the resulting orthonormal frame also is. + +TODO: add main results, tags, etc + +## Implementation note + +Like local frames, orthonormal frames use the junk value pattern: their value is meaningless +outside of the `baseSet` of the trivialisation used to define them. + +## Tags +vector bundle, local frame, smoothness + +-/ + +open Manifold Bundle ContinuousLinearMap ENat Bornology +open scoped ContDiff Topology + +-- Let `V` be a smooth vector bundle with a `C^n` Riemannian structure over a `C^k` manifold `B`. +variable + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace ℝ EB] + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners ℝ EB HB} {n : WithTop ℕ∞} + {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] + {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + {E : B → Type*} [TopologicalSpace (TotalSpace F E)] [∀ x, NormedAddCommGroup (E x)] + [∀ x, InnerProductSpace ℝ (E x)] [FiberBundle F E] [VectorBundle ℝ F E] + [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] + +variable {ι : Type*} + +-- bad, for prototyping +variable (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) + [MemTrivializationAtlas e] + (b : Basis ι ℝ F) {x : B} (hx : x ∈ e.baseSet) +namespace Basis + +-- TODO: do Gram-Schmidt in R bundles first! + +noncomputable def orthonormalFrame_toBasis_at + : Basis ι ℝ (E x) := + sorry -- b.map (e.linearEquivAt (R := 𝕜) x hx).symm + +open scoped Classical in +-- If x is outside of `e.baseSet`, this returns the junk value 0. +noncomputable def orthonormalFrame : ι → (x : B) → E x := fun i x ↦ + -- idea: take the vector b i and apply the trivialisation e to it. + b.localFrame e x--if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 From 115a1df8ebcee034f1e1038d375b059785380c76 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 15:59:36 +0200 Subject: [PATCH 183/601] chore: namespace gramSchmidt to InnerProductSpace, to make room for VectorBundle.gramSchmidt --- .../Analysis/InnerProductSpace/GramSchmidtOrtho.lean | 10 ++++++++++ Mathlib/LinearAlgebra/Matrix/LDL.lean | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 948caac5eb0b70..ff950bfc0dddb8 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -39,6 +39,8 @@ attribute [local instance] IsWellOrder.toHasWellFounded local notation "⟪" x ", " y "⟫" => inner 𝕜 x y +namespace InnerProductSpace + /-- The Gram-Schmidt process takes a set of vectors as input and outputs a set of orthogonal vectors which have the same span. -/ noncomputable def gramSchmidt [WellFoundedLT ι] (f : ι → E) (n : ι) : E := @@ -216,6 +218,12 @@ theorem gramSchmidt_linearIndependent {f : ι → E} (h₀ : LinearIndependent linearIndependent_of_ne_zero_of_inner_eq_zero (fun _ => gramSchmidt_ne_zero _ h₀) fun _ _ => gramSchmidt_orthogonal 𝕜 f +end InnerProductSpace + +open InnerProductSpace + +variable {𝕜} + /-- When given a basis, `gramSchmidt` produces a basis. -/ noncomputable def gramSchmidtBasis (b : Basis ι 𝕜 E) : Basis ι 𝕜 E := Basis.mk (gramSchmidt_linearIndependent b.linearIndependent) @@ -268,6 +276,8 @@ theorem gramSchmidt_orthonormal' (f : ι → E) : rw [Subtype.ext_iff] at hij simp [gramSchmidtNormed, inner_smul_left, inner_smul_right, gramSchmidt_orthogonal 𝕜 f hij] +open Submodule Set Order + theorem span_gramSchmidtNormed (f : ι → E) (s : Set ι) : span 𝕜 (gramSchmidtNormed 𝕜 f '' s) = span 𝕜 (gramSchmidt 𝕜 f '' s) := by refine span_eq_span diff --git a/Mathlib/LinearAlgebra/Matrix/LDL.lean b/Mathlib/LinearAlgebra/Matrix/LDL.lean index 5ec32c52b8c69f..5ad7cd201075cc 100644 --- a/Mathlib/LinearAlgebra/Matrix/LDL.lean +++ b/Mathlib/LinearAlgebra/Matrix/LDL.lean @@ -36,9 +36,9 @@ section set_options set_option quotPrecheck false local notation "⟪" x ", " y "⟫ₑ" => inner 𝕜 (WithLp.toLp 2 x) (WithLp.toLp 2 y) -open Matrix +open Matrix InnerProductSpace -open scoped Matrix ComplexOrder +open scoped ComplexOrder variable {S : Matrix n n 𝕜} [Fintype n] (hS : S.PosDef) From 906c2dfd8de27f4a0ca8f7ecb47e0af6204e802a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 15:25:33 +0200 Subject: [PATCH 184/601] WIP: define Gram-Schmidt on vector bundle sections Copy-paste more API: need to fix a number of proofs Style and small sorries --- Mathlib.lean | 1 + .../VectorBundle/GramSchmidtOrtho.lean | 262 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2ca4f89849963c..e00c8d72dc3de0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3727,6 +3727,7 @@ import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear +import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho import Mathlib.Geometry.Manifold.VectorBundle.Hom import Mathlib.Geometry.Manifold.VectorBundle.LeviCivita import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean new file mode 100644 index 00000000000000..896353fcfbe83a --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -0,0 +1,262 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho +import Mathlib.Geometry.Manifold.VectorBundle.Riemannian + +/-! +# Gram-Schmidt orthonormalisation on sections of Riemannian vector bundles + +In this file, we provide a version of the Gram-Schmidt orthonormalisation procedure +for sections of Riemannian vector bundles: this produces a system of sections which orthogonal +with respect to the bundle metric. If the initial sections were linearly independent resp. +formed a basis at the point, so do the normalised sections. + +If the bundle metric is `C^k`, then the procedure preserves regularity of sections: +if all sections are `C^k`, so are their normalised versions. + +This is used in OrthonormalFrame.lean` to convert a local frame to a local orthonormal frame. + +TODO: add main results + +## Implementation note + + +## Tags +vector bundle, bundle metric, orthonormal frame, Gram-Schmidt + +-/ + +open Manifold Bundle ContinuousLinearMap ENat Bornology +open scoped ContDiff Topology + +-- Let `V` be a smooth vector bundle with a `C^n` Riemannian structure over a `C^k` manifold `B`. +variable + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace ℝ EB] + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners ℝ EB HB} {n : WithTop ℕ∞} + {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] + {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + {E : B → Type*} [TopologicalSpace (TotalSpace F E)] [∀ x, NormedAddCommGroup (E x)] + [∀ x, InnerProductSpace ℝ (E x)] [FiberBundle F E] [VectorBundle ℝ F E] + [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] + +variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] + +attribute [local instance] IsWellOrder.toHasWellFounded + +local notation "⟪" x ", " y "⟫" => inner ℝ x y + +open Finset + +namespace VectorBundle + +open Submodule + +/-- The Gram-Schmidt process takes a set of sections as input +and outputs a set of sections which are point-wise orthogonal with the same span. +Basically, we apply the Gram-Schmidt algorithm point-wise. -/ +noncomputable def gramSchmidt [WellFoundedLT ι] + (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ + s n x - ∑ i : Finset.Iio n, (ℝ ∙ VectorBundle.gramSchmidt s i x).orthogonalProjection (s n x) +termination_by n +decreasing_by exact Finset.mem_Iio.1 i.2 + +-- Let `s i` be a collection of sections in `E`, indexed by `ι`. +variable {s : ι → (x : B) → E x} + +omit [TopologicalSpace B] + +variable (s) in +/-- This lemma uses `∑ i in` instead of `∑ i :`. -/ +theorem gramSchmidt_def (n : ι) (x) : + gramSchmidt s n x = + s n x - ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).orthogonalProjection (s n x) := by + rw [← sum_attach, attach_eq_univ, gramSchmidt] + +variable (s) in +theorem gramSchmidt_def' (n : ι) (x) : + s n x = gramSchmidt s n x + + ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).orthogonalProjection (s n x) := by + rw [gramSchmidt_def, sub_add_cancel] + +variable (s) in +theorem gramSchmidt_def'' (n : ι) (x) : + s n x = gramSchmidt s n x + ∑ i ∈ Iio n, + (⟪gramSchmidt s i x, s n x⟫ / (‖gramSchmidt s i x‖) ^ 2) • gramSchmidt s i x := by + convert gramSchmidt_def' s n x + rw [orthogonalProjection_singleton, RCLike.ofReal_pow] + rfl + +variable (s) in +@[simp] +theorem gramSchmidt_zero {ι : Type*} [LinearOrder ι] [LocallyFiniteOrder ι] [OrderBot ι] + [WellFoundedLT ι] (s : ι → (x : B) → E x) : gramSchmidt s ⊥ = s ⊥ := by + ext x + rw [gramSchmidt_def, Iio_eq_Ico, Finset.Ico_self, Finset.sum_empty, sub_zero] + +variable (s) in +/-- **Gram-Schmidt Orthogonalisation**: +`gramSchmidt` produces an orthogonal system of vectors. -/ +theorem gramSchmidt_orthogonal {a b : ι} (h₀ : a ≠ b) (x) : + ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := by + suffices ∀ a b : ι, a < b → ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 by + rcases h₀.lt_or_gt with ha | hb + · exact this _ _ ha + · rw [inner_eq_zero_symm] + exact this _ _ hb + clear h₀ a b + intro a b h₀ + revert a + apply wellFounded_lt.induction b + intro b ih a h₀ + simp only [gramSchmidt_def s b, inner_sub_right, inner_sum, orthogonalProjection_singleton, + inner_smul_right] + rw [Finset.sum_eq_single_of_mem a (Finset.mem_Iio.mpr h₀)] + · by_cases h : gramSchmidt s a x = 0 + · simp only [h, inner_zero_left, zero_div, zero_mul, sub_zero] + · rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K, div_mul_cancel₀, sub_self] + rwa [inner_self_ne_zero] + intro i hi hia + simp only [mul_eq_zero, div_eq_zero_iff] + right + rcases hia.lt_or_gt with hia₁ | hia₂ + · rw [inner_eq_zero_symm] + exact ih a h₀ i hia₁ + · exact ih i (mem_Iio.1 hi) a hia₂ + +variable (s) in +/-- This is another version of `gramSchmidt_orthogonal` using `Pairwise` instead. -/ +theorem gramSchmidt_pairwise_orthogonal (x) : + Pairwise fun a b ↦ ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := fun _ _ h ↦ + gramSchmidt_orthogonal s h _ + +variable (s) in +theorem gramSchmidt_inv_triangular {i j : ι} (hij : i < j) (x) : + ⟪gramSchmidt s j x, s i x⟫ = 0 := by + rw [gramSchmidt_def'' s] + simp only [inner_add_right, inner_sum, inner_smul_right] + set b /-: ι → E-/ := gramSchmidt s + convert zero_add (0 : ℝ) + · exact gramSchmidt_orthogonal s hij.ne' x + apply Finset.sum_eq_zero + rintro k hki' + have hki : k < i := by simpa using hki' + have : ⟪b j x, b k x⟫ = 0 := gramSchmidt_orthogonal s (hki.trans hij).ne' x + simp [this] + +open Submodule Set Order + +variable (s) in +theorem mem_span_gramSchmidt {i j : ι} (hij : i ≤ j) (x) : + s i x ∈ span ℝ ((gramSchmidt s · x) '' Set.Iic j) := by + rw [gramSchmidt_def' s i] + simp_rw [orthogonalProjection_singleton] + exact Submodule.add_mem _ (subset_span <| mem_image_of_mem _ hij) + (Submodule.sum_mem _ fun k hk ↦ smul_mem (span ℝ ((gramSchmidt s · x) '' Set.Iic j)) _ <| + subset_span <| mem_image_of_mem (gramSchmidt s · x) <| (Finset.mem_Iio.1 hk).le.trans hij) + +variable (s) in +theorem gramSchmidt_mem_span (x) : + ∀ {j i}, i ≤ j → gramSchmidt s i x ∈ span ℝ ((s · x) '' Set.Iic j) := by + intro j i hij + rw [gramSchmidt_def s i] + simp_rw [orthogonalProjection_singleton] + refine Submodule.sub_mem _ (subset_span (mem_image_of_mem _ hij)) + (Submodule.sum_mem _ fun k hk ↦ ?_) + let hkj : k < j := (Finset.mem_Iio.1 hk).trans_le hij + exact smul_mem _ _ + (span_mono (image_subset (s · x) <| Set.Iic_subset_Iic.2 hkj.le) + <| gramSchmidt_mem_span _ le_rfl) +termination_by j => j + +variable (s) in +theorem span_gramSchmidt_Iic (c : ι) (x) : + span ℝ ((gramSchmidt s · x) '' Set.Iic c) = span ℝ ((s · x) '' Set.Iic c) := + span_eq_span (Set.image_subset_iff.2 fun _ ↦ gramSchmidt_mem_span _ _) <| + Set.image_subset_iff.2 fun _ hx ↦ mem_span_gramSchmidt s hx _ + +variable (s) in +theorem span_gramSchmidt_Iio (c : ι) (x) : + span ℝ ((gramSchmidt s · x) '' Set.Iio c) = span ℝ ((s · x) '' Set.Iio c) := by + refine span_eq_span (Set.image_subset_iff.2 fun _ hi ↦ + span_mono (image_subset _ <| Iic_subset_Iio.2 hi) <| gramSchmidt_mem_span _ _ le_rfl) <| + Set.image_subset_iff.2 fun _ hi ↦ + span_mono (image_subset _ <| Iic_subset_Iio.2 hi) <| fun hx ↦ ?_ + apply mem_span_gramSchmidt s le_rfl _ + +-- variable (s) in +-- /-- `gramSchmidt` preserves span of vectors. -/ +-- theorem span_gramSchmidt (x) : span ℝ (range (gramSchmidt ℝ (s · x))) = span ℝ (range (s · x)) := +-- span_eq_span (range_subset_iff.2 fun _ ↦ +-- span_mono (image_subset_range _ _) <| gramSchmidt_mem_span _ _ le_rfl) <| +-- range_subset_iff.2 fun _ ↦ +-- span_mono (image_subset_range _ _) <| mem_span_gramSchmidt _ _ le_rfl + +theorem gramSchmidt_of_orthogonal {x} (hs : Pairwise fun i j ↦ ⟪s i x, s j x⟫ = 0) : + ∀ i₀, gramSchmidt s i₀ x = s i₀ x:= by + intro i + rw [gramSchmidt_def] + trans s i x - 0 + · congr + apply Finset.sum_eq_zero + intro j hj + rw [Submodule.coe_eq_zero] + suffices span ℝ ((s · x) '' Set.Iic j) ⟂ ℝ ∙ s i x by + apply orthogonalProjection_mem_subspace_orthogonalComplement_eq_zero + rw [mem_orthogonal_singleton_iff_inner_left, ← mem_orthogonal_singleton_iff_inner_right] + exact this <| gramSchmidt_mem_span _ _ le_rfl + rw [isOrtho_span] + rintro u ⟨k, hk, rfl⟩ v (rfl : v = s i x) + apply hs + exact (lt_of_le_of_lt hk (Finset.mem_Iio.mp hj)).ne + · simp + +theorem gramSchmidt_ne_zero_coe (n : ι) (x) + (h₀ : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι))) : gramSchmidt s n x ≠ 0 := by + by_contra h + have h₁ : s n x ∈ span ℝ ((s · x) '' Set.Iio n) := by + rw [← span_gramSchmidt_Iio s n x, gramSchmidt_def' s, h, zero_add] + apply Submodule.sum_mem _ _ + intro a ha + simp only [orthogonalProjection_singleton] + apply Submodule.smul_mem _ _ _ + rw [Finset.mem_Iio] at ha + exact subset_span ⟨a, ha, by rfl⟩ + have h₂ : ((s · x) ∘ ((↑) : Set.Iic n → ι)) ⟨n, le_refl n⟩ ∈ + span ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι) '' Set.Iio ⟨n, le_refl n⟩) := by + rw [image_comp] + simpa using h₁ + apply LinearIndependent.notMem_span_image h₀ _ h₂ + simp only [Set.mem_Iio, lt_self_iff_false, not_false_iff] + +variable (s) in +/-- If the input vectors of `gramSchmidt` are linearly independent, +then the output vectors are non-zero. -/ +theorem gramSchmidt_ne_zero (n : ι) {x} (h₀ : LinearIndependent ℝ (s · x)) : + gramSchmidt s n x ≠ 0 := + gramSchmidt_ne_zero_coe _ x (h₀.comp _ Subtype.coe_injective) + +-- not needed at the moment: I want a point-wise version, along the lines +-- "if s i x is a basis, then gramSchmidgt s i x is a triangular matrix" +/- +/-- `gramSchmidt` produces a triangular matrix of vectors when given a basis. -/ +theorem gramSchmidt_triangular {x} {i j : ι} (hij : i < j) (b : Basis ι ℝ (E x)) : + b.repr (gramSchmidt b i x) j = 0 := sorry + b.repr (gramSchmidt b i) j = 0 := by + have : gramSchmidt ℝ b i ∈ span ℝ (gramSchmidt ℝ b '' Set.Iio j) := + subset_span ((Set.mem_image _ _ _).2 ⟨i, hij, rfl⟩) + have : gramSchmidt ℝ b i ∈ span ℝ (b '' Set.Iio j) := by rwa [← span_gramSchmidt_Iio ℝ b j] + have : ↑(b.repr (gramSchmidt ℝ b i)).support ⊆ Set.Iio j := + Basis.repr_support_subset_of_mem_span b (Set.Iio j) this + exact (Finsupp.mem_supported' _ _).1 ((Finsupp.mem_supported ℝ _).2 this) j Set.notMem_Iio_self-/ + +/-- `gramSchmidt` produces linearly independent vectors when given linearly independent vectors. -/ +theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x)) : + LinearIndependent ℝ (gramSchmidt s · x) := + linearIndependent_of_ne_zero_of_inner_eq_zero (fun _ ↦ gramSchmidt_ne_zero _ _ h₀) + (fun _ _ h ↦ gramSchmidt_orthogonal s h x) + +end VectorBundle From 568254edd5a9f24304d3c3194fe459a6af332f00 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 18:13:39 +0200 Subject: [PATCH 185/601] State desired smoothness result for Gram-Schmidt And sketch the strategy of proof --- .../VectorBundle/GramSchmidtOrtho.lean | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 896353fcfbe83a..2d67f6bc56d054 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -5,6 +5,7 @@ Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +import Mathlib.Geometry.Manifold.Elaborators /-! # Gram-Schmidt orthonormalisation on sections of Riemannian vector bundles @@ -260,3 +261,33 @@ theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x) (fun _ _ h ↦ gramSchmidt_orthogonal s h x) end VectorBundle + +-- When given a local frame, this produces an orthonormal local frame... +-- nothing new to prove; will prove in the frames file + +-- Continuity and smoothness. + +-- gramSchmidt followed by trivialisation commutes + +variable {n : WithTop ℕ∞} + +lemma gramSchmidt_contMDiffWithinAt (s : ι → (x : B) → E x) (i : ι) {u : Set B} (x : B) + (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) : + CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by + simp_rw [VectorBundle.gramSchmidt_def] + -- in principle, the proof is not bad: difference, finite sums of smooth sections are smooth + -- challenge 1: do this using (well-founded) induction + -- challenge 2: my definition is point-wise, need to relate to something in a trivialisation + sorry + +lemma gramSchmidt_contMDiffAt (s : ι → (x : B) → E x) (i : ι) (x : B) + (hs : ∀ i, CMDiffAt n (T% (s i)) x) : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := + contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt _ _ _ fun i ↦ hs i + +lemma gramSchmidt_contMDiffOn (s : ι → (x : B) → E x) (i : ι) (u : Set B) + (hs : ∀ i, CMDiff[u] n (T% (s i))) : CMDiff[u] n (T% (VectorBundle.gramSchmidt s i)) := + fun x hx ↦ gramSchmidt_contMDiffWithinAt _ _ _ fun i ↦ hs i x hx + +lemma gramSchmidt_contMDiff (s : ι → (x : B) → E x) (i : ι) + (hs : ∀ i, CMDiff n (T% (s i))) : CMDiff n (T% (VectorBundle.gramSchmidt s i)) := + fun x ↦ gramSchmidt_contMDiffAt _ _ _ (fun i ↦ hs i x) From f8125cfb8ae076eae3f7a37c2cfaf6030fc25ffb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 18:46:54 +0200 Subject: [PATCH 186/601] chore: small clean-up --- .../VectorBundle/CovariantDerivative.lean | 24 +++---------------- .../Manifold/VectorBundle/LeviCivita.lean | 4 +--- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ae4c073ae73978..64b8530e209007 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -240,9 +240,8 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] lemma _root_.IsCovariantDerivativeOn.zeroσ (hf : IsCovariantDerivativeOn F V f s) (X : Π x : M, TangentSpace I x) {x} (hx : x ∈ s := by trivial) : f X 0 x = 0 := by - have : MDiffAt (T% fun x ↦ (0 : V x)) x := by -- TODO: fix using upcoming mdiff lemma - exact (contMDiff_zeroSection 𝕜 V).mdifferentiableAt le_rfl - simpa using (hf.addσ X this this : f X (0+0) x = _) + simpa using (hf.addσ X (mdifferentiableAt_zeroSection ..) + (mdifferentiableAt_zeroSection ..) : f X (0+0) x = _) omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @@ -252,23 +251,6 @@ lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) ext x apply cov.isCovariantDerivativeOn.zeroσ -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -/-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ -lemma _root_.IsCovariantDerivativeOn.congr_σ (_hf : IsCovariantDerivativeOn F V f s) - (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) (x : M) : - f X σ x = f X σ' x := by - simp [funext hσ] - - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -/-- If `σ` and `σ'` are equal sections of `E`, they have equal covariant derivatives. -/ -lemma congr_σ (cov : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} (hσ : ∀ x, σ x = σ' x) (x : M) : - cov X σ x = cov X σ' x := - cov.isCovariantDerivativeOn.congr_σ X hσ x - omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in lemma _root_.IsCovariantDerivativeOn.sum_X (hf : IsCovariantDerivativeOn F V f s) @@ -603,7 +585,7 @@ lemma congr_σ_of_eventuallyEq -- Then, it's a chain of (dependent) equalities. calc cov X σ x _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ hσ] - _ = cov X ((ψ : M → ℝ) • σ') x := cov.congr_σ _ _ (by simp [this]) + _ = cov X ((ψ : M → ℝ) • σ') x := sorry -- use simp [funext hσ] and (by simp [this]) _ = cov X σ' x := by simp [cov.congr_σ_smoothBumpFunction, mdifferentiableAt_dependent_congr hs hσ hσσ'] -/ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 1dc05aaedcc275..50eac9eff51868 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -139,12 +139,10 @@ noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( variable (X Y Z) in lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by - have : ⟪Y, cov X Z - cov Z X⟫ = ⟪Y, VectorField.mlieBracket I X Z⟫ := by - simp [isTorsionFree_iff.mp h.2 X Z] trans ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ · ext x exact h.1 X Y Z x - · simp [← this, product_sub_right] + · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] -- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? variable (X Y Z) in From 9d8eb62b4181e5c16aae0ad345bd49273ba9c391 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 19:53:33 +0200 Subject: [PATCH 187/601] Uniqueness computation for Levi-Civita connection basically done --- .../Manifold/VectorBundle/LeviCivita.lean | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 50eac9eff51868..7bc8279d5e15e8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -78,7 +78,11 @@ variable (X Y Y') in lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] --- product_neg_left,right +variable (X Y) in +@[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] + +variable (X Y) in +@[simp] lemma product_neg_right : ⟪X, -Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] variable (X X' Y) in lemma product_sub_left : ⟪X - X', Y⟫ = ⟪X, Y⟫ - ⟪X', Y⟫ := by @@ -129,8 +133,8 @@ variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If ∇ is a Levi-Civita connection on `TM`, then `⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ -noncomputable def leviCivita_rhs : M → ℝ := 1 / 2 * ( - rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y +noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • ( + rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y - ⟪Y ,(VectorField.mlieBracket I X Z)⟫ - ⟪Z, (VectorField.mlieBracket I X Y)⟫ + ⟪X, (VectorField.mlieBracket I Z Y)⟫ @@ -144,23 +148,42 @@ lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = exact h.1 X Y Z x · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] --- XXX: are there useful intermediate lemmas to deduce just for metric or torsion-free connections? +lemma isolate_aux {α : Type*} [AddCommGroup α] + (X Y Z A D E F : α) (h : X + Y - Z = 2 * A + D + E - F) : + 2 * A = X + Y - Z - D - E + F := by + trans (X + Y - Z) - D - E + F + · rw [h]; abel + · abel + variable (X Y Z) in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by - have eq1 := aux I X Y Z cov h - have eq2 := aux I Y Z X cov h - have eq3 := aux I Z X Y cov h - have : rhs_aux I X Y Z + rhs_aux I Y Z X + rhs_aux I Z X Y = - 2 * ⟪cov X Y, Z⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ - + ⟪Z, VectorField.mlieBracket I X Y⟫ - ⟪X, VectorField.mlieBracket I Z Y⟫ := by + set A := ⟪cov X Y, Z⟫ + set B := ⟪cov Z X, Y⟫ + set C := ⟪cov Y Z, X⟫ + set D := ⟪Y, VectorField.mlieBracket I X Z⟫ with D_eq + set E := ⟪Z, VectorField.mlieBracket I Y X⟫ with E_eq + set F := ⟪X, VectorField.mlieBracket I Z Y⟫ with F_eq + have eq1 : rhs_aux I X Y Z = A + B + D := by + simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (cov Z X)] + have eq2 : rhs_aux I Y Z X = C + A + E := by + simp only [aux I Y Z X cov h, A, C, E, product_swap _ (cov X Y) Z] + have eq3 : rhs_aux I Z X Y = B + C + F := by + simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] + -- add (I) and (II), subtract (III) + have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = 2 * A + D + E - F := by rw [eq1, eq2, eq3] - sorry -- should be obvious now - -- add (I) + (II) and subtract (III) + abel_nf + grind [zsmul_eq_mul, Int.cast_ofNat, Int.reduceNeg, neg_smul, one_smul] + -- solve for ⟪cov X Y, Z⟫ and obtain the claim - sorry + simp only [leviCivita_rhs] -- - D - E + F + ext x + have almost := isolate_aux (X := rhs_aux I X Y Z) (Y := rhs_aux I Y Z X) (Z := rhs_aux I Z X Y) + (A := A) (D := D) (E := E) (F := F) (h := by simp [this]; sorry) + sorry -- obvious: if 2 • A = stuff, A = 1/2 stuff variable (X Y Z Z') in lemma rhs_aux_addZ : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by From e0ec07e609597974731260e893d6fa233f92abef Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 20:40:24 +0200 Subject: [PATCH 188/601] More progress: enough for tonight --- .../Manifold/VectorBundle/LeviCivita.lean | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 7bc8279d5e15e8..1d49d0dbddbbb2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -186,26 +186,28 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : sorry -- obvious: if 2 • A = stuff, A = 1/2 stuff variable (X Y Z Z') in -lemma rhs_aux_addZ : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by - have : ⟪Y, Z + Z'⟫ = ⟪Y, Z⟫ + ⟪Y, Z'⟫ := sorry +lemma rhs_aux_addZ (hY : MDiff Y) (hZ : MDiff Z) (hZ' : MDiff Z') : + rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by + have hZ : MDiff ⟪Y, Z⟫ := sorry -- use C^n metric and hY, hZ and hZ' + have hZ' : MDiff ⟪Y, Z'⟫ := sorry unfold rhs_aux ext x - -- have aux := mfderiv_congr this - --simp_rw [this] - --simp only [rhs_aux] - dsimp - -- prove: product is smooth enough, so we can apply mfderiv_add (and product_add_right)... - -- rw [← mfderiv_add] - -- simp_rw [product_add_right] - sorry + rw [product_add_right, mfderiv_add (hZ x) (hZ' x)]; simp; congr variable (X X' Y Z) in lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by - sorry -- hopefully similar to rhs_aux_addZ + ext x + simp [rhs_aux] variable (X Y Y' Z) in -lemma rhs_aux_addY : rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by - sorry -- hopefully similar to rhs_aux_addZ +lemma rhs_aux_addY (hY : MDiff Y) (hY' : MDiff Y') (hZ : MDiff Z) : + rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by + ext x + simp only [rhs_aux] + have hY : MDiff ⟪Y, Z⟫ := sorry -- use C^n metric and hY, hY' and hZ + have hY' : MDiff ⟪Y', Z⟫ := sorry + rw [product_add_left, mfderiv_add (hY x) (hY' x)] + simp; congr variable (X Y Z) in lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by @@ -228,8 +230,8 @@ lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] -- A bit too painful, and have missing differentiability assumptions. simp only [leviCivita_rhs] set A : M → ℝ := (1 : M → ℝ) / 2 - rw [← left_distrib] - apply congrArg + --rw [← left_distrib] + --apply congrArg ext x have h1 : VectorField.mlieBracket I X (Z + Z') = VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := by @@ -239,7 +241,7 @@ lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z' Y := by ext x simp [VectorField.mlieBracket_add_left (W := Y) (hZ x) (hZ' x)] - simp [h1, h2, rhs_aux_addX, rhs_aux_addY, rhs_aux_addZ] + simp [h1, h2, rhs_aux_addX] -- rhs_aux_addY, rhs_aux_addZ sorry -- module lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} From 11a743f0faf46a90374b8ad09a41dd4277fdd492 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 20:49:05 +0200 Subject: [PATCH 189/601] Fix the build and a few warnings (except for a really strange error) --- .../Manifold/VectorBundle/LeviCivita.lean | 8 +++++--- .../VectorBundle/OrthonormalFrame.lean | 18 +++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 1d49d0dbddbbb2..316a6418cdc480 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -31,7 +31,6 @@ variable {n : WithTop ℕ∞} {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I ∞ M] [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] - [IsContMDiffRiemannianBundle I ∞ E (fun (x : M) ↦ TangentSpace I x)] -- comes in a future PR by sgouezel; don't need this part yet -- [IsRiemannianManifold I M] @@ -185,6 +184,8 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : (A := A) (D := D) (E := E) (F := F) (h := by simp [this]; sorry) sorry -- obvious: if 2 • A = stuff, A = 1/2 stuff +variable [IsContMDiffRiemannianBundle I ∞ E (fun (x : M) ↦ TangentSpace I x)] + variable (X Y Z Z') in lemma rhs_aux_addZ (hY : MDiff Y) (hZ : MDiff Z) (hZ' : MDiff Z') : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by @@ -194,6 +195,7 @@ lemma rhs_aux_addZ (hY : MDiff Y) (hZ : MDiff Z) (hZ' : MDiff Z') : ext x rw [product_add_right, mfderiv_add (hZ x) (hZ' x)]; simp; congr +omit [IsManifold I ∞ M] in variable (X X' Y Z) in lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by ext x @@ -250,7 +252,7 @@ lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tang simp only [leviCivita_rhs] simp [rhs_aux_smulX, rhs_aux_smulY, rhs_aux_smulZ] ext x - simp only [Pi.mul_apply, Pi.inv_apply, Pi.ofNat_apply, Pi.add_apply, Pi.sub_apply] + simp only [Pi.mul_apply, /-Pi.inv_apply, Pi.ofNat_apply,-/ Pi.add_apply /-, Pi.sub_apply-/] -- Only kind of true: get extra mfderiv's, which will cancel in the end... have h1 : VectorField.mlieBracket I X (f • Z) = f • VectorField.mlieBracket I X Z := by @@ -262,7 +264,7 @@ lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tang rw [VectorField.mlieBracket_smul_left (hf x) (hZ x)]; simp; sorry simp [h1, h2] rw [product_smul_left, product_smul_right] - simp; abel_nf + simp only [Pi.smul_apply', smul_eq_mul]; abel_nf sorry -- easy computation variable {I} in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index b879ff6c01b9d0..3d0d92e90dc5e2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -47,14 +47,14 @@ variable (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E (b : Basis ι ℝ F) {x : B} (hx : x ∈ e.baseSet) namespace Basis --- TODO: do Gram-Schmidt in R bundles first! +-- TODO: revisit this using GramSchmidtOrtho.lean! -noncomputable def orthonormalFrame_toBasis_at - : Basis ι ℝ (E x) := - sorry -- b.map (e.linearEquivAt (R := 𝕜) x hx).symm +-- noncomputable def orthonormalFrame_toBasis_at : Basis ι ℝ (E x) := +-- sorry -- b.map (e.linearEquivAt (R := 𝕜) x hx).symm -open scoped Classical in --- If x is outside of `e.baseSet`, this returns the junk value 0. -noncomputable def orthonormalFrame : ι → (x : B) → E x := fun i x ↦ - -- idea: take the vector b i and apply the trivialisation e to it. - b.localFrame e x--if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 +-- open scoped Classical in +-- -- If x is outside of `e.baseSet`, this returns the junk value 0. +-- noncomputable def orthonormalFrame : ι → (x : B) → E x := fun i x ↦ +-- -- idea: take the vector b i and apply the trivialisation e to it. +-- b.localFrame e x--if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 +end Basis From 459114da7d1d90dc74b1b6023ddde84d41bccfc0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 8 Jul 2025 21:52:01 +0200 Subject: [PATCH 190/601] Fix the build: we need a better error message, please! --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 316a6418cdc480..e0760ff0c7d30f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -187,7 +187,7 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : variable [IsContMDiffRiemannianBundle I ∞ E (fun (x : M) ↦ TangentSpace I x)] variable (X Y Z Z') in -lemma rhs_aux_addZ (hY : MDiff Y) (hZ : MDiff Z) (hZ' : MDiff Z') : +lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by have hZ : MDiff ⟪Y, Z⟫ := sorry -- use C^n metric and hY, hZ and hZ' have hZ' : MDiff ⟪Y, Z'⟫ := sorry @@ -202,7 +202,7 @@ lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z simp [rhs_aux] variable (X Y Y' Z) in -lemma rhs_aux_addY (hY : MDiff Y) (hY' : MDiff Y') (hZ : MDiff Z) : +lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by ext x simp only [rhs_aux] From 1bebb986d9abdabfd30ff490ffd0aeff5b5ff970 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 9 Jul 2025 00:05:31 +0200 Subject: [PATCH 191/601] Remove remaining test in manifold elaborators file --- Mathlib/Geometry/Manifold/Elaborators.lean | 39 ---------------------- 1 file changed, 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index dd200c080719da..735be6cdf81696 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -15,31 +15,10 @@ TODO: add a more complete doc-string -/ -open Bundle Filter Function Topology - open scoped Bundle Manifold ContDiff -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section - -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - - -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -- `F` model fiber - (n : WithTop ℕ∞) - (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul 𝕜 (V x)] - [FiberBundle F V] [VectorBundle 𝕜 F V] - -- `V` vector bundle - open Lean Meta Elab Tactic open Mathlib.Tactic @@ -351,22 +330,4 @@ elab:max "ContMDiffAt%" nt:term:arg t:term:arg : term => do return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." -variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] - -variable {EM' : Type*} [NormedAddCommGroup EM'] - [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - (f : M → M') (m : M) - --- Other tests in MathlibTest/DifferentialGeomtry/Elaborators. - -/-- info: ContMDiff I (I.prod 𝓘(𝕜, E)) 1 fun m ↦ TotalSpace.mk' E m (X m) : Prop -/ -#guard_msgs in -#check ContMDiff% 1 (T% X) - -/-- info: ContMDiffAt I (I.prod 𝓘(𝕜, E)) 1 (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ -#guard_msgs in -#check ContMDiffAt% 1 (T% X) m - end From bc8127b1dcd42d3a7340b726b812b5add4b3ac10 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 09:32:56 +0200 Subject: [PATCH 192/601] Close some sorries in LeviCivita; two statements are wrong --- .../Manifold/VectorBundle/LeviCivita.lean | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index e0760ff0c7d30f..9beb029d0ae944 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -186,14 +186,17 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : variable [IsContMDiffRiemannianBundle I ∞ E (fun (x : M) ↦ TangentSpace I x)] +-- TODO: should be MDifferentiable.inner_bundle, but fails with an instance synthesis error +-- I do not understand. +variable {I} in +lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := sorry + variable (X Y Z Z') in lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by - have hZ : MDiff ⟪Y, Z⟫ := sorry -- use C^n metric and hY, hZ and hZ' - have hZ' : MDiff ⟪Y, Z'⟫ := sorry unfold rhs_aux ext x - rw [product_add_right, mfderiv_add (hZ x) (hZ' x)]; simp; congr + rw [product_add_right, mfderiv_add ((foo hY hZ) x) ((foo hY hZ') x)]; simp; congr omit [IsManifold I ∞ M] in variable (X X' Y Z) in @@ -206,24 +209,30 @@ lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by ext x simp only [rhs_aux] - have hY : MDiff ⟪Y, Z⟫ := sorry -- use C^n metric and hY, hY' and hZ - have hY' : MDiff ⟪Y', Z⟫ := sorry - rw [product_add_left, mfderiv_add (hY x) (hY' x)] + rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] simp; congr variable (X Y Z) in lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by ext x simp only [rhs_aux] + rw [product_smul_right] + -- XXX: not true, the product rule gives us two terms + -- and there is missing API in mathlib! -- only holds given enough smoothness! sorry variable (X Y Z) in lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by - sorry + ext x + simp [rhs_aux] variable (X Y Z Z') in lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by + ext x + simp [rhs_aux] + rw [product_smul_left] + -- TODO: get a second term from the product rule! sorry lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] @@ -327,7 +336,7 @@ noncomputable def existence_candidate [FiniteDimensional ℝ E] : variable (X Y) in -- The above definition behaves well: for each compatible trivialisation e, -- using e on e.baseSet yields the same result as above. -lemma foo [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) +lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) : existence_candidate I M X Y x = existence_candidate_aux I X Y e x := sorry @@ -352,6 +361,6 @@ def LeviCivitaConnection : CovariantDerivative I E (TangentSpace I : M → Type -- IsCovariantDerivativeOn sorry -lemma bar : (LeviCivitaConnection I M).IsLeviCivitaConnection := sorry +lemma baz : (LeviCivitaConnection I M).IsLeviCivitaConnection := sorry end CovariantDerivative From f7ae55906f9c7c8dad92d5a967b5dcf8db5d9ebe Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 09:53:59 +0200 Subject: [PATCH 193/601] feat: add mdifferentiable version of hom bundle smoothness lemmas These are necessary to prove that the pairing of bundle sections induced by a smooth Riemannian metric preserves differentiability. From the path towards geodesics and the Levi-Civita connection. --- .../Geometry/Manifold/VectorBundle/Hom.lean | 163 +++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index 0fefa9d2415e4f..e9698a6e05662d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -5,6 +5,7 @@ Authors: Floris van Doorn -/ import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Topology.VectorBundle.Hom +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! # Homs of `C^n` vector bundles over the same base space @@ -42,6 +43,8 @@ variable {𝕜 B F₁ F₂ M : Type*} {n : WithTop ℕ∞} local notation "LE₁E₂" => TotalSpace (F₁ →L[𝕜] F₂) (fun (b : B) ↦ E₁ b →L[𝕜] E₂ b) +section + -- Porting note (https://github.com/leanprover-community/mathlib4/issues/11083): -- moved slow parts to separate lemmas theorem contMDiffOn_continuousLinearMapCoordChange @@ -78,7 +81,41 @@ theorem contMDiffAt_hom_bundle (f : M → LE₁E₂) {x₀ : M} : (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) x₀ := contMDiffAt_totalSpace -variable [ContMDiffVectorBundle n F₁ E₁ IB] [ContMDiffVectorBundle n F₂ E₂ IB] +end + +section + +theorem mdifferentiableOn_continuousLinearMapCoordChange + [ContMDiffVectorBundle 1 F₁ E₁ IB] [ContMDiffVectorBundle 1 F₂ E₂ IB] + [MemTrivializationAtlas e₁] [MemTrivializationAtlas e₁'] + [MemTrivializationAtlas e₂] [MemTrivializationAtlas e₂'] : + MDifferentiableOn IB 𝓘(𝕜, (F₁ →L[𝕜] F₂) →L[𝕜] F₁ →L[𝕜] F₂) + (continuousLinearMapCoordChange (RingHom.id 𝕜) e₁ e₁' e₂ e₂') + (e₁.baseSet ∩ e₂.baseSet ∩ (e₁'.baseSet ∩ e₂'.baseSet)) := by + have h₁ := contMDiffOn_coordChangeL (IB := IB) e₁' e₁ (n := 1) |>.mdifferentiableOn le_rfl + have h₂ := contMDiffOn_coordChangeL (IB := IB) e₂ e₂' (n := 1) |>.mdifferentiableOn le_rfl + refine (h₁.mono ?_).cle_arrowCongr (h₂.mono ?_) <;> mfld_set_tac + +variable [∀ x, IsTopologicalAddGroup (E₂ x)] [∀ x, ContinuousSMul 𝕜 (E₂ x)] + +theorem mdifferentiableWithinAt_hom_bundle (f : M → LE₁E₂) {s : Set M} {x₀ : M} : + MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) f s x₀ ↔ + MDifferentiableWithinAt IM IB (fun x ↦ (f x).1) s x₀ ∧ + MDifferentiableWithinAt IM 𝓘(𝕜, F₁ →L[𝕜] F₂) + (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) s x₀ := + mdifferentiableWithinAt_totalSpace IB .. + +theorem mdifferentiableAt_hom_bundle (f : M → LE₁E₂) {x₀ : M} : + MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) f x₀ ↔ + MDifferentiableAt IM IB (fun x ↦ (f x).1) x₀ ∧ + MDifferentiableAt IM 𝓘(𝕜, F₁ →L[𝕜] F₂) + (fun x ↦ inCoordinates F₁ E₁ F₂ E₂ (f x₀).1 (f x).1 (f x₀).1 (f x).1 (f x).2) x₀ := + mdifferentiableAt_totalSpace .. + +end + +variable [∀ x, IsTopologicalAddGroup (E₂ x)] [∀ x, ContinuousSMul 𝕜 (E₂ x)] + [ContMDiffVectorBundle n F₁ E₁ IB] [ContMDiffVectorBundle n F₂ E₂ IB] instance Bundle.ContinuousLinearMap.vectorPrebundle.isContMDiff : (Bundle.ContinuousLinearMap.vectorPrebundle (RingHom.id 𝕜) F₁ E₁ F₂ E₂).IsContMDiff IB n where @@ -276,6 +313,63 @@ lemma ContMDiff.clm_bundle_apply end OneVariable +section OneVariable' + +variable [∀ x, IsTopologicalAddGroup (E₂ x)] [∀ x, ContinuousSMul 𝕜 (E₂ x)] + {ϕ : ∀ x, (E₁ (b x) →L[𝕜] E₂ (b x))} + +/-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and +linear maps `ϕ m : E₁ (b m) → E₂ (b m)` depending smoothly on `m`. +One can apply `ϕ m` to `v m`, and the resulting map is differentiable. + +We give here a version of this statement within a set at a point. -/ +lemma MDifferentiableWithinAt.clm_bundle_apply + (hϕ : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) + s x) + (hv : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁)) + (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s x) : + MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₂)) + (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) s x := by + simp only [mdifferentiableWithinAt_hom_bundle] at hϕ + exact hϕ.2.clm_apply_of_inCoordinates hv hϕ.1 + +/-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and +linear maps `ϕ m : E₁ (b m) → E₂ (b m)` depending smoothly on `m`. +One can apply `ϕ m` to `v m`, and the resulting map is differentiable. + +We give here a version of this statement at a point. -/ +lemma MDifferentiableAt.clm_bundle_apply + (hϕ : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) x) + (hv : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) : + MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) x := + MDifferentiableWithinAt.clm_bundle_apply hϕ hv + +/-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and +linear maps `ϕ m : E₁ (b m) → E₂ (b m)` depending smoothly on `m`. +One can apply `ϕ m` to `v m`, and the resulting map is differentiable. + +We give here a version of this statement on a set. -/ +lemma MDifferentiableOn.clm_bundle_apply + (hϕ : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m)) s) + (hv : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s) : + MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) s := + fun x hx ↦ (hϕ x hx).clm_bundle_apply (hv x hx) + +/-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a base map `b : M → B`, and +linear maps `ϕ m : E₁ (b m) → E₂ (b m)` depending smoothly on `m`. +One can apply `ϕ m` to `v m`, and the resulting map is differentiable. -/ +lemma MDifferentiable.clm_bundle_apply + (hϕ : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂) (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x)) (b m) (ϕ m))) + (hv : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) : + MDifferentiable IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := + fun x ↦ (hϕ x).clm_bundle_apply (hv x) + +end OneVariable' + section TwoVariables variable [∀ x, IsTopologicalAddGroup (E₃ x)] [∀ x, ContinuousSMul 𝕜 (E₃ x)] @@ -341,4 +435,71 @@ lemma ContMDiff.clm_bundle_apply₂ end TwoVariables +section TwoVariables' + +variable [∀ x, IsTopologicalAddGroup (E₃ x)] [∀ x, ContinuousSMul 𝕜 (E₃ x)] + {ψ : ∀ x, (E₁ (b x) →L[𝕜] E₂ (b x) →L[𝕜] E₃ (b x))} {w : ∀ x, E₂ (b x)} + +/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +`b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. +One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. + +We give here a version of this statement within a set at a point. -/ +lemma MDifferentiableWithinAt.clm_bundle_apply₂ + (hψ : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) s x) + (hv : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₁)) + (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s x) + (hw : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₂)) + (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) s x) : + MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F₃)) + (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) s x := + hψ.clm_bundle_apply hv |>.clm_bundle_apply hw + +/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +`b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. +One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. + +We give here a version of this statement at a point. -/ +lemma MDifferentiableAt.clm_bundle_apply₂ + (hψ : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) x) + (hv : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) x) + (hw : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) x) : + MDifferentiableAt IM (IB.prod 𝓘(𝕜, F₃)) + (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) x := + MDifferentiableWithinAt.clm_bundle_apply₂ hψ hv hw + +/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +`b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. +One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. + +We give here a version of this statement on a set. -/ +lemma MDifferentiableOn.clm_bundle_apply₂ + (hψ : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m)) s) + (hv : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m)) s) + (hw : MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (w m)) s) : + MDifferentiableOn IM (IB.prod 𝓘(𝕜, F₃)) + (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) s := + fun x hx ↦ (hψ x hx).clm_bundle_apply₂ (hv x hx) (hw x hx) + +/-- Consider differentiable maps `v : M → E₁` and `v : M → E₂` to vector bundles, over a base map +`b : M → B`, and bilinear maps `ψ m : E₁ (b m) → E₂ (b m) → E₃ (b m)` depending smoothly on `m`. +One can apply `ψ m` to `v m` and `w m`, and the resulting map is differentiable. -/ +lemma MDifferentiable.clm_bundle_apply₂ + (hψ : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂ →L[𝕜] F₃)) + (fun m ↦ TotalSpace.mk' (F₁ →L[𝕜] F₂ →L[𝕜] F₃) + (E := fun (x : B) ↦ (E₁ x →L[𝕜] E₂ x →L[𝕜] E₃ x)) (b m) (ψ m))) + (hv : MDifferentiable IM (IB.prod 𝓘(𝕜, F₁)) (fun m ↦ TotalSpace.mk' F₁ (b m) (v m))) + (hw : MDifferentiable IM (IB.prod 𝓘(𝕜, F₂)) (fun m ↦ TotalSpace.mk' F₂ (b m) (w m))) : + MDifferentiable IM (IB.prod 𝓘(𝕜, F₃)) + (fun m ↦ TotalSpace.mk' F₃ (b m) (ψ m (v m) (w m))) := + fun x ↦ (hψ x).clm_bundle_apply₂ (hv x) (hw x) + +end TwoVariables' + end From b2658433123f12c54db1439ce9699704d296fb85 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 00:15:08 +0200 Subject: [PATCH 194/601] feat: add mdifferentiable analogues of C^n metric lemmas --- .../Manifold/VectorBundle/Riemannian.lean | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean b/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean index b80c6d0a0eea24..f5c2ce1f7f1e27 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Riemannian.lean @@ -155,6 +155,61 @@ lemma ContMDiff.inner_bundle end ContMDiff +section MDifferentiable + +variable + {EM : Type*} [NormedAddCommGroup EM] [NormedSpace ℝ EM] + {HM : Type*} [TopologicalSpace HM] {IM : ModelWithCorners ℝ EM HM} + {M : Type*} [TopologicalSpace M] [ChartedSpace HM M] + [h : IsContMDiffRiemannianBundle IB 1 F E] + {b : M → B} {v w : ∀ x, E (b x)} {s : Set M} {x : M} + +/-- Given two differentiable maps into the same fibers of a Riemannian bundle, +their scalar product is differentiable. -/ +lemma MDifferentiableWithinAt.inner_bundle + (hv : MDifferentiableWithinAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E)) s x) + (hw : MDifferentiableWithinAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E)) s x) : + MDifferentiableWithinAt IM 𝓘(ℝ) (fun m ↦ ⟪v m, w m⟫) s x := by + rcases h.exists_contMDiff with ⟨g, g_smooth, hg⟩ + have hb : MDifferentiableWithinAt IM IB b s x := by + simp only [mdifferentiableWithinAt_totalSpace] at hv + exact hv.1 + simp only [hg] + have : MDifferentiableWithinAt IM (IB.prod 𝓘(ℝ)) + (fun m ↦ TotalSpace.mk' ℝ (E := Bundle.Trivial B ℝ) (b m) (g (b m) (v m) (w m))) s x := by + apply MDifferentiableWithinAt.clm_bundle_apply₂ (F₁ := F) (F₂ := F) + · exact MDifferentiableAt.comp_mdifferentiableWithinAt x (g_smooth.mdifferentiableAt le_rfl) hb + · exact hv + · exact hw + simp only [mdifferentiableWithinAt_totalSpace] at this + exact this.2 + +/-- Given two smooth maps into the same fibers of a Riemannian bundle, +their scalar product is smooth. -/ +lemma MDifferentiableAt.inner_bundle + (hv : MDifferentiableAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E)) x) + (hw : MDifferentiableAt IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E)) x) : + MDifferentiableAt IM 𝓘(ℝ) (fun b ↦ ⟪v b, w b⟫) x := + MDifferentiableWithinAt.inner_bundle hv hw + +/-- Given two smooth maps into the same fibers of a Riemannian bundle, +their scalar product is smooth. -/ +lemma MDifferentiableOn.inner_bundle + (hv : MDifferentiableOn IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E)) s) + (hw : MDifferentiableOn IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E)) s) : + MDifferentiableOn IM 𝓘(ℝ) (fun b ↦ ⟪v b, w b⟫) s := + fun x hx ↦ (hv x hx).inner_bundle (hw x hx) + +/-- Given two smooth maps into the same fibers of a Riemannian bundle, +their scalar product is smooth. -/ +lemma MDifferentiable.inner_bundle + (hv : MDifferentiable IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (v m : TotalSpace F E))) + (hw : MDifferentiable IM (IB.prod 𝓘(ℝ, F)) (fun m ↦ (w m : TotalSpace F E))) : + MDifferentiable IM 𝓘(ℝ) (fun b ↦ ⟪v b, w b⟫) := + fun x ↦ (hv x).inner_bundle (hw x) + +end MDifferentiable + end namespace Bundle From 5193ef142bd659accb4c2dd691ad6be8ff765bf1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 10:20:10 +0200 Subject: [PATCH 195/601] Fix sorry, but there is a usability cliff! --- .../Manifold/VectorBundle/LeviCivita.lean | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 9beb029d0ae944..15c51a33d7fc8c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -184,12 +184,18 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : (A := A) (D := D) (E := E) (F := F) (h := by simp [this]; sorry) sorry -- obvious: if 2 • A = stuff, A = 1/2 stuff -variable [IsContMDiffRiemannianBundle I ∞ E (fun (x : M) ↦ TangentSpace I x)] - --- TODO: should be MDifferentiable.inner_bundle, but fails with an instance synthesis error --- I do not understand. +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] + +/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` +yields an error +synthesized type class instance is not definitionally equal to expression inferred by typing rules, +synthesized + fun x ↦ instNormedAddCommGroupOfRiemannianBundle x +inferred + fun b ↦ inst✝⁷ -/ variable {I} in -lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := sorry +lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := + MDifferentiable.inner_bundle hY hZ variable (X Y Z Z') in lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : From de072a7319915c34c0aaaebe1b6b1b808593a090 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 11:26:17 +0200 Subject: [PATCH 196/601] Further along smoothness for Gram-Schmidt --- .../VectorBundle/GramSchmidtOrtho.lean | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 2d67f6bc56d054..24bea0f62fad5d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -5,6 +5,7 @@ Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.Elaborators /-! @@ -267,18 +268,30 @@ end VectorBundle -- Continuity and smoothness. --- gramSchmidt followed by trivialisation commutes - variable {n : WithTop ℕ∞} +-- TODO: fix pretty-printing of my new elaborators! +set_option linter.style.commandStart false + +def foo {s t : (x : B) → E x} {u : Set B} (x : B) + (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) : + -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! + letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).orthogonalProjection (t x); + CMDiffAt[u] n (T% S) x := by + sorry + lemma gramSchmidt_contMDiffWithinAt (s : ι → (x : B) → E x) (i : ι) {u : Set B} (x : B) (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by simp_rw [VectorBundle.gramSchmidt_def] - -- in principle, the proof is not bad: difference, finite sums of smooth sections are smooth + have : ContMDiffWithinAt IB (IB.prod 𝓘(ℝ, F)) n (T% s i) u x := sorry + apply this.sub_section + apply ContMDiffWithinAt.sum_section + intro i' hi' + have hproj : CMDiffAt[u] n (T% VectorBundle.gramSchmidt s i') x := sorry + apply foo x hproj (hs i) + -- challenge 1: do this using (well-founded) induction - -- challenge 2: my definition is point-wise, need to relate to something in a trivialisation - sorry lemma gramSchmidt_contMDiffAt (s : ι → (x : B) → E x) (i : ι) (x : B) (hs : ∀ i, CMDiffAt n (T% (s i)) x) : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := From 680b3c9a1c15c89c06f87bad1b59a74999510da3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 11:28:23 +0200 Subject: [PATCH 197/601] Progress --- Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 24bea0f62fad5d..7af8436fb33df7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -284,11 +284,10 @@ lemma gramSchmidt_contMDiffWithinAt (s : ι → (x : B) → E x) (i : ι) {u : S (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by simp_rw [VectorBundle.gramSchmidt_def] - have : ContMDiffWithinAt IB (IB.prod 𝓘(ℝ, F)) n (T% s i) u x := sorry - apply this.sub_section + apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' - have hproj : CMDiffAt[u] n (T% VectorBundle.gramSchmidt s i') x := sorry + have hproj : CMDiffAt[u] n (T% VectorBundle.gramSchmidt s i') x := sorry -- use recursion! apply foo x hproj (hs i) -- challenge 1: do this using (well-founded) induction From b302f89be02f00a7af7626a76ccd63cb80fde140 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 12:51:09 +0200 Subject: [PATCH 198/601] Smoothness sorry done, just recursion remains! --- .../VectorBundle/GramSchmidtOrtho.lean | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 7af8436fb33df7..2445d73bc94493 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -273,14 +273,24 @@ variable {n : WithTop ℕ∞} -- TODO: fix pretty-printing of my new elaborators! set_option linter.style.commandStart false -def foo {s t : (x : B) → E x} {u : Set B} (x : B) - (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) : +variable [IsContMDiffRiemannianBundle IB n F E] + +def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} + (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).orthogonalProjection (t x); CMDiffAt[u] n (T% S) x := by - sorry - -lemma gramSchmidt_contMDiffWithinAt (s : ι → (x : B) → E x) (i : ι) {u : Set B} (x : B) + simp_rw [Submodule.orthogonalProjection_singleton] + apply ContMDiffWithinAt.smul_section ?_ hs + suffices ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (fun x ↦ ⟪s x, t x⟫ / ⟪s x, s x⟫) u x by + apply this.congr + · intro y hy + rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K] + · rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K] + exact (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) + +lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] + (s : ι → (x : B) → E x) (i : ι) {u : Set B} (x : B) (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by simp_rw [VectorBundle.gramSchmidt_def] @@ -288,9 +298,8 @@ lemma gramSchmidt_contMDiffWithinAt (s : ι → (x : B) → E x) (i : ι) {u : S apply ContMDiffWithinAt.sum_section intro i' hi' have hproj : CMDiffAt[u] n (T% VectorBundle.gramSchmidt s i') x := sorry -- use recursion! - apply foo x hproj (hs i) - - -- challenge 1: do this using (well-founded) induction + apply contMDiffWithinAt_myproj hproj (hs i) + sorry -- TODO: figure out the right preconditions! lemma gramSchmidt_contMDiffAt (s : ι → (x : B) → E x) (i : ι) (x : B) (hs : ∀ i, CMDiffAt n (T% (s i)) x) : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := From 56f4a9e2cb3120dcb267ef3cc007ca937112ff7b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 12:54:07 +0200 Subject: [PATCH 199/601] Recursion done --- .../Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 2445d73bc94493..fd32c53ecbe18d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -297,9 +297,11 @@ lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' - have hproj : CMDiffAt[u] n (T% VectorBundle.gramSchmidt s i') x := sorry -- use recursion! - apply contMDiffWithinAt_myproj hproj (hs i) + apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt s i' x hs) (hs i) sorry -- TODO: figure out the right preconditions! +termination_by i +decreasing_by + exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' lemma gramSchmidt_contMDiffAt (s : ι → (x : B) → E x) (i : ι) (x : B) (hs : ∀ i, CMDiffAt n (T% (s i)) x) : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := From 252565c075e89aae2f7a72fc7f91f99d8c3a4646 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 12:59:54 +0200 Subject: [PATCH 200/601] Almost done --- .../VectorBundle/GramSchmidtOrtho.lean | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index fd32c53ecbe18d..e10a8d8a82a523 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -291,26 +291,35 @@ def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] (s : ι → (x : B) → E x) (i : ι) {u : Set B} (x : B) - (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) : + (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) + (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by simp_rw [VectorBundle.gramSchmidt_def] apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' - apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt s i' x hs) (hs i) - sorry -- TODO: figure out the right preconditions! + have : LinearIndependent ℝ ((fun x_1 ↦ s x_1 x) ∘ @Subtype.val ι fun x ↦ x ∈ Set.Iic i') := by + sorry -- hs'.mono + apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt s i' x hs this) (hs i) + apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' lemma gramSchmidt_contMDiffAt (s : ι → (x : B) → E x) (i : ι) (x : B) - (hs : ∀ i, CMDiffAt n (T% (s i)) x) : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := - contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt _ _ _ fun i ↦ hs i + (hs : ∀ i, CMDiffAt n (T% (s i)) x) + (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) + : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := + contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt _ _ _ (fun i ↦ hs i) hs' lemma gramSchmidt_contMDiffOn (s : ι → (x : B) → E x) (i : ι) (u : Set B) - (hs : ∀ i, CMDiff[u] n (T% (s i))) : CMDiff[u] n (T% (VectorBundle.gramSchmidt s i)) := - fun x hx ↦ gramSchmidt_contMDiffWithinAt _ _ _ fun i ↦ hs i x hx + (hs : ∀ i, CMDiff[u] n (T% (s i))) + (hs' : ∀ x ∈ u, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : + CMDiff[u] n (T% (VectorBundle.gramSchmidt s i)) := + fun x hx ↦ gramSchmidt_contMDiffWithinAt _ _ _ (fun i ↦ hs i x hx) (hs' _ hx) lemma gramSchmidt_contMDiff (s : ι → (x : B) → E x) (i : ι) - (hs : ∀ i, CMDiff n (T% (s i))) : CMDiff n (T% (VectorBundle.gramSchmidt s i)) := - fun x ↦ gramSchmidt_contMDiffAt _ _ _ (fun i ↦ hs i x) + (hs : ∀ i, CMDiff n (T% (s i))) + (hs' : ∀ x, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : + CMDiff n (T% (VectorBundle.gramSchmidt s i)) := + fun x ↦ gramSchmidt_contMDiffAt _ _ _ (fun i ↦ hs i x) (hs' x) From c0f80df884005f259d59633bbfaac88ea47c2214 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 13:33:01 +0200 Subject: [PATCH 201/601] Closer --- .../Manifold/VectorBundle/GramSchmidtOrtho.lean | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index e10a8d8a82a523..f88cb8d9e3c121 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -298,8 +298,16 @@ lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' + have aux : { x // x ∈ Set.Iic i' } → { x // x ∈ Set.Iic i } := sorry + have : Function.Injective aux := sorry + have asdf := hs'.comp aux this have : LinearIndependent ℝ ((fun x_1 ↦ s x_1 x) ∘ @Subtype.val ι fun x ↦ x ∈ Set.Iic i') := by - sorry -- hs'.mono + convert asdf + ext ⟨x', hx'⟩ + -- ext x' + simp --only [Function.comp_apply] + congr + sorry apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt s i' x hs this) (hs i) apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i From 303b1d3eeffe9dda6788567be663ac7572df5000 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 13:46:17 +0200 Subject: [PATCH 202/601] Two missing sorries, are math-obvious --- .../Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index f88cb8d9e3c121..6d89108ca05b45 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -298,8 +298,11 @@ lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' - have aux : { x // x ∈ Set.Iic i' } → { x // x ∈ Set.Iic i } := sorry - have : Function.Injective aux := sorry + have aux : { x // x ∈ Set.Iic i' } → { x // x ∈ Set.Iic i } := + fun ⟨x, hx⟩ ↦ ⟨x, hx.trans (Finset.mem_Iio.mp hi').le⟩ + have : Function.Injective aux := by + intro ⟨x, hx⟩ ⟨x', hx'⟩ h + sorry -- unfold aux, obvious, right? have asdf := hs'.comp aux this have : LinearIndependent ℝ ((fun x_1 ↦ s x_1 x) ∘ @Subtype.val ι fun x ↦ x ∈ Set.Iic i') := by convert asdf @@ -307,7 +310,7 @@ lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] -- ext x' simp --only [Function.comp_apply] congr - sorry + sorry -- obvious by definition of aux apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt s i' x hs this) (hs i) apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i From 9ab0fb466c5fbb08aac31f9f1d20a2e9d925d04e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 14:18:37 +0200 Subject: [PATCH 203/601] Fix the issue, and reduce Morse code --- .../VectorBundle/GramSchmidtOrtho.lean | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 6d89108ca05b45..a892d1289bce5f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -289,8 +289,7 @@ def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} · rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K] exact (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) -lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] - (s : ι → (x : B) → E x) (i : ι) {u : Set B} (x : B) +lemma gramSchmidt_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : Set B} {x : B} (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by @@ -298,39 +297,32 @@ lemma gramSchmidt_contMDiffWithinAt [IsContMDiffRiemannianBundle IB n F E] apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' - have aux : { x // x ∈ Set.Iic i' } → { x // x ∈ Set.Iic i } := + let aux : { x // x ∈ Set.Iic i' } → { x // x ∈ Set.Iic i } := fun ⟨x, hx⟩ ↦ ⟨x, hx.trans (Finset.mem_Iio.mp hi').le⟩ - have : Function.Injective aux := by - intro ⟨x, hx⟩ ⟨x', hx'⟩ h - sorry -- unfold aux, obvious, right? - have asdf := hs'.comp aux this have : LinearIndependent ℝ ((fun x_1 ↦ s x_1 x) ∘ @Subtype.val ι fun x ↦ x ∈ Set.Iic i') := by - convert asdf - ext ⟨x', hx'⟩ - -- ext x' - simp --only [Function.comp_apply] - congr - sorry -- obvious by definition of aux - apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt s i' x hs this) (hs i) + apply hs'.comp aux + intro ⟨x, hx⟩ ⟨x', hx'⟩ h + simp_all only [Subtype.mk.injEq, aux] + apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt i' hs this) (hs i) apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' -lemma gramSchmidt_contMDiffAt (s : ι → (x : B) → E x) (i : ι) (x : B) +lemma gramSchmidt_contMDiffAt {s : ι → (x : B) → E x} (i : ι) {x : B} (hs : ∀ i, CMDiffAt n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := - contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt _ _ _ (fun i ↦ hs i) hs' + contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt _ (fun i ↦ hs i) hs' -lemma gramSchmidt_contMDiffOn (s : ι → (x : B) → E x) (i : ι) (u : Set B) +lemma gramSchmidt_contMDiffOn {s : ι → (x : B) → E x} (i : ι) (u : Set B) (hs : ∀ i, CMDiff[u] n (T% (s i))) (hs' : ∀ x ∈ u, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff[u] n (T% (VectorBundle.gramSchmidt s i)) := - fun x hx ↦ gramSchmidt_contMDiffWithinAt _ _ _ (fun i ↦ hs i x hx) (hs' _ hx) + fun x hx ↦ gramSchmidt_contMDiffWithinAt _ (fun i ↦ hs i x hx) (hs' _ hx) -lemma gramSchmidt_contMDiff (s : ι → (x : B) → E x) (i : ι) +lemma gramSchmidt_contMDiff {s : ι → (x : B) → E x} (i : ι) (hs : ∀ i, CMDiff n (T% (s i))) (hs' : ∀ x, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff n (T% (VectorBundle.gramSchmidt s i)) := - fun x ↦ gramSchmidt_contMDiffAt _ _ _ (fun i ↦ hs i x) (hs' x) + fun x ↦ gramSchmidt_contMDiffAt _ (fun i ↦ hs i x) (hs' x) From caedcfdba8f0c034f814e1de05b5f68f8628d090 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 14:38:08 +0200 Subject: [PATCH 204/601] Golf all proofs: re-define gramSchmidt to apply point-wise --- .../VectorBundle/GramSchmidtOrtho.lean | 107 ++++-------------- 1 file changed, 20 insertions(+), 87 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index a892d1289bce5f..9c6e90e425d8c1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -62,9 +62,7 @@ and outputs a set of sections which are point-wise orthogonal with the same span Basically, we apply the Gram-Schmidt algorithm point-wise. -/ noncomputable def gramSchmidt [WellFoundedLT ι] (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ - s n x - ∑ i : Finset.Iio n, (ℝ ∙ VectorBundle.gramSchmidt s i x).orthogonalProjection (s n x) -termination_by n -decreasing_by exact Finset.mem_Iio.1 i.2 + InnerProductSpace.gramSchmidt ℝ (s · x) n -- Let `s i` be a collection of sections in `E`, indexed by `ι`. variable {s : ι → (x : B) → E x} @@ -76,7 +74,7 @@ variable (s) in theorem gramSchmidt_def (n : ι) (x) : gramSchmidt s n x = s n x - ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).orthogonalProjection (s n x) := by - rw [← sum_attach, attach_eq_univ, gramSchmidt] + simp only [gramSchmidt, InnerProductSpace.gramSchmidt_def] variable (s) in theorem gramSchmidt_def' (n : ι) (x) : @@ -97,97 +95,47 @@ variable (s) in theorem gramSchmidt_zero {ι : Type*} [LinearOrder ι] [LocallyFiniteOrder ι] [OrderBot ι] [WellFoundedLT ι] (s : ι → (x : B) → E x) : gramSchmidt s ⊥ = s ⊥ := by ext x - rw [gramSchmidt_def, Iio_eq_Ico, Finset.Ico_self, Finset.sum_empty, sub_zero] + apply InnerProductSpace.gramSchmidt_zero variable (s) in /-- **Gram-Schmidt Orthogonalisation**: `gramSchmidt` produces an orthogonal system of vectors. -/ theorem gramSchmidt_orthogonal {a b : ι} (h₀ : a ≠ b) (x) : - ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := by - suffices ∀ a b : ι, a < b → ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 by - rcases h₀.lt_or_gt with ha | hb - · exact this _ _ ha - · rw [inner_eq_zero_symm] - exact this _ _ hb - clear h₀ a b - intro a b h₀ - revert a - apply wellFounded_lt.induction b - intro b ih a h₀ - simp only [gramSchmidt_def s b, inner_sub_right, inner_sum, orthogonalProjection_singleton, - inner_smul_right] - rw [Finset.sum_eq_single_of_mem a (Finset.mem_Iio.mpr h₀)] - · by_cases h : gramSchmidt s a x = 0 - · simp only [h, inner_zero_left, zero_div, zero_mul, sub_zero] - · rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K, div_mul_cancel₀, sub_self] - rwa [inner_self_ne_zero] - intro i hi hia - simp only [mul_eq_zero, div_eq_zero_iff] - right - rcases hia.lt_or_gt with hia₁ | hia₂ - · rw [inner_eq_zero_symm] - exact ih a h₀ i hia₁ - · exact ih i (mem_Iio.1 hi) a hia₂ + ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := + InnerProductSpace.gramSchmidt_orthogonal _ _ h₀ variable (s) in /-- This is another version of `gramSchmidt_orthogonal` using `Pairwise` instead. -/ theorem gramSchmidt_pairwise_orthogonal (x) : - Pairwise fun a b ↦ ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := fun _ _ h ↦ - gramSchmidt_orthogonal s h _ + Pairwise fun a b ↦ ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := + fun _ _ h ↦ gramSchmidt_orthogonal s h _ variable (s) in theorem gramSchmidt_inv_triangular {i j : ι} (hij : i < j) (x) : - ⟪gramSchmidt s j x, s i x⟫ = 0 := by - rw [gramSchmidt_def'' s] - simp only [inner_add_right, inner_sum, inner_smul_right] - set b /-: ι → E-/ := gramSchmidt s - convert zero_add (0 : ℝ) - · exact gramSchmidt_orthogonal s hij.ne' x - apply Finset.sum_eq_zero - rintro k hki' - have hki : k < i := by simpa using hki' - have : ⟪b j x, b k x⟫ = 0 := gramSchmidt_orthogonal s (hki.trans hij).ne' x - simp [this] + ⟪gramSchmidt s j x, s i x⟫ = 0 := + InnerProductSpace.gramSchmidt_inv_triangular _ _ hij open Submodule Set Order variable (s) in theorem mem_span_gramSchmidt {i j : ι} (hij : i ≤ j) (x) : - s i x ∈ span ℝ ((gramSchmidt s · x) '' Set.Iic j) := by - rw [gramSchmidt_def' s i] - simp_rw [orthogonalProjection_singleton] - exact Submodule.add_mem _ (subset_span <| mem_image_of_mem _ hij) - (Submodule.sum_mem _ fun k hk ↦ smul_mem (span ℝ ((gramSchmidt s · x) '' Set.Iic j)) _ <| - subset_span <| mem_image_of_mem (gramSchmidt s · x) <| (Finset.mem_Iio.1 hk).le.trans hij) + s i x ∈ span ℝ ((gramSchmidt s · x) '' Set.Iic j) := + InnerProductSpace.mem_span_gramSchmidt _ _ hij variable (s) in theorem gramSchmidt_mem_span (x) : - ∀ {j i}, i ≤ j → gramSchmidt s i x ∈ span ℝ ((s · x) '' Set.Iic j) := by - intro j i hij - rw [gramSchmidt_def s i] - simp_rw [orthogonalProjection_singleton] - refine Submodule.sub_mem _ (subset_span (mem_image_of_mem _ hij)) - (Submodule.sum_mem _ fun k hk ↦ ?_) - let hkj : k < j := (Finset.mem_Iio.1 hk).trans_le hij - exact smul_mem _ _ - (span_mono (image_subset (s · x) <| Set.Iic_subset_Iic.2 hkj.le) - <| gramSchmidt_mem_span _ le_rfl) -termination_by j => j + ∀ {j i}, i ≤ j → gramSchmidt s i x ∈ span ℝ ((s · x) '' Set.Iic j) := + InnerProductSpace.gramSchmidt_mem_span _ _ variable (s) in theorem span_gramSchmidt_Iic (c : ι) (x) : span ℝ ((gramSchmidt s · x) '' Set.Iic c) = span ℝ ((s · x) '' Set.Iic c) := - span_eq_span (Set.image_subset_iff.2 fun _ ↦ gramSchmidt_mem_span _ _) <| - Set.image_subset_iff.2 fun _ hx ↦ mem_span_gramSchmidt s hx _ + InnerProductSpace.span_gramSchmidt_Iic .. variable (s) in theorem span_gramSchmidt_Iio (c : ι) (x) : - span ℝ ((gramSchmidt s · x) '' Set.Iio c) = span ℝ ((s · x) '' Set.Iio c) := by - refine span_eq_span (Set.image_subset_iff.2 fun _ hi ↦ - span_mono (image_subset _ <| Iic_subset_Iio.2 hi) <| gramSchmidt_mem_span _ _ le_rfl) <| - Set.image_subset_iff.2 fun _ hi ↦ - span_mono (image_subset _ <| Iic_subset_Iio.2 hi) <| fun hx ↦ ?_ - apply mem_span_gramSchmidt s le_rfl _ + span ℝ ((gramSchmidt s · x) '' Set.Iio c) = span ℝ ((s · x) '' Set.Iio c) := + InnerProductSpace.span_gramSchmidt_Iio _ _ _ -- variable (s) in -- /-- `gramSchmidt` preserves span of vectors. -/ @@ -217,29 +165,15 @@ theorem gramSchmidt_of_orthogonal {x} (hs : Pairwise fun i j ↦ ⟪s i x, s j x · simp theorem gramSchmidt_ne_zero_coe (n : ι) (x) - (h₀ : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι))) : gramSchmidt s n x ≠ 0 := by - by_contra h - have h₁ : s n x ∈ span ℝ ((s · x) '' Set.Iio n) := by - rw [← span_gramSchmidt_Iio s n x, gramSchmidt_def' s, h, zero_add] - apply Submodule.sum_mem _ _ - intro a ha - simp only [orthogonalProjection_singleton] - apply Submodule.smul_mem _ _ _ - rw [Finset.mem_Iio] at ha - exact subset_span ⟨a, ha, by rfl⟩ - have h₂ : ((s · x) ∘ ((↑) : Set.Iic n → ι)) ⟨n, le_refl n⟩ ∈ - span ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι) '' Set.Iio ⟨n, le_refl n⟩) := by - rw [image_comp] - simpa using h₁ - apply LinearIndependent.notMem_span_image h₀ _ h₂ - simp only [Set.mem_Iio, lt_self_iff_false, not_false_iff] + (h₀ : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι))) : gramSchmidt s n x ≠ 0 := + InnerProductSpace.gramSchmidt_ne_zero_coe _ h₀ variable (s) in /-- If the input vectors of `gramSchmidt` are linearly independent, then the output vectors are non-zero. -/ theorem gramSchmidt_ne_zero (n : ι) {x} (h₀ : LinearIndependent ℝ (s · x)) : gramSchmidt s n x ≠ 0 := - gramSchmidt_ne_zero_coe _ x (h₀.comp _ Subtype.coe_injective) + InnerProductSpace.gramSchmidt_ne_zero _ h₀ -- not needed at the moment: I want a point-wise version, along the lines -- "if s i x is a basis, then gramSchmidgt s i x is a triangular matrix" @@ -258,8 +192,7 @@ theorem gramSchmidt_triangular {x} {i j : ι} (hij : i < j) (b : Basis ι ℝ (E /-- `gramSchmidt` produces linearly independent vectors when given linearly independent vectors. -/ theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x)) : LinearIndependent ℝ (gramSchmidt s · x) := - linearIndependent_of_ne_zero_of_inner_eq_zero (fun _ ↦ gramSchmidt_ne_zero _ _ h₀) - (fun _ _ h ↦ gramSchmidt_orthogonal s h x) + InnerProductSpace.gramSchmidt_linearIndependent h₀ end VectorBundle From 7a025f0cd5727b54d88d02e4f2bf69c92c8c7da7 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 9 Jul 2025 15:13:35 +0200 Subject: [PATCH 205/601] Start Trivialization.covDeriv --- .../VectorBundle/CovariantDerivative.lean | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 64b8530e209007..27018791627d04 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -902,6 +902,24 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] end classification +section from_trivialization + +variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] + +noncomputable +def _root_.Trivialization.covDeriv (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) + (x : M) : V x := e.symm x (mfderiv I 𝓘(ℝ, F) (fun x' ↦ (e (σ x')).2) x (X x)) + +lemma _root_.Trivialization.covDeriv_isCovariantDerivativeOn : + IsCovariantDerivativeOn (I := I) F V e.covDeriv e.baseSet where + addX X X' σ x hx := by sorry + smulX X σ c' x hx := by sorry + addσ X σ σ' x hσ hσ' hx := by sorry + smul_const_σ X σ a x hx := by sorry + leibniz X σ f x hσ hf hx := by sorry + +end from_trivialization + section horiz def proj (cov : CovariantDerivative I F V) (e : TotalSpace F V) : From 26816eaf7ad59e19dd06286da810c73550441c99 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 15:13:19 +0200 Subject: [PATCH 206/601] chore: missing API for gramSchmidt; rename zero to bot --- .../InnerProductSpace/GramSchmidtOrtho.lean | 5 ++++- .../Manifold/VectorBundle/GramSchmidtOrtho.lean | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index ff950bfc0dddb8..10599b5ae56b54 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -64,10 +64,13 @@ theorem gramSchmidt_def'' (f : ι → E) (n : ι) : rw [orthogonalProjection_singleton, RCLike.ofReal_pow] @[simp] -theorem gramSchmidt_zero {ι : Type*} [LinearOrder ι] [LocallyFiniteOrder ι] [OrderBot ι] +theorem gramSchmidt_bot {ι : Type*} [LinearOrder ι] [LocallyFiniteOrder ι] [OrderBot ι] [WellFoundedLT ι] (f : ι → E) : gramSchmidt 𝕜 f ⊥ = f ⊥ := by rw [gramSchmidt_def, Iio_eq_Ico, Finset.Ico_self, Finset.sum_empty, sub_zero] +@[simp] +theorem gramSchmidt_zero (n : ι) : gramSchmidt 𝕜 (0 : ι → E) n = 0 := by simp [gramSchmidt_def] + /-- **Gram-Schmidt Orthogonalisation**: `gramSchmidt` produces an orthogonal system of vectors. -/ theorem gramSchmidt_orthogonal (f : ι → E) {a b : ι} (h₀ : a ≠ b) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 9c6e90e425d8c1..e90af0150feb79 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -92,10 +92,20 @@ theorem gramSchmidt_def'' (n : ι) (x) : variable (s) in @[simp] -theorem gramSchmidt_zero {ι : Type*} [LinearOrder ι] [LocallyFiniteOrder ι] [OrderBot ι] +lemma gramSchmidt_apply (n : ι) (x) : + gramSchmidt s n x = InnerProductSpace.gramSchmidt ℝ (s · x) n := rfl + +variable (s) in +@[simp] +theorem gramSchmidt_bot {ι : Type*} [LinearOrder ι] [LocallyFiniteOrder ι] [OrderBot ι] [WellFoundedLT ι] (s : ι → (x : B) → E x) : gramSchmidt s ⊥ = s ⊥ := by ext x - apply InnerProductSpace.gramSchmidt_zero + apply InnerProductSpace.gramSchmidt_bot + +@[simp] +theorem gramSchmidt_zero (n : ι) : gramSchmidt (0 : ι → (x : B) → E x) n = 0 := by + ext x + simpa using InnerProductSpace.gramSchmidt_zero .. variable (s) in /-- **Gram-Schmidt Orthogonalisation**: From dcc3fdc0765d51e052914d4dcf6176483166644b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 14:39:16 +0200 Subject: [PATCH 207/601] Define orthonormal frames; some very basic API. --- .../VectorBundle/GramSchmidtOrtho.lean | 6 +- .../VectorBundle/OrthonormalFrame.lean | 55 ++++++++++++++----- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index e90af0150feb79..e224df8d0b4ab7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -19,9 +19,7 @@ formed a basis at the point, so do the normalised sections. If the bundle metric is `C^k`, then the procedure preserves regularity of sections: if all sections are `C^k`, so are their normalised versions. -This is used in OrthonormalFrame.lean` to convert a local frame to a local orthonormal frame. - -TODO: add main results +This is used in `OrthonormalFrame.lean` to convert a local frame to a local orthonormal frame. ## Implementation note @@ -186,7 +184,7 @@ theorem gramSchmidt_ne_zero (n : ι) {x} (h₀ : LinearIndependent ℝ (s · x)) InnerProductSpace.gramSchmidt_ne_zero _ h₀ -- not needed at the moment: I want a point-wise version, along the lines --- "if s i x is a basis, then gramSchmidgt s i x is a triangular matrix" +-- "if s i x is a basis, then gramSchmidt s i x is a triangular matrix" /- /-- `gramSchmidt` produces a triangular matrix of vectors when given a basis. -/ theorem gramSchmidt_triangular {x} {i j : ι} (hij : i < j) (b : Basis ι ℝ (E x)) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 3d0d92e90dc5e2..8868caca5cf8f7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -3,8 +3,8 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ +import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame -import Mathlib.Geometry.Manifold.VectorBundle.Riemannian /-! # Existence of orthonormal frames on Riemannian vector bundles @@ -13,7 +13,7 @@ In this file, we prove that a Riemannian vector bundle has orthonormal frames ne These are constructed by taking any local frame, and applying Gram-Schmidt orthonormalisation to it (point-wise). If the bundle metric is `C^k`, the resulting orthonormal frame also is. -TODO: add main results, tags, etc +TODO: add main results, etc ## Implementation note @@ -39,22 +39,51 @@ variable [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] -variable {ι : Type*} +variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] -- bad, for prototyping -variable (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) - [MemTrivializationAtlas e] - (b : Basis ι ℝ F) {x : B} (hx : x ∈ e.baseSet) +variable {b : Basis ι ℝ F} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} + [MemTrivializationAtlas e] {x : B} -- (hx : x ∈ e.baseSet) namespace Basis --- TODO: revisit this using GramSchmidtOrtho.lean! - -- noncomputable def orthonormalFrame_toBasis_at : Basis ι ℝ (E x) := -- sorry -- b.map (e.linearEquivAt (R := 𝕜) x hx).symm --- open scoped Classical in --- -- If x is outside of `e.baseSet`, this returns the junk value 0. --- noncomputable def orthonormalFrame : ι → (x : B) → E x := fun i x ↦ --- -- idea: take the vector b i and apply the trivialisation e to it. --- b.localFrame e x--if hx : x ∈ e.baseSet then b.localFrame_toBasis_at e hx i else 0 +variable (b e) in +/-- The orthonormal frame associated to the basis `b` and the trivialisation `e`: +this is obtained by applying the Gram-Schmidt orthonormalisation procedure to `b.localFrame e`. +In particular, if x is outside of `e.baseSet`, this returns the junk value 0. -/ +noncomputable def orthonormalFrame : ι → (x : B) → E x := + VectorBundle.gramSchmidt (b.localFrame e) + +variable (b e) in +/-- Each orthonormal frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local +trivialisation `e`, is `C^k` on `e.baseSet`. -/ +lemma contMDiffOn_orthonormalFrame_baseSet (i : ι) : + CMDiff[e.baseSet] n (T% b.orthonormalFrame e i) := by + apply gramSchmidt_contMDiffOn _ _ (fun i ↦ b.contMDiffOn_localFrame_baseSet n e _) + intro x hx + sorry -- missing lemma: localFrame is linearly independent at each point in the baseSet + +variable (b e) in +lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e.baseSet) : + CMDiffAt n (T% b.orthonormalFrame e i) x := + -- bug: if I change this to a by apply, and put #check after the `by`, it works, but #check' fails + -- #check' contMDiffOn_orthonormalFrame_baseSet + (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx + +-- variable (b e) in +-- @[simp] +-- lemma orthonormalFrame_apply_of_mem_baseSet {i : ι} (hx : x ∈ e.baseSet) : +-- b.orthonormalFrame e i x = b.orthonormalFrame_toBasis_at e hx i := by +-- simp [orthonormalFrame, hx] + +@[simp] +lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : + b.orthonormalFrame e i x = 0 := by + simp only [orthonormalFrame, VectorBundle.gramSchmidt_apply] + convert InnerProductSpace.gramSchmidt_zero ℝ i + apply localFrame_apply_of_notMem e b hx + end Basis From 6b6d0199049ca1f438d53406bd871cf949a594ed Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 15:52:25 +0200 Subject: [PATCH 208/601] Start refactoring local frames: define a predicate IsLocalFrameOn --- .../Manifold/VectorBundle/LocalFrame.lean | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 4bafb08e1851c9..68545a04f8c206 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -73,12 +73,43 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] -- `V` vector bundle -section +noncomputable section -variable {ι : Type*} +section IsLocalFrame + +omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] + +variable {ι : Type*} {s : ι → (x : M) → V x} {u : Set M} + +variable (I F) in +/- +A family of sections `s i` of `V → M` is called a **C^k local frame** on a set `U ⊆ M` iff +- the section values `s i x` form a basis for each `x ∈ U`, +- each section `s i` is `C^k` on `U`. +-/ +structure IsLocalFrameOn (s : ι → (x : M) → V x) (u : Set M) where + linearIndependent {x : M} (hx : x ∈ u) : LinearIndependent 𝕜 (s · x) + generating {x : M} (hx : x ∈ u) : ⊤ ≤ Submodule.span 𝕜 (Set.range (s · x)) + contMDiffOn (i : ι) : CMDiff 1 (T% (s i)) + +namespace IsLocalFrameOn + +/-- Given a local frame `{s i}` on `U ∋ x`, returns the basis `{s i}` of `V x` -/ +def toBasisAt (hs : IsLocalFrameOn I F s u) {x} (hx : x ∈ u) : Basis ι 𝕜 (V x) := + Basis.mk (hs.linearIndependent hx) (hs.generating hx) + +lemma toBasisAt_coe (hs : IsLocalFrameOn I F s u) {x} (hx : x ∈ u) (i : ι) : + (toBasisAt hs hx) i = s i x := by + simpa only [toBasisAt] using Basis.mk_apply (hs.linearIndependent hx) (hs.generating hx) i + +end IsLocalFrameOn + +end IsLocalFrame namespace Basis +variable {ι : Type*} + noncomputable def localFrame_toBasis_at (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] @@ -229,7 +260,7 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : end Basis -variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} +variable {ι : Type*} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} omit [IsManifold I 0 M] in From e900ccf308184ed0c3ca13f84071dd84e7c8a326 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 16:07:04 +0200 Subject: [PATCH 209/601] chore: more API for local frames; actually becomes cleaner! --- .../Manifold/VectorBundle/LocalFrame.lean | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 68545a04f8c206..861da316fc1a4f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -98,10 +98,72 @@ namespace IsLocalFrameOn def toBasisAt (hs : IsLocalFrameOn I F s u) {x} (hx : x ∈ u) : Basis ι 𝕜 (V x) := Basis.mk (hs.linearIndependent hx) (hs.generating hx) +@[simp] lemma toBasisAt_coe (hs : IsLocalFrameOn I F s u) {x} (hx : x ∈ u) (i : ι) : (toBasisAt hs hx) i = s i x := by simpa only [toBasisAt] using Basis.mk_apply (hs.linearIndependent hx) (hs.generating hx) i +open scoped Classical in +/-- Coefficients of a section `s` of `V` w.r.t. a local frame `{s i}` on `u`. +Outside of `u`, this returns the junk value 0. -/ +-- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate +-- cases. +def repr (hs : IsLocalFrameOn I F s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where + toFun s x := if hx : x ∈ u then (hs.toBasisAt hx).repr (s x) i else 0 + map_add' s s' := by + ext x + by_cases hx : x ∈ u <;> simp [hx] + map_smul' c s := by + ext x + by_cases hx : x ∈ u <;> simp [hx] + +variable {x : M} + +@[simp] +lemma repr_apply_of_notMem (hs : IsLocalFrameOn I F s u) (hx : x ∉ u) (t : Π x : M, V x) (i : ι) : + hs.repr i t x = 0 := by + simp [repr, hx] + +@[simp] +lemma repr_apply_of_mem (hs : IsLocalFrameOn I F s u) (hx : x ∈ u) (t : Π x : M, V x) (i : ι) : + hs.repr i t x = (hs.toBasisAt hx).repr (t x) i := by + simp [repr, hx] + +-- TODO: add uniqueness of the decomposition; follows from the IsBasis property in the definition + +lemma repr_sum_eq [Fintype ι] (hs : IsLocalFrameOn I F s u) (t : Π x : M, V x) (hx : x ∈ u) : + t x = (∑ i, (hs.repr i t x) • (s i x)) := by + simpa [repr, hx] using (Basis.sum_repr (hs.toBasisAt hx) (t x)).symm + +/-- A local frame locally spans the space of sections for `V`: for each local frame `s i` on an open +set `u` around `x`, we have `t = ∑ i, (hs.repr i t) • (s i x)` near `x`. -/ +lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F s u) + (t : Π x : M, V x) (hx : x ∈ u) (hu : IsOpen u) : + ∀ᶠ x' in 𝓝 x, t x' = ∑ i, (hs.repr i t x') • (s i x') := + eventually_nhds_iff.mpr ⟨u, fun _ h ↦ hs.repr_sum_eq t h, hu, hx⟩ + +/-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ +lemma repr_congr (hs : IsLocalFrameOn I F s u) {t t' : Π x : M, V x}-- (hx : x ∈ u) + {i : ι} (htt' : t x = t' x) : + hs.repr i t x = hs.repr i t' x := by + by_cases hxe : x ∈ u + · simp [repr, hxe] + congr + · simp [repr, hxe] + +lemma repr_apply_zero_at (hs : IsLocalFrameOn I F s u) {t : Π x : M, V x} (ht : t x = 0) (i : ι) : + hs.repr i t x = 0 := by + simp [hs.repr_congr (t' := 0) ht] + +-- XXX: this statement does not readily transfer, but probably I won't need this particular +-- result in this general setting +-- /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `t` a bundle section. +-- Then the coefficient of `t` w.r.t. a local frame `s i` near `x` +-- equals the cofficient of "`t x` read in the trivialisation `e`" for `b i`. -/ +-- lemma localFrame_repr_eq_repr (hs : IsLocalFrameOn I F s u) (hxe : x ∈ u) {i : ι} {t : Π x : M, V x} : +-- hs.repr i t x = b.repr (e (s x)).2 i := by +-- simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] + end IsLocalFrameOn end IsLocalFrame From 338fac2c64472e820231fb978b3e81448d231516 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 18:15:49 +0200 Subject: [PATCH 210/601] checkpoint: LocalFrame compiles, a few results refactored (and a bit of uglification, sadly) --- .../Manifold/VectorBundle/LocalFrame.lean | 203 ++++++++++-------- 1 file changed, 109 insertions(+), 94 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 861da316fc1a4f..a85973d6665ad4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -79,9 +79,9 @@ section IsLocalFrame omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] -variable {ι : Type*} {s : ι → (x : M) → V x} {u : Set M} +variable {ι : Type*} {s : ι → (x : M) → V x} {u : Set M} {x : M} {n : WithTop ℕ∞} -variable (I F) in +variable (I F n) in /- A family of sections `s i` of `V → M` is called a **C^k local frame** on a set `U ⊆ M` iff - the section values `s i x` form a basis for each `x ∈ U`, @@ -90,16 +90,20 @@ A family of sections `s i` of `V → M` is called a **C^k local frame** on a set structure IsLocalFrameOn (s : ι → (x : M) → V x) (u : Set M) where linearIndependent {x : M} (hx : x ∈ u) : LinearIndependent 𝕜 (s · x) generating {x : M} (hx : x ∈ u) : ⊤ ≤ Submodule.span 𝕜 (Set.range (s · x)) - contMDiffOn (i : ι) : CMDiff 1 (T% (s i)) + contMDiffOn (i : ι) : CMDiff[u] n (T% (s i)) namespace IsLocalFrameOn +lemma contMDiffAt (hs : IsLocalFrameOn I F n s u) (hu : IsOpen u) (hx : x ∈ u) (i : ι) : + CMDiffAt n (T% s i) x := + (hs.contMDiffOn i).contMDiffAt <| hu.mem_nhds hx + /-- Given a local frame `{s i}` on `U ∋ x`, returns the basis `{s i}` of `V x` -/ -def toBasisAt (hs : IsLocalFrameOn I F s u) {x} (hx : x ∈ u) : Basis ι 𝕜 (V x) := +def toBasisAt (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) : Basis ι 𝕜 (V x) := Basis.mk (hs.linearIndependent hx) (hs.generating hx) @[simp] -lemma toBasisAt_coe (hs : IsLocalFrameOn I F s u) {x} (hx : x ∈ u) (i : ι) : +lemma toBasisAt_coe (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) (i : ι) : (toBasisAt hs hx) i = s i x := by simpa only [toBasisAt] using Basis.mk_apply (hs.linearIndependent hx) (hs.generating hx) i @@ -108,7 +112,7 @@ open scoped Classical in Outside of `u`, this returns the junk value 0. -/ -- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate -- cases. -def repr (hs : IsLocalFrameOn I F s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where +def repr (hs : IsLocalFrameOn I F n s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where toFun s x := if hx : x ∈ u then (hs.toBasisAt hx).repr (s x) i else 0 map_add' s s' := by ext x @@ -120,38 +124,38 @@ def repr (hs : IsLocalFrameOn I F s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M variable {x : M} @[simp] -lemma repr_apply_of_notMem (hs : IsLocalFrameOn I F s u) (hx : x ∉ u) (t : Π x : M, V x) (i : ι) : +lemma repr_apply_of_notMem (hs : IsLocalFrameOn I F n s u) (hx : x ∉ u) (t : Π x : M, V x) (i : ι) : hs.repr i t x = 0 := by simp [repr, hx] @[simp] -lemma repr_apply_of_mem (hs : IsLocalFrameOn I F s u) (hx : x ∈ u) (t : Π x : M, V x) (i : ι) : +lemma repr_apply_of_mem (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) (t : Π x : M, V x) (i : ι) : hs.repr i t x = (hs.toBasisAt hx).repr (t x) i := by simp [repr, hx] -- TODO: add uniqueness of the decomposition; follows from the IsBasis property in the definition -lemma repr_sum_eq [Fintype ι] (hs : IsLocalFrameOn I F s u) (t : Π x : M, V x) (hx : x ∈ u) : +lemma repr_sum_eq [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hx : x ∈ u) : t x = (∑ i, (hs.repr i t x) • (s i x)) := by simpa [repr, hx] using (Basis.sum_repr (hs.toBasisAt hx) (t x)).symm /-- A local frame locally spans the space of sections for `V`: for each local frame `s i` on an open set `u` around `x`, we have `t = ∑ i, (hs.repr i t) • (s i x)` near `x`. -/ -lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F s u) +lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hx : x ∈ u) (hu : IsOpen u) : ∀ᶠ x' in 𝓝 x, t x' = ∑ i, (hs.repr i t x') • (s i x') := eventually_nhds_iff.mpr ⟨u, fun _ h ↦ hs.repr_sum_eq t h, hu, hx⟩ /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma repr_congr (hs : IsLocalFrameOn I F s u) {t t' : Π x : M, V x}-- (hx : x ∈ u) - {i : ι} (htt' : t x = t' x) : +lemma repr_congr (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} + (htt' : t x = t' x) (i : ι) : hs.repr i t x = hs.repr i t' x := by by_cases hxe : x ∈ u · simp [repr, hxe] congr · simp [repr, hxe] -lemma repr_apply_zero_at (hs : IsLocalFrameOn I F s u) {t : Π x : M, V x} (ht : t x = 0) (i : ι) : +lemma repr_apply_zero_at (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} (ht : t x = 0) (i : ι) : hs.repr i t x = 0 := by simp [hs.repr_congr (t' := 0) ht] @@ -160,7 +164,7 @@ lemma repr_apply_zero_at (hs : IsLocalFrameOn I F s u) {t : Π x : M, V x} (ht : -- /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `t` a bundle section. -- Then the coefficient of `t` w.r.t. a local frame `s i` near `x` -- equals the cofficient of "`t x` read in the trivialisation `e`" for `b i`. -/ --- lemma localFrame_repr_eq_repr (hs : IsLocalFrameOn I F s u) (hxe : x ∈ u) {i : ι} {t : Π x : M, V x} : +-- lemma localFrame_repr_eq_repr (hs : IsLocalFrameOn I F s u) {t : Π x : M, V x} (hxe : x ∈ u) {i : ι} : -- hs.repr i t x = b.repr (e (s x)).2 i := by -- simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] @@ -202,12 +206,29 @@ lemma contMDiffOn_localFrame_baseSet intro y hy simp [localFrame, hy, localFrame_toBasis_at] +omit [IsManifold I 0 M] in +variable (I) in +/-- `b.localFrame e i` is indeed a local frame on `e.baseSet` -/ +lemma localFrame_isLocalFrameOn_baseSet + (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : IsLocalFrameOn I F n (b.localFrame e) e.baseSet + where + contMDiffOn i := b.contMDiffOn_localFrame_baseSet _ e i + linearIndependent := by + intro x hx + convert (b.localFrame_toBasis_at e hx).linearIndependent + simp [localFrame, hx, localFrame_toBasis_at] + generating := by + intro x hx + convert (b.localFrame_toBasis_at e hx).span_eq.ge + simp [localFrame, hx, localFrame_toBasis_at] + omit [IsManifold I 0 M] in lemma _root_.contMDiffAt_localFrame_of_mem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) {x : M} (hx : x ∈ e.baseSet) : CMDiffAt n (T% b.localFrame e i) x := - (contMDiffOn_localFrame_baseSet n e b i).contMDiffAt <| e.open_baseSet.mem_nhds hx + (b.localFrame_isLocalFrameOn_baseSet I n e).contMDiffAt e.open_baseSet hx _ @[simp] lemma localFrame_apply_of_mem_baseSet @@ -229,17 +250,20 @@ lemma localFrame_toBasis_at_coe (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : b.localFrame_toBasis_at e hx i = b.localFrame e i x := by simp [hx] --- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? -/-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ -def isBasis_localFrame - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) : sorry := by - -- the b i form a basis of F, - -- and the trivialisation e is a linear equivalence (thus preserves bases) - sorry +-- -- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? +-- /-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ +-- def isBasis_localFrame +-- (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) +-- [MemTrivializationAtlas e] +-- (b : Basis ι 𝕜 F) : sorry := by +-- -- the b i form a basis of F, +-- -- and the trivialisation e is a linear equivalence (thus preserves bases) +-- sorry + +variable [ContMDiffVectorBundle 1 F V I] open scoped Classical in +variable (I) in /-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ -- If x is outside of `e.baseSet`, this returns the junk value 0. -- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate @@ -247,69 +271,61 @@ open scoped Classical in noncomputable def localFrame_repr (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where - toFun s x := if hx : x ∈ e.baseSet then (b.localFrame_toBasis_at e hx).repr (s x) i else 0 - map_add' s s' := by - ext x - by_cases hx : x ∈ e.baseSet <;> simp [hx] - map_smul' c s := by - ext x - by_cases hx : x ∈ e.baseSet <;> simp [hx] + (b : Basis ι 𝕜 F) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 := + (b.localFrame_isLocalFrameOn_baseSet I 1 e).repr i variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} +omit [IsManifold I 0 M] in variable (e b) in @[simp] lemma localFrame_repr_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : - b.localFrame_repr e i s x = 0 := by - simpa [localFrame_repr] using fun hx' ↦ (hx hx').elim + b.localFrame_repr I e i s x = 0 := by + simpa [localFrame_repr] using + (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_apply_of_notMem hx s i +-- XXX: do I want this lemma, or just the IsLocalFrameOn version? variable (e b) in @[simp] lemma localFrame_repr_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : - b.localFrame_repr e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by - simp [localFrame_repr, hx] - --- uniqueness of the decomposition: follows from the IsBasis property above + b.localFrame_repr I e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by + simp [localFrame_repr, hx, localFrame_toBasis_at, IsLocalFrameOn.toBasisAt] + congr + sorry -- TODO: better name? +omit [IsManifold I 0 M] in lemma localFrame_repr_sum_eq [Fintype ι] (s : Π x : M, V x) {x'} (hx : x' ∈ e.baseSet) : - s x' = (∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x') := by - simp [Basis.localFrame_repr, hx] - exact (sum_repr (localFrame_toBasis_at e b hx) (s x')).symm + s x' = (∑ i, (b.localFrame_repr I e i s x') • b.localFrame e i x') := by + simp only [localFrame_repr] + exact (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_sum_eq s hx variable (b) in +omit [IsManifold I 0 M] in /-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` of `V` around `x`, we have `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` -/ lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr e i s x') • b.localFrame e i x' := + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr I e i s x') • b.localFrame e i x' := eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_repr_sum_eq s h, e.open_baseSet, hxe⟩ +omit [IsManifold I 0 M] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma localFrame_repr_congr (b : Basis ι 𝕜 F) {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : - b.localFrame_repr e i s x = b.localFrame_repr e i s' x := by + b.localFrame_repr I e i s x = b.localFrame_repr I e i s' x := by by_cases hxe : x ∈ e.baseSet - · simp [localFrame_repr, hxe, localFrame_toBasis_at] + · simp [localFrame_repr, hxe] congr · simp [localFrame_repr, hxe] +omit [IsManifold I 0 M] in lemma localFrame_repr_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.localFrame_repr e i s x = 0 := by - rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] - simp - -- This proof may indicate a missing simp lemma. - -- by_cases hxe : x ∈ e.baseSet; swap - -- · simp [localFrame_repr, hxe] - -- simp [localFrame_repr, localFrame_toBasis_at, hxe, hs] - -- have : e.symm x = 0 := sorry - -- have : (e { proj := x, snd := 0 }).2 = 0 := by - -- trans (e { proj := x, snd := e.symm x 0 }).2 - -- · simp [this] - -- · simp [e.apply_mk_symm hxe] - -- simp [this] + b.localFrame_repr I e i s x = 0 := by + --rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] + simp only [localFrame_repr] + exact (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_apply_zero_at hs i variable {n} @@ -317,13 +333,15 @@ variable {n} Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : - b.localFrame_repr e i s x = b.repr (e (s x)).2 i := by - simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] + b.localFrame_repr I e i s x = b.repr (e (s x)).2 i := by + simp only [localFrame_repr] + sorry -- simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] end Basis variable {ι : Type*} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} + [ContMDiffVectorBundle 1 F V I] omit [IsManifold I 0 M] in /-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame @@ -332,7 +350,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] (hs : CMDiffAt k (T% s) x) (i : ι) : - CMDiffAt k (b.localFrame_repr e i s) x := by + CMDiffAt k (b.localFrame_repr I e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical -- step 1: on e.baseSet, can compute the coefficient very well @@ -369,16 +387,16 @@ in the local frame induced by `e` -/ lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} [ContMDiffVectorBundle k F V I] (ht : IsOpen t) (ht' : t ⊆ e.baseSet) - (hs : CMDiff[t] k (T% s)) (i : ι) : CMDiff[t] k (b.localFrame_repr e i s) := + (hs : CMDiff[t] k (T% s)) (i : ι) : CMDiff[t] k (b.localFrame_repr I e i s) := fun _ hx ↦ (contMDiffAt_localFrame_repr (ht' hx) b (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -omit [IsManifold I 0 M] [ContMDiffVectorBundle n F V I] in +omit [IsManifold I 0 M] in -- [ContMDiffVectorBundle n F V I] in /-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] - (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : CMDiff[e.baseSet] k (b.localFrame_repr e i s) := + (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : CMDiff[e.baseSet] k (b.localFrame_repr I e i s) := contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ omit [IsManifold I 0 M] in @@ -387,15 +405,15 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {x' : M} (hx : x' ∈ e.baseSet) : - CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_repr e i s) x' := by + CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_repr I e i s) x' := by refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ - have this (i) : CMDiffAt k (T% ((b.localFrame_repr e i) s • b.localFrame e i)) x' := + have this (i) : CMDiffAt k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) x' := (hi i).smul_section (contMDiffAt_localFrame_of_mem k e b i hx) have almost : CMDiffAt k - (T% (fun x ↦ ∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + (T% (fun x ↦ ∑ i, (b.localFrame_repr I e i) s x • b.localFrame e i x)) x' := .sum_section fun i _ ↦ this i apply almost.congr_of_eventuallyEq ?_ - obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) + obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec (I := I) hx s) exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] omit [IsManifold I 0 M] in @@ -404,11 +422,11 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_repr e i s) := by + CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_repr I e i s) := by refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ - have this (i) : CMDiff[t] k (T% ((b.localFrame_repr e i) s • b.localFrame e i)) := + have this (i) : CMDiff[t] k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') - let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' + let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i apply almost.congr intro y hy @@ -420,7 +438,7 @@ omit [IsManifold I 0 M] in coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] : - CMDiff[e.baseSet] k (T% s) ↔ ∀ i, CMDiff[e.baseSet] k (b.localFrame_repr e i s) := by + CMDiff[e.baseSet] k (T% s) ↔ ∀ i, CMDiff[e.baseSet] k (b.localFrame_repr I e i s) := by rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] -- Differentiability of a section can be checked in terms of its local frame coefficients @@ -430,9 +448,8 @@ omit [IsManifold I 0 M] in /-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame near `x` induced by `e` and `b` -/ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - [ContMDiffVectorBundle 1 F V I] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDiffAt (T% s) x) (i : ι) : - MDiffAt (b.localFrame_repr e i s) x := by + MDiffAt (b.localFrame_repr I e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical -- step 1: on e.baseSet, can compute the coefficient very well @@ -466,9 +483,9 @@ omit [IsManifold I 0 M] in /-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma mdifferentiableOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) - [ContMDiffVectorBundle 1 F V I] {s : Π x : M, V x} {t : Set M} + {s : Π x : M, V x} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : MDiff[t] (T% s)) (i : ι) : - MDiff[t] (b.localFrame_repr e i s) := + MDiff[t] (b.localFrame_repr I e i s) := fun _ hx ↦ (mdifferentiableAt_localFrame_repr (ht' hx) b (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt @@ -476,41 +493,40 @@ omit [IsManifold I 0 M] in /-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame induced by `e` -/ lemma mdifferentiableOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} + (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDiff[e.baseSet] (T% s)) (i : ι) : - MDiff[e.baseSet] (b.localFrame_repr e i s) := + MDiff[e.baseSet] (b.localFrame_repr I e i s) := mdifferentiableOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable at `x ∈ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : - MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_repr e i s) x' := by + MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_repr I e i s) x' := by refine ⟨fun h i ↦ mdifferentiableAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ - have this (i) : MDiffAt (T% (b.localFrame_repr e i) s • b.localFrame e i) x' := + have this (i) : MDiffAt (T% (b.localFrame_repr I e i) s • b.localFrame e i) x' := mdifferentiableAt_smul_section (hi i) ((contMDiffAt_localFrame_of_mem 1 e b i hx).mdifferentiableAt le_rfl) have almost : MDiffAt - (T% (fun x ↦ ∑ i, (b.localFrame_repr e i) s x • b.localFrame e i x)) x' := + (T% (fun x ↦ ∑ i, (b.localFrame_repr I e i) s x • b.localFrame e i x)) x' := mdifferentiableAt_finsum_section fun i ↦ this i apply almost.congr_of_eventuallyEq ?_ - obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec hx s) + obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec (I := I) hx s) exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on `t ⊆ e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - [ContMDiffVectorBundle 1 F V I] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} + (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - MDiff[t] (T% s) ↔ ∀ i, MDiff[t] (b.localFrame_repr e i s) := by + MDiff[t] (T% s) ↔ ∀ i, MDiff[t] (b.localFrame_repr I e i s) := by refine ⟨fun h i ↦ mdifferentiableOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ - have this (i) : MDiff[t] (T% ((b.localFrame_repr e i) s • b.localFrame e i)) := + have this (i) : MDiff[t] (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := mdifferentiableOn_smul_section (hi i) <| ((b.contMDiffOn_localFrame_baseSet 1 e i).mono ht').mdifferentiableOn le_rfl - let rhs := fun x' ↦ ∑ i, (b.localFrame_repr e i) s x' • b.localFrame e i x' + let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' have almost : MDiff[t] (T% rhs) := mdifferentiableOn_finsum_section fun i ↦ this i apply almost.congr intro y hy @@ -521,9 +537,8 @@ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableOn_baseSet_iff_localFrame_repr - [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle 1 F V I] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} : - MDiff[e.baseSet] (T% s) ↔ ∀ i, MDiff[e.baseSet] (b.localFrame_repr e i s) := by + [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} : + MDiff[e.baseSet] (T% s) ↔ ∀ i, MDiff[e.baseSet] (b.localFrame_repr I e i s) := by rw [mdifferentiableOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] end MDifferentiable @@ -575,12 +590,12 @@ lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : nth_rw 2 [← (b.localFrame_toBasis_at e hx).sum_repr v] /-- A local extension has constant frame coefficients within its defining trivialisation. -/ -lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) +lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) [ContMDiffVectorBundle 1 F V I] {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) (i : ι) - {x' : M} (hx' : x' ∈ e.baseSet): - b.localFrame_repr e i (localExtensionOn b e x v) x' = - b.localFrame_repr e i (localExtensionOn b e x v) x := by + {x' : M} (hx' : x' ∈ e.baseSet) : + b.localFrame_repr I e i (localExtensionOn b e x v) x' = + b.localFrame_repr I e i (localExtensionOn b e x v) x := by simp [localExtensionOn, hx, hx'] -- By construction, localExtensionOn is a linear map. @@ -614,7 +629,7 @@ lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace -- constant, hence smoothness follows. rw [contMDiffOn_baseSet_iff_localFrame_repr b] intro i - apply (contMDiffOn_const (c := (b.localFrame_repr e i) (localExtensionOn b e x v) x)).congr + apply (contMDiffOn_const (c := (b.localFrame_repr I e i) (localExtensionOn b e x v) x)).congr intro y hy rw [localExtensionOn_localFrame_repr b hx v i hy] From 2600785a1acb8f252132579864c7e5d5186ab6c9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 19:27:05 +0200 Subject: [PATCH 211/601] Clean up orthonormal frame accordingly. --- .../VectorBundle/OrthonormalFrame.lean | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 8868caca5cf8f7..0636a7e450bea2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -41,14 +41,30 @@ variable variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] +variable {s : ι → (x : B) → E x} {u : Set B} + +-- also: monotonicity? will see if useful, at all... + +/-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ +def IsLocalFrameOn.gramSchmidt (hs : IsLocalFrameOn IB F n s u) : + IsLocalFrameOn IB F n (VectorBundle.gramSchmidt s) u where + linearIndependent := by + intro x hx + exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) + generating := by + intro x hx + sorry -- lemma about Gram-Schmidt... + contMDiffOn i := gramSchmidt_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| + fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective + +namespace Basis + -- bad, for prototyping variable {b : Basis ι ℝ F} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} [MemTrivializationAtlas e] {x : B} -- (hx : x ∈ e.baseSet) -namespace Basis --- noncomputable def orthonormalFrame_toBasis_at : Basis ι ℝ (E x) := --- sorry -- b.map (e.linearEquivAt (R := 𝕜) x hx).symm +-- noncomputable def orthonormalFrame_toBasis_at : Basis ι ℝ (E x) := sorry variable (b e) in /-- The orthonormal frame associated to the basis `b` and the trivialisation `e`: @@ -57,15 +73,20 @@ In particular, if x is outside of `e.baseSet`, this returns the junk value 0. -/ noncomputable def orthonormalFrame : ι → (x : B) → E x := VectorBundle.gramSchmidt (b.localFrame e) +omit [IsManifold IB n B] in +/-- An orthonormal frame w.r.t. a local trivialisation is a local frame. -/ +lemma orthonormalFrame_isLocalFrameOn : IsLocalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := + (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidt + +omit [IsManifold IB n B] in variable (b e) in /-- Each orthonormal frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_orthonormalFrame_baseSet (i : ι) : - CMDiff[e.baseSet] n (T% b.orthonormalFrame e i) := by - apply gramSchmidt_contMDiffOn _ _ (fun i ↦ b.contMDiffOn_localFrame_baseSet n e _) - intro x hx - sorry -- missing lemma: localFrame is linearly independent at each point in the baseSet + CMDiff[e.baseSet] n (T% b.orthonormalFrame e i) := + orthonormalFrame_isLocalFrameOn.contMDiffOn _ +omit [IsManifold IB n B] in variable (b e) in lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e.baseSet) : CMDiffAt n (T% b.orthonormalFrame e i) x := @@ -87,3 +108,16 @@ lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : apply localFrame_apply_of_notMem e b hx end Basis + +/- next steps: + +lemma: local frame coefficients (in the same way), +a section is C^k iff its coefficients are +(prove for IsLocalFrameOn first!) + +lemma: frame coefficient of s_i is the product with that local section + (only true here, by orthogonality) + +cor: section t is smooth iff each product is (just rewrite twice) + +lemma: uniqueness (what I need for torsion) -/ From 90848b39fa2fcf6897dae42b7b38e8b56b260a3f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 19:45:07 +0200 Subject: [PATCH 212/601] Prepare generalising smoothness in frame coefficient lemmas --- .../Manifold/VectorBundle/LocalFrame.lean | 35 +++++++--- .../VectorBundle/OrthonormalFrame.lean | 66 ++++++++++++++++++- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index a85973d6665ad4..0d5d16f2426f54 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -18,10 +18,18 @@ i.e. a collection of sections `s_i` of `V` which is smooth on `e.baseSet` such t basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquely written as `s = ∑ i, f^i s_i` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. +The latter statement holds in many cases, but not for every vector bundle. In this file, we prove +it for local frames induced by a trivialisation, for finite rank bundles over a complete field. +In `OrthonormalFrame.lean`, we prove the same for real vector bundles of any rank which admit +a `C^n` bundle metric. This includes bundles of finite rank, modelled on a Hilbert space or +on a Banach space which has smooth partitions of unity. + We use this to construct local extensions of a vector to a section which is smooth on the trivialisation domain. ## Main definitions and results +TODO: this doc-string is outdated, needs to be augmented for the recent refactoring! + * `Basis.localFrame e b`: the local frame on `V` w.r.t. a local trivialisation `e` of `V` and a basis `b` of `F`. Use `b.localFrame e i` to access the i-th section in that frame. * `b.contMDiffOn_localFrame_baseSet`: each section `b.localFrame e i` is smooth on `e.baseSet` @@ -79,7 +87,7 @@ section IsLocalFrame omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] -variable {ι : Type*} {s : ι → (x : M) → V x} {u : Set M} {x : M} {n : WithTop ℕ∞} +variable {ι : Type*} {s : ι → (x : M) → V x} {u u' : Set M} {x : M} {n : WithTop ℕ∞} variable (I F n) in /- @@ -94,6 +102,15 @@ structure IsLocalFrameOn (s : ι → (x : M) → V x) (u : Set M) where namespace IsLocalFrameOn +lemma mono (hs : IsLocalFrameOn I F n s u) (hu'u : u' ⊆ u) : IsLocalFrameOn I F n s u' where + linearIndependent := by + intro x hx + exact hs.linearIndependent (hu'u hx) + generating := by + intro x hx + exact hs.generating (hu'u hx) + contMDiffOn i := (hs.contMDiffOn i).mono hu'u + lemma contMDiffAt (hs : IsLocalFrameOn I F n s u) (hu : IsOpen u) (hx : x ∈ u) (i : ι) : CMDiffAt n (T% s i) x := (hs.contMDiffOn i).contMDiffAt <| hu.mem_nhds hx @@ -159,15 +176,6 @@ lemma repr_apply_zero_at (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} (ht hs.repr i t x = 0 := by simp [hs.repr_congr (t' := 0) ht] --- XXX: this statement does not readily transfer, but probably I won't need this particular --- result in this general setting --- /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `t` a bundle section. --- Then the coefficient of `t` w.r.t. a local frame `s i` near `x` --- equals the cofficient of "`t x` read in the trivialisation `e`" for `b i`. -/ --- lemma localFrame_repr_eq_repr (hs : IsLocalFrameOn I F s u) {t : Π x : M, V x} (hxe : x ∈ u) {i : ι} : --- hs.repr i t x = b.repr (e (s x)).2 i := by --- simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] - end IsLocalFrameOn end IsLocalFrame @@ -339,6 +347,13 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : end Basis +/-! # Determining smoothness of a section via its local frame coefficients +We show that for finite rank bundles over a complete field, a section is smooth iff its coefficients +in a local frame induced by a local trivialisation are. In many contexts, this statement holds for +*any* local frame (e.g., for all real bundles which admit a continuous bundle metric, as is +proven in `OrthonormalFrame.lean`). +-/ + variable {ι : Type*} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} [ContMDiffVectorBundle 1 F V I] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 0636a7e450bea2..54b0ce59c18364 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -43,7 +43,71 @@ variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT variable {s : ι → (x : B) → E x} {u : Set B} --- also: monotonicity? will see if useful, at all... +/-! # Determining smoothness of a section via its local frame coefficients + +We show that for any local frame `{s i}` on `u ⊆ B`, a section `t` is smooth on `u` if and only if +its coefficients in `{s i}` are. This argument crucially depends on the existence of a smooth +bundle metric on `V` (which always holds in finite dimensions, and in certain important +infinite-dimensional cases). + +See `LocalFrame.lean` for a similar statement, about local frames induced by a local trivialisation +on finite rank bundles over any complete field. +-/ + +section smoothness + +namespace IsLocalFrameOn + +variable (hs : IsLocalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} + +set_option linter.style.commandStart false + +/-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ +lemma contMDiffAt_repr (hx : x ∈ u) (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : + CMDiffAt n (hs.repr i t) x := by + sorry + +/-- If `{s i}` is a local frame on `u` and `t` is `C^k` on `u`, +so is its coefficient in the local frame `s i` -/ +lemma contMDiffOn_repr + (hu : IsOpen u) (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.repr i t) := by + intro x' hx + apply ContMDiffAt.contMDiffWithinAt + apply hs.contMDiffAt_repr hx (hu.mem_nhds hx) (ht.contMDiffAt <| hu.mem_nhds hx) + +/-- A section `s` of `V` is `C^k` at `x ∈ u` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma _root_.contMDiffAt_iff_isLocalFrameOn_repr --[Fintype ι] + (hx : x ∈ u) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.repr i t) x := by + refine ⟨fun h i ↦ hs.contMDiffAt_repr hx sorry/-hu-/ h i, fun hi ↦ ?_⟩ + sorry /-have this (i) : CMDiffAt n (T% (hs.repr i t • s i)) x := + (hi i).smul_section (hs.contMDiffAt sorry/-hu-/ hx i) + have almost : CMDiffAt n + (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := + .sum_section fun i _ ↦ this i + apply almost.congr_of_eventuallyEq ?_ + obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (hs.repr_spec (I := I) t hx sorry) + exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] -/ + +-- omit [IsManifold I 0 M] in +/-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its +coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ +lemma contMDiffOn_iff_repr [Fintype ι] : + CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.repr i t) := by +-- refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ +-- have this (i) : CMDiff[t] k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := +-- (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') +-- let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' +-- have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i +-- apply almost.congr +-- intro y hy +-- congr +-- exact b.localFrame_repr_sum_eq s (ht' hy) + sorry + +end IsLocalFrameOn + +end smoothness /-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ def IsLocalFrameOn.gramSchmidt (hs : IsLocalFrameOn IB F n s u) : From 2c976566478e9471199896f704de02743aadc0f3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 9 Jul 2025 20:53:24 +0200 Subject: [PATCH 213/601] Fix the build and silence a few linter errors --- .../Geometry/Manifold/VectorBundle/LeviCivita.lean | 4 +++- .../Geometry/Manifold/VectorBundle/Tensoriality.lean | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 15c51a33d7fc8c..ee6de84d1ce7bb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -105,6 +105,8 @@ lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product end product +set_option linter.style.commandStart false -- custom elaborators not handled well yet + namespace CovariantDerivative -- Let `cov` be a covariant derivative on `TM`. @@ -348,7 +350,7 @@ lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] : + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (TangentSpace I) (existence_candidate I M) e.baseSet := by sorry diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index f1ccf5da2a5aac..ed1d0436517f13 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -86,7 +86,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_repr t b + let c := Basis.localFrame_repr I t b have hs (i) : MDiffAt (T% s i) x:= (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : @@ -112,6 +112,7 @@ include I in omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] + [ContMDiffVectorBundle 1 F V I] {φ : (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' : Π x : M, V x} (hσσ' : σ x = σ' x) @@ -145,9 +146,9 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_repr t b - rw [locality (b.localFrame_repr_spec x_mem σ), locality (b.localFrame_repr_spec x_mem σ'), - sum_phi, sum_phi] + let c := Basis.localFrame_repr (I := I) t b + rw [locality (b.localFrame_repr_spec (I := I) x_mem σ), + locality (b.localFrame_repr_spec (I := I) x_mem σ'), sum_phi, sum_phi] change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x congr ext i @@ -159,7 +160,7 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi include I in omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in lemma tensoriality_criterion₂' [FiberBundle F V] [VectorBundle ℝ F V] - [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] + [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle 1 F V I] [FiberBundle F' V'] [VectorBundle ℝ F' V'] {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' τ τ' : Π x : M, V x} From e147cea4fc4ef759a7ab9c8eb2f7ec22bd50476e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 00:40:53 +0200 Subject: [PATCH 214/601] Progress: local frame coefficients for local frames --- .../VectorBundle/OrthonormalFrame.lean | 78 +++++++++++++++---- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 54b0ce59c18364..bdff30bc3ef12d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -31,17 +31,52 @@ open scoped ContDiff Topology -- Let `V` be a smooth vector bundle with a `C^n` Riemannian structure over a `C^k` manifold `B`. variable {EB : Type*} [NormedAddCommGroup EB] [NormedSpace ℝ EB] - {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners ℝ EB HB} {n : WithTop ℕ∞} + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners ℝ EB HB} {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] {E : B → Type*} [TopologicalSpace (TotalSpace F E)] [∀ x, NormedAddCommGroup (E x)] - [∀ x, InnerProductSpace ℝ (E x)] [FiberBundle F E] [VectorBundle ℝ F E] + [∀ x, InnerProductSpace ℝ (E x)] [FiberBundle F E] [VectorBundle ℝ F E] {n : WithTop ℕ∞} [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] +local notation "⟪" x ", " y "⟫" => inner ℝ x y + variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] -variable {s : ι → (x : B) → E x} {u : Set B} +variable {s : ι → (x : B) → E x} {u u' : Set B} + +variable (IB F n) in +structure IsOrthogonalFrameOn (s : ι → (x : B) → E x) (u : Set B) + extends IsLocalFrameOn IB F n s u where + /-- Any two distinct sections are point-wise orthogonal on `u`. -/ + orthogonal {i j : ι} {x : B} : i ≠ j → x ∈ u → ⟪s i x, s j x⟫ = 0 + +omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] + [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] in +lemma IsOrthogonalFrameOn.mono (hs : IsOrthogonalFrameOn IB F n s u) (huu' : u' ⊆ u) : + IsOrthogonalFrameOn IB F n s u' where + toIsLocalFrameOn := hs.toIsLocalFrameOn.mono huu' + orthogonal hij hx := hs.orthogonal hij (huu' hx) + +/-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ +def IsLocalFrameOn.gramSchmidt (hs : IsLocalFrameOn IB F n s u) : + IsLocalFrameOn IB F n (VectorBundle.gramSchmidt s) u where + linearIndependent := by + intro x hx + exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) + generating := by + intro x hx + sorry -- lemma about Gram-Schmidt... + contMDiffOn i := gramSchmidt_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| + fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective + +/-- Applying the Gram-Schmidt procedure to an orthogonal local frame yields +another orthogonal local frame. -/ +def IsOrthogonalFrameOn.gramSchmidt (hs : IsOrthogonalFrameOn IB F n s u) : + IsOrthogonalFrameOn IB F n (VectorBundle.gramSchmidt s) u where + toIsLocalFrameOn := hs.toIsLocalFrameOn.gramSchmidt + orthogonal {_ _ x} hij _hx := VectorBundle.gramSchmidt_orthogonal s hij x /-! # Determining smoothness of a section via its local frame coefficients @@ -54,6 +89,17 @@ See `LocalFrame.lean` for a similar statement, about local frames induced by a l on finite rank bundles over any complete field. -/ +-- The local frame coefficients take a particularly simple form in orthogonal frames. + +variable (t) in +lemma IsOrthogonalFrameOn.repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) + {x} (hx : x ∈ u) (i : ι) : + hs.toIsLocalFrameOn.repr i t x = inner ℝ (s i x) (t x) / (‖s i x‖ ^ 2) := by + -- should be a general lemma: orthogonal basis, have this identity + sorry + +-- deduce an inductive formula for all frame coefficients for any local frame + section smoothness namespace IsLocalFrameOn @@ -62,6 +108,20 @@ variable (hs : IsLocalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} set_option linter.style.commandStart false +-- include hs in +-- lemma aux (hx : x ∈ u) (i : ι) : +-- hs.repr i t x = inner ℝ (s i x) (t x) / (‖s i x‖ ^ 2) := by +-- -- is this actually true, without Gram-Schmidt-ing everything? +-- -- there is a version of this which is true (Gram-Schmidt, then it's obvious, then revert)... +-- -- which is more tedious to state! +-- sorry --hs.repr i t x = (inner ℝ (s i x) (t x)) / (‖s i x‖ ^ 2) • (s i x) := sorry + +-- -- better proof, assuming finiteness +-- -- let s' be the orthonormalised versions, then hs'.repr i t x is the coefficient of s' i in t +-- -- that coefficient is the scalar product we want, same for the other intermediate ones +-- -- then add up, get something with smoothness! + +-- XXX: only need one of these hypotheses! /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffAt_repr (hx : x ∈ u) (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : CMDiffAt n (hs.repr i t) x := by @@ -109,18 +169,6 @@ end IsLocalFrameOn end smoothness -/-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ -def IsLocalFrameOn.gramSchmidt (hs : IsLocalFrameOn IB F n s u) : - IsLocalFrameOn IB F n (VectorBundle.gramSchmidt s) u where - linearIndependent := by - intro x hx - exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) - generating := by - intro x hx - sorry -- lemma about Gram-Schmidt... - contMDiffOn i := gramSchmidt_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| - fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective - namespace Basis -- bad, for prototyping From 3346d9d0a75a6fbfa354bd3ede11816ad37dc6e4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 00:51:21 +0200 Subject: [PATCH 215/601] Is this a fine approach? --- .../Manifold/VectorBundle/OrthonormalFrame.lean | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index bdff30bc3ef12d..5d80f1c973035b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -67,7 +67,8 @@ def IsLocalFrameOn.gramSchmidt (hs : IsLocalFrameOn IB F n s u) : exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) generating := by intro x hx - sorry -- lemma about Gram-Schmidt... + simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] + using hs.generating hx contMDiffOn i := gramSchmidt_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective @@ -78,6 +79,7 @@ def IsOrthogonalFrameOn.gramSchmidt (hs : IsOrthogonalFrameOn IB F n s u) : toIsLocalFrameOn := hs.toIsLocalFrameOn.gramSchmidt orthogonal {_ _ x} hij _hx := VectorBundle.gramSchmidt_orthogonal s hij x + /-! # Determining smoothness of a section via its local frame coefficients We show that for any local frame `{s i}` on `u ⊆ B`, a section `t` is smooth on `u` if and only if @@ -100,6 +102,17 @@ lemma IsOrthogonalFrameOn.repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) -- deduce an inductive formula for all frame coefficients for any local frame +variable (t) in +lemma IsOrthogonalFrameOn.repr_eq (hs : IsLocalFrameOn IB F n s u) {x} (hx : x ∈ u) (i : ι) : + hs.repr i t x = sorry := by + -- normalise the sections s + let s' := VectorBundle.gramSchmidt s + have : hs.gramSchmidt.repr i t x = ⟪s' i x, t x⟫ / ‖s' i x‖ ^ 2 := by + apply IsOrthogonalFrameOn.repr_eq_inner _ ?_ hx i + sorry + -- write s' = s - ∑ ... and apply induction? is that sound? + sorry + section smoothness namespace IsLocalFrameOn From a1a7d5638e75c9474fa525d9273bde4adfef2090 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 11:24:30 +0200 Subject: [PATCH 216/601] feat: more basic API for local frames Prove that C^k coefficients imply a C^k section. --- .../Manifold/VectorBundle/LocalFrame.lean | 82 ++++++++++++++++--- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 0d5d16f2426f54..9d9da358bd283d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -87,7 +87,7 @@ section IsLocalFrame omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] -variable {ι : Type*} {s : ι → (x : M) → V x} {u u' : Set M} {x : M} {n : WithTop ℕ∞} +variable {ι : Type*} {s s' : ι → (x : M) → V x} {u u' : Set M} {x : M} {n : WithTop ℕ∞} variable (I F n) in /- @@ -102,6 +102,19 @@ structure IsLocalFrameOn (s : ι → (x : M) → V x) (u : Set M) where namespace IsLocalFrameOn +/-- If `s = s'` on `u` and `s i` is a local frame on `u`, then so is `s'`. -/ +lemma congr (hs : IsLocalFrameOn I F n s u) (hs' : ∀ i, ∀ x, x ∈ u → s i x = s' i x) : + IsLocalFrameOn I F n s' u where + linearIndependent := by + intro x hx + have := hs.linearIndependent hx + simp_all + generating := by + intro x hx + have := hs.generating hx + simp_all + contMDiffOn i := (hs.contMDiffOn i).congr fun y hy ↦ by simp [hs' i y hy] + lemma mono (hs : IsLocalFrameOn I F n s u) (hu'u : u' ⊆ u) : IsLocalFrameOn I F n s u' where linearIndependent := by intro x hx @@ -172,10 +185,60 @@ lemma repr_congr (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} congr · simp [repr, hxe] +/-- If `s` and `s'` are local frames which are equal at `x`, +a section `t` has equal frame coefficients in them. -/ +lemma repr_eq_of_eq (hs : IsLocalFrameOn I F n s u) (hs' : IsLocalFrameOn I F n s' u) {x} + (hss' : ∀ i, s i x = s' i x) {t : Π x : M, V x} (i : ι) : + hs.repr i t x = hs'.repr i t x := by + by_cases hxe : x ∈ u + · simp [repr, hxe] + simp_all [toBasisAt] + · simp [repr, hxe] + lemma repr_apply_zero_at (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} (ht : t x = 0) (i : ι) : hs.repr i t x = 0 := by simp [hs.repr_congr (t' := 0) ht] +variable (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} [VectorBundle 𝕜 F V] + +set_option linter.style.commandStart false + +/-- Given a local frame `s i ` on `u`, if a section `t` has `C^k` coefficients on `u` w.r.t. `s i`, +then `t` is `C^n` on `u`. -/ +lemma contMDiffOn_of_repr [Fintype ι] (h : ∀ i, CMDiff[u] n (hs.repr i t)) : + CMDiff[u] n (T% t) := by + have this (i) : CMDiff[u] n (T% (hs.repr i t • s i)) := + (h i).smul_section (hs.contMDiffOn i) + have almost : CMDiff[u] n (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) := + .sum_section fun i _ ↦ this i + apply almost.congr + intro y hy + simp [hs.repr_sum_eq t hy] + +/-- Given a local frame `s i` on `u`, if a section `t` has `C^k` coefficients at `x ∈ u` +w.r.t. `s i`, then `t` is `C^n` at `x`. -/ +lemma contMDiffAt_of_repr_aux [Fintype ι] + (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : IsOpen u) (hx : x ∈ u) : CMDiffAt n (T% t) x := by + have this (i) : CMDiffAt n (T% (hs.repr i t • s i)) x := + (h i).smul_section (hs.contMDiffAt hu hx i) + have almost : CMDiffAt n + (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := + .sum_section fun i _ ↦ this i + apply almost.congr_of_eventuallyEq ?_ + obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (hs.repr_spec (I := I) t hx hu) + exact Filter.eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] + +/-- Given a local frame `s i` on a neighbourhood `u` of `x`, +if a section `t` has `C^k` coefficients at `x` w.r.t. `s i`, then `t` is `C^n` at `x`. -/ +lemma contMDiffAt_of_repr [Fintype ι] + (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x := by + obtain ⟨u', hu'u, hu', hxu'⟩ := mem_nhds_iff.mp hu + apply (hs.mono hu'u).contMDiffAt_of_repr_aux (fun i ↦ ?_) hu' hxu' + apply (h i).congr_of_eventuallyEq <| eventually_of_mem (hu'.mem_nhds hxu') (fun x hx ↦ ?_) + simp [repr, hx, hu'u hx, toBasisAt] + +set_option linter.style.commandStart true + end IsLocalFrameOn end IsLocalFrame @@ -420,16 +483,10 @@ coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {x' : M} (hx : x' ∈ e.baseSet) : - CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_repr I e i s) x' := by - refine ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ - have this (i) : CMDiffAt k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) x' := - (hi i).smul_section (contMDiffAt_localFrame_of_mem k e b i hx) - have almost : CMDiffAt k - (T% (fun x ↦ ∑ i, (b.localFrame_repr I e i) s x • b.localFrame e i x)) x' := - .sum_section fun i _ ↦ this i - apply almost.congr_of_eventuallyEq ?_ - obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec (I := I) hx s) - exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] + CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_repr I e i s) x' := + ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, + fun hi ↦ (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_repr hi + (e.open_baseSet.mem_nhds hx)⟩ omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its @@ -445,8 +502,7 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i apply almost.congr intro y hy - congr - exact b.localFrame_repr_sum_eq s (ht' hy) + simpa using b.localFrame_repr_sum_eq s (ht' hy) omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its From a50bc0e5d482e3efb2961de8573ce52220e321e1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 14:03:00 +0200 Subject: [PATCH 217/601] chore(VectorBundle/MDifferentiable): fix some lemma names The mathlib PR has a full set of changes --- .../VectorBundle/MDifferentiable.lean | 38 +++++++++---------- .../Manifold/VectorBundle/Tensoriality.lean | 8 ++-- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index a7d02f49028507..374c912d92ac13 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -457,7 +457,7 @@ lemma mdifferentiable_sub_section MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) := fun x₀ ↦ mdifferentiableAt_sub_section (hs x₀) (ht x₀) -lemma mdifferentiableWithinAt_smul_section +lemma MDifferentiableWithinAt.smul_section (hf : MDifferentiableWithinAt I 𝓘(𝕜) f u x₀) (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by @@ -471,43 +471,43 @@ lemma mdifferentiableWithinAt_smul_section apply (e.linear 𝕜 hx).2 · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 -lemma mdifferentiableAt_smul_section (hf : MDifferentiableAt I 𝓘(𝕜) f x₀) +lemma MDifferentiableAt.smul_section (hf : MDifferentiableAt I 𝓘(𝕜) f x₀) (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by rw [← mdifferentiableWithinAt_univ] at hs ⊢ - exact mdifferentiableWithinAt_smul_section hf hs + exact .smul_section hf hs -lemma mdifferentiableOn_smul_section (hf : MDifferentiableOn I 𝓘(𝕜) f u) +lemma MDifferentiableOn.smul_section (hf : MDifferentiableOn I 𝓘(𝕜) f u) (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := - fun x₀ hx₀ ↦ mdifferentiableWithinAt_smul_section (hf x₀ hx₀) (hs x₀ hx₀) + fun x₀ hx₀ ↦ .smul_section (hf x₀ hx₀) (hs x₀ hx₀) lemma mdifferentiable_smul_section (hf : MDifferentiable I 𝓘(𝕜) f) (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) := - fun x₀ ↦ mdifferentiableAt_smul_section (hf x₀) (hs x₀) + fun x₀ ↦ (hf x₀).smul_section (hs x₀) lemma mdifferentiableWithinAt_smul_const_section (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := - mdifferentiableWithinAt_smul_section mdifferentiableWithinAt_const hs + .smul_section mdifferentiableWithinAt_const hs -lemma mdifferentiableAt_smul_const_section +lemma MDifferentiableAt.smul_const_section (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := - mdifferentiableAt_smul_section mdifferentiableAt_const hs + .smul_section mdifferentiableAt_const hs -lemma mdifferentiableOn_smul_const_section +lemma MDifferentiableOn.smul_const_section (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u := - mdifferentiableOn_smul_section mdifferentiableOn_const hs + .smul_section mdifferentiableOn_const hs lemma mdifferentiable_smul_const_section (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) := - fun x₀ ↦ mdifferentiableAt_smul_const_section (hs x₀) + fun x₀ ↦ (hs x₀).smul_const_section -lemma mdifferentiableWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} +lemma MDifferentiableWithinAt.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} (hs : ∀ i, MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) @@ -518,21 +518,21 @@ lemma mdifferentiableWithinAt_finsum_section {ι : Type*} {s : Finset ι} {t : | insert i s hi h => simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h -lemma mdifferentiableAt_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} {x₀ : B} +lemma MDifferentiableAt.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} {x₀ : B} (hs : ∀ i, MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by simp_rw [← mdifferentiableWithinAt_univ] at hs ⊢ - exact mdifferentiableWithinAt_finsum_section hs + exact MDifferentiableWithinAt.sum_section hs -lemma mdifferentiableOn_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} +lemma MDifferentiableOn.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} (hs : ∀ i, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u) : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := - fun x₀ hx₀ ↦ mdifferentiableWithinAt_finsum_section fun i ↦ hs i x₀ hx₀ + fun x₀ hx₀ ↦ .sum_section fun i ↦ hs i x₀ hx₀ -lemma mdifferentiable_finsum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} +lemma MDifferentiable.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} (hs : ∀ i, MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x))) : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := - fun x₀ ↦ mdifferentiableAt_finsum_section fun i ↦ (hs i) x₀ + fun x₀ ↦ .sum_section fun i ↦ (hs i) x₀ end operations diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index ed1d0436517f13..311d88047e3517 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -81,7 +81,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] | insert a s ha h => change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ simp [Finset.sum_insert ha, ← h] - exact φ_add _ _ (hσ a) (mdifferentiableAt_finsum_section hσ) + exact φ_add _ _ (hσ a) (.sum_section hσ) have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x @@ -97,7 +97,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by exact locality hσ - (mdifferentiableAt_finsum_section fun i ↦ mdifferentiableAt_smul_section (hc hσ i) (hs i)) + (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) (Basis.localFrame_repr_spec b x_mem σ) rw [hφ hσ, hφ hσ', sum_phi, sum_phi] · change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x @@ -105,8 +105,8 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] ext i rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i), Basis.localFrame_repr_congr b hσσ'] - · exact fun i ↦ mdifferentiableAt_smul_section (hc hσ' i) (hs i) - · exact fun i ↦ mdifferentiableAt_smul_section (hc hσ i) (hs i) + · exact fun i ↦ (hc hσ' i).smul_section (hs i) + · exact fun i ↦ (hc hσ i).smul_section (hs i) include I in omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in From 089ef7cef0145f20cb9e8fcae69d4df7218387d0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 14:32:56 +0200 Subject: [PATCH 218/601] chore(LocalFrame): generalise mdifferentiability lemmas also And golf some of the later proofs using it. --- .../Manifold/VectorBundle/LocalFrame.lean | 96 +++++++++++-------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 9d9da358bd283d..ff236129f1000f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -171,10 +171,9 @@ lemma repr_sum_eq [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V /-- A local frame locally spans the space of sections for `V`: for each local frame `s i` on an open set `u` around `x`, we have `t = ∑ i, (hs.repr i t) • (s i x)` near `x`. -/ -lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F n s u) - (t : Π x : M, V x) (hx : x ∈ u) (hu : IsOpen u) : +lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hu'' : u ∈ 𝓝 x) : ∀ᶠ x' in 𝓝 x, t x' = ∑ i, (hs.repr i t x') • (s i x') := - eventually_nhds_iff.mpr ⟨u, fun _ h ↦ hs.repr_sum_eq t h, hu, hx⟩ + eventually_of_mem hu'' fun _ hx ↦ hs.repr_sum_eq _ hx /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma repr_congr (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} @@ -215,27 +214,55 @@ lemma contMDiffOn_of_repr [Fintype ι] (h : ∀ i, CMDiff[u] n (hs.repr i t)) : intro y hy simp [hs.repr_sum_eq t hy] -/-- Given a local frame `s i` on `u`, if a section `t` has `C^k` coefficients at `x ∈ u` -w.r.t. `s i`, then `t` is `C^n` at `x`. -/ -lemma contMDiffAt_of_repr_aux [Fintype ι] - (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : IsOpen u) (hx : x ∈ u) : CMDiffAt n (T% t) x := by - have this (i) : CMDiffAt n (T% (hs.repr i t • s i)) x := - (h i).smul_section (hs.contMDiffAt hu hx i) - have almost : CMDiffAt n - (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := - .sum_section fun i _ ↦ this i - apply almost.congr_of_eventuallyEq ?_ - obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (hs.repr_spec (I := I) t hx hu) - exact Filter.eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] - /-- Given a local frame `s i` on a neighbourhood `u` of `x`, if a section `t` has `C^k` coefficients at `x` w.r.t. `s i`, then `t` is `C^n` at `x`. -/ lemma contMDiffAt_of_repr [Fintype ι] (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x := by - obtain ⟨u', hu'u, hu', hxu'⟩ := mem_nhds_iff.mp hu - apply (hs.mono hu'u).contMDiffAt_of_repr_aux (fun i ↦ ?_) hu' hxu' - apply (h i).congr_of_eventuallyEq <| eventually_of_mem (hu'.mem_nhds hxu') (fun x hx ↦ ?_) - simp [repr, hx, hu'u hx, toBasisAt] + have this (i) : CMDiffAt n (T% (hs.repr i t • s i)) x := + (h i).smul_section <| (hs.contMDiffOn i).contMDiffAt hu + have almost : CMDiffAt n + (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := .sum_section (fun i _ ↦ this i) + exact almost.congr_of_eventuallyEq <| (hs.repr_spec t hu).mono fun x h ↦ by simp [h] + +/-- Given a local frame `s i` on an open set `u` containing `x`, if a section `t` has `C^k` +coefficients at `x ∈ u` w.r.t. `s i`, then `t` is `C^n` at `x`. -/ +lemma contMDiffAt_of_repr_aux [Fintype ι] + (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : IsOpen u) (hx : x ∈ u) : CMDiffAt n (T% t) x := + hs.contMDiffAt_of_repr h (hu.mem_nhds hx) + +section + +variable (hs : IsLocalFrameOn I F 1 s u) + +/-- Given a local frame `s i ` on `u`, if a section `t` has differentiable coefficients on `u` +w.r.t. `s i`, then `t` is differentiable on `u`. -/ +lemma mdifferentiableOn_of_repr [Fintype ι] (h : ∀ i, MDiff[u] (hs.repr i t)) : + MDiff[u] (T% t) := by + have this (i) : MDiff[u] (T% (hs.repr i t • s i)) := + (h i).smul_section ((hs.contMDiffOn i).mdifferentiableOn le_rfl) + have almost : MDiff[u] (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) := + .sum_section (fun i _ hx ↦ this i _ hx) + apply almost.congr + intro y hy + simp [hs.repr_sum_eq t hy] + +/-- Given a local frame `s i` on a neighbourhood `u` of `x`, if a section `t` has differentiable +coefficients at `x` w.r.t. `s i`, then `t` is differentiable at `x`. -/ +lemma mdifferentiableAt_of_repr [Fintype ι] + (h : ∀ i, MDiffAt (hs.repr i t) x) (hu : u ∈ 𝓝 x) : MDiffAt (T% t) x := by + have this (i) : MDiffAt (T% (hs.repr i t • s i)) x := + (h i).smul_section <| ((hs.contMDiffOn i).mdifferentiableOn le_rfl).mdifferentiableAt hu + have almost : MDiffAt + (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := .sum_section (fun i ↦ this i) + exact almost.congr_of_eventuallyEq <| (hs.repr_spec t hu).mono fun x h ↦ by simp [h] + +/-- Given a local frame `s i` on open set `u` containing `x`, if a section `t` +has differentiable coefficients at `x ∈ u` w.r.t. `s i`, then `t` is differentiable at `x`. -/ +lemma mdifferentiableAt_of_repr_aux [Fintype ι] + (h : ∀ i, MDiffAt (hs.repr i t) x) (hu : IsOpen u) (hx : x ∈ u) : MDiffAt (T% t) x := + hs.mdifferentiableAt_of_repr h (hu.mem_nhds hx) + +end set_option linter.style.commandStart true @@ -496,6 +523,9 @@ lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [C {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_repr I e i s) := by refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ + -- TODO: golf this using the lemmas above + -- intro x hx + -- let aux := (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_repr (t := s) (x := x) have this (i) : CMDiff[t] k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' @@ -574,17 +604,9 @@ omit [IsManifold I 0 M] in coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ lemma mdifferentiableAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : - MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_repr I e i s) x' := by - refine ⟨fun h i ↦ mdifferentiableAt_localFrame_repr hx b h i, fun hi ↦ ?_⟩ - have this (i) : MDiffAt (T% (b.localFrame_repr I e i) s • b.localFrame e i) x' := - mdifferentiableAt_smul_section (hi i) - ((contMDiffAt_localFrame_of_mem 1 e b i hx).mdifferentiableAt le_rfl) - have almost : MDiffAt - (T% (fun x ↦ ∑ i, (b.localFrame_repr I e i) s x • b.localFrame e i x)) x' := - mdifferentiableAt_finsum_section fun i ↦ this i - apply almost.congr_of_eventuallyEq ?_ - obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (b.localFrame_repr_spec (I := I) hx s) - exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] + MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_repr I e i s) x' := + ⟨fun h i ↦ mdifferentiableAt_localFrame_repr hx b h i, fun hi ↦ + (b.localFrame_isLocalFrameOn_baseSet I 1 e).mdifferentiableAt_of_repr_aux hi e.open_baseSet hx⟩ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on `t ⊆ e.baseSet` iff each of its @@ -594,15 +616,9 @@ lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : MDiff[t] (T% s) ↔ ∀ i, MDiff[t] (b.localFrame_repr I e i s) := by refine ⟨fun h i ↦ mdifferentiableOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ - have this (i) : MDiff[t] (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := - mdifferentiableOn_smul_section (hi i) <| - ((b.contMDiffOn_localFrame_baseSet 1 e i).mono ht').mdifferentiableOn le_rfl - let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' - have almost : MDiff[t] (T% rhs) := mdifferentiableOn_finsum_section fun i ↦ this i - apply almost.congr - intro y hy - congr - exact b.localFrame_repr_sum_eq s (ht' hy) + apply ((b.localFrame_isLocalFrameOn_baseSet I 1 e).mono ht').mdifferentiableOn_of_repr (t := s) + convert hi + sorry -- should be easy/already done above omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its From 79dcd96acd7fcdfb57907b4baa0ea04ece55184d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 15:59:57 +0200 Subject: [PATCH 219/601] feat: prove smoothness iff in frame coefficients for orthogonal frames Except for some pesky lemmas about smooth pairings, which I already proven for Gram-Schmidt; let me dig those up next. --- .../Manifold/VectorBundle/LocalFrame.lean | 1 - .../VectorBundle/OrthonormalFrame.lean | 181 +++++++++--------- 2 files changed, 89 insertions(+), 93 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index ff236129f1000f..ebb8c6583e78d9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -421,7 +421,6 @@ omit [IsManifold I 0 M] in lemma localFrame_repr_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : b.localFrame_repr I e i s x = 0 := by - --rw [b.localFrame_repr_congr (s' := 0) (by simp [hs])] simp only [localFrame_repr] exact (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_apply_zero_at hs i diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 5d80f1c973035b..5cdc14616270d2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -82,103 +82,111 @@ def IsOrthogonalFrameOn.gramSchmidt (hs : IsOrthogonalFrameOn IB F n s u) : /-! # Determining smoothness of a section via its local frame coefficients -We show that for any local frame `{s i}` on `u ⊆ B`, a section `t` is smooth on `u` if and only if -its coefficients in `{s i}` are. This argument crucially depends on the existence of a smooth -bundle metric on `V` (which always holds in finite dimensions, and in certain important +We show that for any orthogonal local frame `{s i}` on `u ⊆ B`, a section `t` is smooth on `u` +if and only if its coefficients in `{s i}` are. This argument crucially depends on the existence of +a smooth bundle metric on `V` (which always holds in finite dimensions, and in certain important infinite-dimensional cases). See `LocalFrame.lean` for a similar statement, about local frames induced by a local trivialisation on finite rank bundles over any complete field. --/ - --- The local frame coefficients take a particularly simple form in orthogonal frames. - -variable (t) in -lemma IsOrthogonalFrameOn.repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) - {x} (hx : x ∈ u) (i : ι) : - hs.toIsLocalFrameOn.repr i t x = inner ℝ (s i x) (t x) / (‖s i x‖ ^ 2) := by - -- should be a general lemma: orthogonal basis, have this identity - sorry - --- deduce an inductive formula for all frame coefficients for any local frame -variable (t) in -lemma IsOrthogonalFrameOn.repr_eq (hs : IsLocalFrameOn IB F n s u) {x} (hx : x ∈ u) (i : ι) : - hs.repr i t x = sorry := by - -- normalise the sections s - let s' := VectorBundle.gramSchmidt s - have : hs.gramSchmidt.repr i t x = ⟪s' i x, t x⟫ / ‖s' i x‖ ^ 2 := by - apply IsOrthogonalFrameOn.repr_eq_inner _ ?_ hx i - sorry - -- write s' = s - ∑ ... and apply induction? is that sound? - sorry +The orthogonality requirement can be removed, with additional technical effort: see the comment +below for details. It simplifies the proofs as the local frame coefficients take a particularly +simple form in orthgonal frames. +-/ section smoothness -namespace IsLocalFrameOn +namespace IsOrthogonalFrameOn -variable (hs : IsLocalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} +variable (hs : IsOrthogonalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} set_option linter.style.commandStart false --- include hs in --- lemma aux (hx : x ∈ u) (i : ι) : --- hs.repr i t x = inner ℝ (s i x) (t x) / (‖s i x‖ ^ 2) := by --- -- is this actually true, without Gram-Schmidt-ing everything? --- -- there is a version of this which is true (Gram-Schmidt, then it's obvious, then revert)... --- -- which is more tedious to state! --- sorry --hs.repr i t x = (inner ℝ (s i x) (t x)) / (‖s i x‖ ^ 2) • (s i x) := sorry +variable (t) in +lemma repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) + {x} (hx : x ∈ u) (i : ι) : + hs.repr i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by + -- should be a general lemma: orthogonal basis, have this identity + sorry --- -- better proof, assuming finiteness --- -- let s' be the orthonormalised versions, then hs'.repr i t x is the coefficient of s' i in t --- -- that coefficient is the scalar product we want, same for the other intermediate ones --- -- then add up, get something with smoothness! +/-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ +lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : + CMDiffAt[u] n (hs.repr i t) x := by + have aux : CMDiffAt[u] n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by + refine ContMDiffWithinAt.smul ?_ ?_ + · sorry -- same for Gram-Schmidt + refine ContMDiffWithinAt.inv₀ ?_ ?_ + · sorry -- likewise + have : s i x ≠ 0 := by + have := hs.linearIndependent hx + sorry -- lemma: linearly independent => all non-zero + simp [this] + exact aux.congr_of_mem (fun y hy ↦ hs.repr_eq_inner _ hy _) hx --- XXX: only need one of these hypotheses! /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ -lemma contMDiffAt_repr (hx : x ∈ u) (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : +lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : CMDiffAt n (hs.repr i t) x := by - sorry - -/-- If `{s i}` is a local frame on `u` and `t` is `C^k` on `u`, -so is its coefficient in the local frame `s i` -/ -lemma contMDiffOn_repr - (hu : IsOpen u) (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.repr i t) := by - intro x' hx - apply ContMDiffAt.contMDiffWithinAt - apply hs.contMDiffAt_repr hx (hu.mem_nhds hx) (ht.contMDiffAt <| hu.mem_nhds hx) - -/-- A section `s` of `V` is `C^k` at `x ∈ u` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma _root_.contMDiffAt_iff_isLocalFrameOn_repr --[Fintype ι] - (hx : x ∈ u) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.repr i t) x := by - refine ⟨fun h i ↦ hs.contMDiffAt_repr hx sorry/-hu-/ h i, fun hi ↦ ?_⟩ - sorry /-have this (i) : CMDiffAt n (T% (hs.repr i t • s i)) x := - (hi i).smul_section (hs.contMDiffAt sorry/-hu-/ hx i) - have almost : CMDiffAt n - (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := - .sum_section fun i _ ↦ this i - apply almost.congr_of_eventuallyEq ?_ - obtain ⟨u, heq, hu, hxu⟩ := eventually_nhds_iff.mp (hs.repr_spec (I := I) t hx sorry) - exact eventually_of_mem (hu.mem_nhds hxu) fun x hx ↦ by simp [heq x hx] -/ - --- omit [IsManifold I 0 M] in -/-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ + sorry -- easy... + -- have aux : CMDiffAt n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by + -- refine ContMDiffAt.smul ?_ ?_ + -- · sorry -- same for Gram-Schmidt + -- refine ContMDiffAt.inv₀ ?_ ?_ + -- · sorry --refine ContMDiffAt.smul ?_ ?_ + -- · have : s i x ≠ 0 := by + -- have := hs.linearIndependent (x := x) (mem_of_mem_nhds hu) + -- sorry -- lemma: linearly independent => all non-zero + -- simp [this] + -- apply aux.congr_of_eventuallyEq + -- apply Filter.eventually_of_mem hu fun y hy ↦ hs.repr_eq_inner t hy i + +-- Future: prove the same result for all local frames +-- if `{s i}` is a local frame on `u`, and `{s' i}` are the corresponding orthogonalised frame, +-- for each `x ∈ u` the vectors `{s i x}` and `{s' i x}` are bases of `E x`, +-- and the coefficients w.r.t. `s i` and `s' i x` are related by the base change matrix. +-- This matrix depends smoothly on `x`, hence the frame coefficients w.r.t. `{s i}` are smooth iff +-- those w.r.t. `{s' i}` are. + +/-- If `{s i}` is an orthogonal local frame on a neighbourhood `u` of `x` and `t` is `C^k` on `u`, +so is its coefficient in the frame `{s i}`. -/ +lemma contMDiffOn_repr (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.repr i t) := + fun x' hx ↦ hs.contMDiffWithinAt_repr (ht x' hx) hx _ + +/-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal +local frame near `x` is. -/ +lemma contMDiffAt_iff_repr [Fintype ι] + (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.repr i t) x := + ⟨fun h i ↦ hs.contMDiffAt_repr hu h i, fun h ↦ hs.contMDiffAt_of_repr h hu⟩ + +/-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff +each of its coefficients `hs.repr i s` w.r.t. the local frame `{s i}` is. -/ lemma contMDiffOn_iff_repr [Fintype ι] : - CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.repr i t) := by --- refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ --- have this (i) : CMDiff[t] k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := --- (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') --- let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' --- have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i --- apply almost.congr --- intro y hy --- congr --- exact b.localFrame_repr_sum_eq s (ht' hy) - sorry - -end IsLocalFrameOn + CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.repr i t) := + ⟨fun h i ↦ hs.contMDiffOn_repr h i, fun hi ↦ hs.contMDiffOn_of_repr hi⟩ + +-- unused, just stating for convenience/nice API +include hs in +lemma contMDiffAt_iff_repr' [Fintype ι] + (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫) x := by + trans ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫/ (‖s i x‖ ^ 2)) x + · rw [hs.contMDiffAt_iff_repr hu] + have (i : ι) := Filter.eventually_of_mem hu fun x hx ↦ (hs.repr_eq_inner t hx i) + exact ⟨fun h i ↦ (h i).congr_of_eventuallyEq <| Filter.EventuallyEq.symm (this i), + fun h i ↦ (h i).congr_of_eventuallyEq (this i)⟩ + · peel with i + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · sorry -- similar to other direction below + · apply h.smul + refine ContMDiffAt.inv₀ ?_ ?_ + · sorry -- rewrite ‖ ‖² = ⟨s, s⟩ + · sorry -- neq 0 + +-- unused, just stating for convenience/nice API +lemma contMDiffOn_iff_repr' [Fintype ι] : + CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (fun x ↦ ⟪s i x, t x⟫) := + sorry -- similar to the above lemma + +end IsOrthogonalFrameOn end smoothness @@ -234,15 +242,4 @@ lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : end Basis -/- next steps: - -lemma: local frame coefficients (in the same way), -a section is C^k iff its coefficients are -(prove for IsLocalFrameOn first!) - -lemma: frame coefficient of s_i is the product with that local section - (only true here, by orthogonality) - -cor: section t is smooth iff each product is (just rewrite twice) - -lemma: uniqueness (what I need for torsion) -/ +/- next lemma: uniqueness (what I need for torsion) -/ From 1bbf98225c31090e6b45ac55fd8f85a2509b52d4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 16:39:48 +0200 Subject: [PATCH 220/601] chore: extract a helper lemma for further use --- .../VectorBundle/GramSchmidtOrtho.lean | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index e224df8d0b4ab7..b2c8217795ba9d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -216,19 +216,25 @@ set_option linter.style.commandStart false variable [IsContMDiffRiemannianBundle IB n F E] +-- TODO: give a much better name! +lemma contMDiffWithinAt_aux {s t : (x : B) → E x} {u : Set B} {x : B} + (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : + CMDiffAt[u] n (fun x ↦ ⟪s x, t x⟫ / (‖s x‖ ^ 2)) x := by + suffices ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (fun x ↦ ⟪s x, t x⟫ / ⟪s x, s x⟫) u x by + apply this.congr + · intro y hy + simp [inner_self_eq_norm_sq_to_K] + · congr + rw [← real_inner_self_eq_norm_sq] + exact (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) + def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).orthogonalProjection (t x); CMDiffAt[u] n (T% S) x := by simp_rw [Submodule.orthogonalProjection_singleton] - apply ContMDiffWithinAt.smul_section ?_ hs - suffices ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (fun x ↦ ⟪s x, t x⟫ / ⟪s x, s x⟫) u x by - apply this.congr - · intro y hy - rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K] - · rw [RCLike.ofReal_pow, ← inner_self_eq_norm_sq_to_K] - exact (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) + exact (contMDiffWithinAt_aux hs ht hs').smul_section hs lemma gramSchmidt_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : Set B} {x : B} (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) From 1e0c5d4e1cc43cf9e99238ba1a478cf88eb31445 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 16:55:41 +0200 Subject: [PATCH 221/601] chore: solve the Gram-Schmidt sorries --- .../VectorBundle/GramSchmidtOrtho.lean | 6 ++++ .../VectorBundle/OrthonormalFrame.lean | 29 ++++++------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index b2c8217795ba9d..5c36403c102e0c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -228,6 +228,12 @@ lemma contMDiffWithinAt_aux {s t : (x : B) → E x} {u : Set B} {x : B} rw [← real_inner_self_eq_norm_sq] exact (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) +lemma contMDiffAt_aux {s t : (x : B) → E x} {x : B} + (hs : CMDiffAt n (T% s) x) (ht : CMDiffAt n (T% t) x) (hs' : s x ≠ 0) : + CMDiffAt n (fun x ↦ ⟪s x, t x⟫ / (‖s x‖ ^ 2)) x := by + rw [← contMDiffWithinAt_univ] at hs ht ⊢ + exact contMDiffWithinAt_aux hs ht hs' + def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 5cdc14616270d2..ed845e7fe51cbe 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -114,31 +114,20 @@ lemma repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : CMDiffAt[u] n (hs.repr i t) x := by have aux : CMDiffAt[u] n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by - refine ContMDiffWithinAt.smul ?_ ?_ - · sorry -- same for Gram-Schmidt - refine ContMDiffWithinAt.inv₀ ?_ ?_ - · sorry -- likewise - have : s i x ≠ 0 := by - have := hs.linearIndependent hx - sorry -- lemma: linearly independent => all non-zero - simp [this] + apply contMDiffWithinAt_aux ((hs.contMDiffOn i) x hx) ht + have := hs.linearIndependent hx + sorry exact aux.congr_of_mem (fun y hy ↦ hs.repr_eq_inner _ hy _) hx /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : CMDiffAt n (hs.repr i t) x := by - sorry -- easy... - -- have aux : CMDiffAt n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by - -- refine ContMDiffAt.smul ?_ ?_ - -- · sorry -- same for Gram-Schmidt - -- refine ContMDiffAt.inv₀ ?_ ?_ - -- · sorry --refine ContMDiffAt.smul ?_ ?_ - -- · have : s i x ≠ 0 := by - -- have := hs.linearIndependent (x := x) (mem_of_mem_nhds hu) - -- sorry -- lemma: linearly independent => all non-zero - -- simp [this] - -- apply aux.congr_of_eventuallyEq - -- apply Filter.eventually_of_mem hu fun y hy ↦ hs.repr_eq_inner t hy i + have aux : CMDiffAt n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by + apply contMDiffAt_aux ((hs.contMDiffOn i).contMDiffAt hu) ht + have := hs.linearIndependent (mem_of_mem_nhds hu) + sorry + exact aux.congr_of_eventuallyEq <| + Filter.eventually_of_mem hu fun x hx ↦ hs.repr_eq_inner _ hx _ -- Future: prove the same result for all local frames -- if `{s i}` is a local frame on `u`, and `{s' i}` are the corresponding orthogonalised frame, From 8f9549e8b8317d4714d949c0b487302f940e8a12 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 17:03:24 +0200 Subject: [PATCH 222/601] Two more sorries --- .../Manifold/VectorBundle/OrthonormalFrame.lean | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index ed845e7fe51cbe..e123018cc65773 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -113,19 +113,16 @@ lemma repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : CMDiffAt[u] n (hs.repr i t) x := by - have aux : CMDiffAt[u] n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by - apply contMDiffWithinAt_aux ((hs.contMDiffOn i) x hx) ht - have := hs.linearIndependent hx - sorry + have aux : CMDiffAt[u] n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := + contMDiffWithinAt_aux ((hs.contMDiffOn i) x hx) ht <| (hs.linearIndependent hx).ne_zero _ exact aux.congr_of_mem (fun y hy ↦ hs.repr_eq_inner _ hy _) hx /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : CMDiffAt n (hs.repr i t) x := by - have aux : CMDiffAt n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := by - apply contMDiffAt_aux ((hs.contMDiffOn i).contMDiffAt hu) ht - have := hs.linearIndependent (mem_of_mem_nhds hu) - sorry + have aux : CMDiffAt n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := + contMDiffAt_aux ((hs.contMDiffOn i).contMDiffAt hu) ht <| + (hs.linearIndependent (mem_of_mem_nhds hu)).ne_zero _ exact aux.congr_of_eventuallyEq <| Filter.eventually_of_mem hu fun x hx ↦ hs.repr_eq_inner _ hx _ From 3ba2f74bf2fd0542eb1846439b2ace4c8ed692a8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 17:15:16 +0200 Subject: [PATCH 223/601] chore(GramSchmidtOrtho): namespace the remaining file --- Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 10599b5ae56b54..6f114b67fc9c09 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -221,12 +221,6 @@ theorem gramSchmidt_linearIndependent {f : ι → E} (h₀ : LinearIndependent linearIndependent_of_ne_zero_of_inner_eq_zero (fun _ => gramSchmidt_ne_zero _ h₀) fun _ _ => gramSchmidt_orthogonal 𝕜 f -end InnerProductSpace - -open InnerProductSpace - -variable {𝕜} - /-- When given a basis, `gramSchmidt` produces a basis. -/ noncomputable def gramSchmidtBasis (b : Basis ι 𝕜 E) : Basis ι 𝕜 E := Basis.mk (gramSchmidt_linearIndependent b.linearIndependent) @@ -364,3 +358,5 @@ theorem gramSchmidtOrthonormalBasis_det [DecidableEq ι] : exact ((gramSchmidtOrthonormalBasis h f).repr_apply_apply (f _) _).symm end OrthonormalBasis + +end InnerProductSpace From aa4291e1a246d0c637e726987ab35523d6f894f5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 17:16:49 +0200 Subject: [PATCH 224/601] fix: rename two misnamed lemmas --- .../InnerProductSpace/GramSchmidtOrtho.lean | 13 +++++++++---- Mathlib/Analysis/InnerProductSpace/Orientation.lean | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 6f114b67fc9c09..1721e2c3c0fdb1 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -252,7 +252,7 @@ theorem gramSchmidtNormed_unit_length' {f : ι → E} {n : ι} (hn : gramSchmidt /-- **Gram-Schmidt Orthonormalization**: `gramSchmidtNormed` applied to a linearly independent set of vectors produces an orthornormal system of vectors. -/ -theorem gramSchmidt_orthonormal {f : ι → E} (h₀ : LinearIndependent 𝕜 f) : +theorem gramSchmidtNormed_orthonormal {f : ι → E} (h₀ : LinearIndependent 𝕜 f) : Orthonormal 𝕜 (gramSchmidtNormed 𝕜 f) := by unfold Orthonormal constructor @@ -263,16 +263,21 @@ theorem gramSchmidt_orthonormal {f : ι → E} (h₀ : LinearIndependent 𝕜 f) repeat' right exact gramSchmidt_orthogonal 𝕜 f hij +@[deprecated (since := "2025-07-10")] alias gramSchmidt_orthonormal := gramSchmidtNormed_orthonormal + /-- **Gram-Schmidt Orthonormalization**: `gramSchmidtNormed` produces an orthornormal system of vectors after removing the vectors which become zero in the process. -/ -theorem gramSchmidt_orthonormal' (f : ι → E) : +theorem gramSchmidtNormed_orthonormal' (f : ι → E) : Orthonormal 𝕜 fun i : { i | gramSchmidtNormed 𝕜 f i ≠ 0 } => gramSchmidtNormed 𝕜 f i := by refine ⟨fun i => gramSchmidtNormed_unit_length' i.prop, ?_⟩ rintro i j (hij : ¬_) rw [Subtype.ext_iff] at hij simp [gramSchmidtNormed, inner_smul_left, inner_smul_right, gramSchmidt_orthogonal 𝕜 f hij] +@[deprecated (since := "2025-07-10")] +alias gramSchmidt_orthonormal' := gramSchmidtNormed_orthonormal' + open Submodule Set Order theorem span_gramSchmidtNormed (f : ι → E) (s : Set ι) : @@ -300,12 +305,12 @@ size of the index set is the dimension of `E`, produce an orthonormal basis for with the orthonormal set produced by the Gram-Schmidt orthonormalization process on the elements of `ι` for which this process gives a nonzero number. -/ noncomputable def gramSchmidtOrthonormalBasis : OrthonormalBasis ι 𝕜 E := - ((gramSchmidt_orthonormal' f).exists_orthonormalBasis_extension_of_card_eq + ((gramSchmidtNormed_orthonormal' f).exists_orthonormalBasis_extension_of_card_eq (v := gramSchmidtNormed 𝕜 f) h).choose theorem gramSchmidtOrthonormalBasis_apply {f : ι → E} {i : ι} (hi : gramSchmidtNormed 𝕜 f i ≠ 0) : gramSchmidtOrthonormalBasis h f i = gramSchmidtNormed 𝕜 f i := - ((gramSchmidt_orthonormal' f).exists_orthonormalBasis_extension_of_card_eq + ((gramSchmidtNormed_orthonormal' f).exists_orthonormalBasis_extension_of_card_eq (v := gramSchmidtNormed 𝕜 f) h).choose_spec i hi theorem gramSchmidtOrthonormalBasis_apply_of_orthogonal {f : ι → E} diff --git a/Mathlib/Analysis/InnerProductSpace/Orientation.lean b/Mathlib/Analysis/InnerProductSpace/Orientation.lean index 21eed46b7a3ee5..0d229041a933ac 100644 --- a/Mathlib/Analysis/InnerProductSpace/Orientation.lean +++ b/Mathlib/Analysis/InnerProductSpace/Orientation.lean @@ -38,7 +38,7 @@ noncomputable section variable {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] -open Module +open Module InnerProductSpace open scoped RealInnerProductSpace From 5f5377d8846c87393cea1484445831b841330ad5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 17:36:03 +0200 Subject: [PATCH 225/601] WIP: add normalised Gram-Schmidt on vector bundles And fix doc-strings which were mis-copy-pasted. --- .../VectorBundle/GramSchmidtOrtho.lean | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 5c36403c102e0c..92e6e222ab2940 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -106,8 +106,8 @@ theorem gramSchmidt_zero (n : ι) : gramSchmidt (0 : ι → (x : B) → E x) n = simpa using InnerProductSpace.gramSchmidt_zero .. variable (s) in -/-- **Gram-Schmidt Orthogonalisation**: -`gramSchmidt` produces an orthogonal system of vectors. -/ +/-- **Gram-Schmidt Orthogonalisation**: `gramSchmidt` produces a point-wise orthogonal system +of sections. -/ theorem gramSchmidt_orthogonal {a b : ι} (h₀ : a ≠ b) (x) : ⟪gramSchmidt s a x, gramSchmidt s b x⟫ = 0 := InnerProductSpace.gramSchmidt_orthogonal _ _ h₀ @@ -146,7 +146,7 @@ theorem span_gramSchmidt_Iio (c : ι) (x) : InnerProductSpace.span_gramSchmidt_Iio _ _ _ -- variable (s) in --- /-- `gramSchmidt` preserves span of vectors. -/ +-- /-- `gramSchmidt` preserves the point-wise span of sections. -/ -- theorem span_gramSchmidt (x) : span ℝ (range (gramSchmidt ℝ (s · x))) = span ℝ (range (s · x)) := -- span_eq_span (range_subset_iff.2 fun _ ↦ -- span_mono (image_subset_range _ _) <| gramSchmidt_mem_span _ _ le_rfl) <| @@ -177,8 +177,8 @@ theorem gramSchmidt_ne_zero_coe (n : ι) (x) InnerProductSpace.gramSchmidt_ne_zero_coe _ h₀ variable (s) in -/-- If the input vectors of `gramSchmidt` are linearly independent, -then the output vectors are non-zero. -/ +/-- If the input sections of `gramSchmidt` are point-wise linearly independent, +the resulting sections are non-zero. -/ theorem gramSchmidt_ne_zero (n : ι) {x} (h₀ : LinearIndependent ℝ (s · x)) : gramSchmidt s n x ≠ 0 := InnerProductSpace.gramSchmidt_ne_zero _ h₀ @@ -186,7 +186,8 @@ theorem gramSchmidt_ne_zero (n : ι) {x} (h₀ : LinearIndependent ℝ (s · x)) -- not needed at the moment: I want a point-wise version, along the lines -- "if s i x is a basis, then gramSchmidt s i x is a triangular matrix" /- -/-- `gramSchmidt` produces a triangular matrix of vectors when given a basis. -/ +/-- At each point, when given a basis, `gramSchmidt` produces a triangular matrix of section +values. -/ theorem gramSchmidt_triangular {x} {i j : ι} (hij : i < j) (b : Basis ι ℝ (E x)) : b.repr (gramSchmidt b i x) j = 0 := sorry b.repr (gramSchmidt b i) j = 0 := by @@ -197,11 +198,55 @@ theorem gramSchmidt_triangular {x} {i j : ι} (hij : i < j) (b : Basis ι ℝ (E Basis.repr_support_subset_of_mem_span b (Set.Iio j) this exact (Finsupp.mem_supported' _ _).1 ((Finsupp.mem_supported ℝ _).2 this) j Set.notMem_Iio_self-/ -/-- `gramSchmidt` produces linearly independent vectors when given linearly independent vectors. -/ +/-- `gramSchmidt` produces point-wise linearly independent sections when given linearly +independent sections. -/ theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x)) : LinearIndependent ℝ (gramSchmidt s · x) := InnerProductSpace.gramSchmidt_linearIndependent h₀ +noncomputable def gramSchmidtNormed [WellFoundedLT ι] + (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ + InnerProductSpace.gramSchmidtNormed ℝ (s · x) n + +variable {x} + +theorem gramSchmidtNormed_unit_length_coe (n : ι) + (h₀ : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι))) : + ‖gramSchmidtNormed s n x‖ = 1 := + InnerProductSpace.gramSchmidtNormed_unit_length_coe n h₀ + +theorem gramSchmidtNormed_unit_length (n : ι) (h₀ : LinearIndependent ℝ (s · x)) : + ‖gramSchmidtNormed s n x‖ = 1 := + InnerProductSpace.gramSchmidtNormed_unit_length n h₀ + +theorem gramSchmidtNormed_unit_length' {n : ι} (hn : gramSchmidtNormed s n x ≠ 0) : + ‖gramSchmidtNormed s n x‖ = 1 := + InnerProductSpace.gramSchmidtNormed_unit_length' hn + +/-- **Gram-Schmidt Orthonormalization**: `gramSchmidtNormed` applied to a point-wise linearly +independent set of sections produces a point-wise orthornormal system of sections. -/ +theorem gramSchmidtNormed_orthonormal (h₀ : LinearIndependent ℝ (s · x)) : + Orthonormal ℝ (gramSchmidtNormed s · x) := + InnerProductSpace.gramSchmidtNormed_orthonormal h₀ + +variable (s) in +/-- **Gram-Schmidt Orthonormalization**: `gramSchmidtNormed` produces a point-wise orthornormal +system of sections after removing the sections which become zero in the process. -/ +theorem gramSchmidtNormed_orthonormal' (x) : + Orthonormal ℝ fun i : { i | gramSchmidtNormed s i x ≠ 0 } => gramSchmidtNormed s i x := + InnerProductSpace.gramSchmidtNormed_orthonormal' _ + +open Submodule Set Order + +-- Statement needs to be changed a bit to make it type-check. +-- variable (s) in +-- theorem span_gramSchmidtNormed (t : Set ι) : +-- span ℝ (gramSchmidtNormed s '' t) = span ℝ (gramSchmidt s '' t) := sorry + +-- theorem span_gramSchmidtNormed_range (f : ι → E) : +-- span 𝕜 (range (gramSchmidtNormed 𝕜 f)) = span 𝕜 (range (gramSchmidt 𝕜 f)) := by +-- simpa only [image_univ.symm] using span_gramSchmidtNormed f univ + end VectorBundle -- When given a local frame, this produces an orthonormal local frame... From ed521afab4790a88526ed39d6bf3f8402d55ab11 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 19:13:46 +0200 Subject: [PATCH 226/601] Almost done proving smoothness for normalised Gram-Schmidt --- .../VectorBundle/GramSchmidtOrtho.lean | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 92e6e222ab2940..33e33d84e3ecb9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -208,6 +208,10 @@ noncomputable def gramSchmidtNormed [WellFoundedLT ι] (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ InnerProductSpace.gramSchmidtNormed ℝ (s · x) n +lemma gramSchmidtNormed_coe {n : ι} {x} : + gramSchmidtNormed s n x = ‖gramSchmidt s n x‖⁻¹ • gramSchmidt s n x := by + simp [gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed] + variable {x} theorem gramSchmidtNormed_unit_length_coe (n : ι) @@ -324,3 +328,50 @@ lemma gramSchmidt_contMDiff {s : ι → (x : B) → E x} (i : ι) (hs' : ∀ x, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff n (T% (VectorBundle.gramSchmidt s i)) := fun x ↦ gramSchmidt_contMDiffAt _ (fun i ↦ hs i x) (hs' x) + +lemma gramSchmidtNormed_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : Set B} {x : B} + (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) + (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : + CMDiffAt[u] n (T% (VectorBundle.gramSchmidtNormed s i)) x := by + have : CMDiffAt[u] n (T% + (fun x ↦ ‖VectorBundle.gramSchmidt s i x‖⁻¹ • VectorBundle.gramSchmidt s i x)) x := by + refine ContMDiffWithinAt.smul_section ?_ (gramSchmidt_contMDiffWithinAt i hs hs') + refine ContMDiffWithinAt.inv₀ ?_ ?_ + · let F (x) := ⟪VectorBundle.gramSchmidt s i x, VectorBundle.gramSchmidt s i x⟫ + have aux : ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (Real.sqrt ∘ F) u x := by + have h1 : CMDiffAt[(F '' u)] n (Real.sqrt) + ⟪VectorBundle.gramSchmidt s i x, VectorBundle.gramSchmidt s i x⟫ := by + apply ContMDiffAt.contMDiffWithinAt + rw [contMDiffAt_iff_contDiffAt] + apply Real.contDiffAt_sqrt + simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' + have h2 : CMDiffAt[u] n F x := by + unfold F + -- have : CMDiffAt[u] n (T% (fun x ↦ VectorBundle.gramSchmidt s i x)) x := by + -- sorry -- did this already + sorry --apply this.inner_bundle this + exact h1.comp x (h2) (Set.mapsTo_image _ u) + apply aux.congr + · intro x hx + sorry + sorry + simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' + exact this.congr (fun y hy ↦ by congr) (by congr) + +lemma gramSchmidtNormed_contMDiffAt {s : ι → (x : B) → E x} (i : ι) {x : B} + (hs : ∀ i, CMDiffAt n (T% (s i)) x) + (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) + : CMDiffAt n (T% (VectorBundle.gramSchmidtNormed s i)) x := + contMDiffWithinAt_univ.mpr <| gramSchmidtNormed_contMDiffWithinAt _ (fun i ↦ hs i) hs' + +lemma gramSchmidtNormed_contMDiffOn {s : ι → (x : B) → E x} (i : ι) (u : Set B) + (hs : ∀ i, CMDiff[u] n (T% (s i))) + (hs' : ∀ x ∈ u, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : + CMDiff[u] n (T% (VectorBundle.gramSchmidtNormed s i)) := + fun x hx ↦ gramSchmidtNormed_contMDiffWithinAt _ (fun i ↦ hs i x hx) (hs' _ hx) + +lemma gramSchmidtNormed_contMDiff {s : ι → (x : B) → E x} (i : ι) + (hs : ∀ i, CMDiff n (T% (s i))) + (hs' : ∀ x, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : + CMDiff n (T% (VectorBundle.gramSchmidtNormed s i)) := + fun x ↦ gramSchmidtNormed_contMDiffAt _ (fun i ↦ hs i x) (hs' x) From 294421da778e2c2653aa14789ef830397c677f1a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 19:32:15 +0200 Subject: [PATCH 227/601] wip: use normalised Gram-Schmidt to normalised local frames --- .../VectorBundle/OrthonormalFrame.lean | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index e123018cc65773..1ef1ace7274c34 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -46,38 +46,41 @@ variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT variable {s : ι → (x : B) → E x} {u u' : Set B} variable (IB F n) in -structure IsOrthogonalFrameOn (s : ι → (x : B) → E x) (u : Set B) +structure IsOrthonormalFrameOn (s : ι → (x : B) → E x) (u : Set B) extends IsLocalFrameOn IB F n s u where /-- Any two distinct sections are point-wise orthogonal on `u`. -/ orthogonal {i j : ι} {x : B} : i ≠ j → x ∈ u → ⟪s i x, s j x⟫ = 0 + normalised {i : ι} {x : B} : x ∈ u → ‖s i x‖ = 1 omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] in -lemma IsOrthogonalFrameOn.mono (hs : IsOrthogonalFrameOn IB F n s u) (huu' : u' ⊆ u) : - IsOrthogonalFrameOn IB F n s u' where +lemma IsOrthonormalFrameOn.mono (hs : IsOrthonormalFrameOn IB F n s u) (huu' : u' ⊆ u) : + IsOrthonormalFrameOn IB F n s u' where toIsLocalFrameOn := hs.toIsLocalFrameOn.mono huu' orthogonal hij hx := hs.orthogonal hij (huu' hx) + normalised hx := hs.normalised (huu' hx) /-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ -def IsLocalFrameOn.gramSchmidt (hs : IsLocalFrameOn IB F n s u) : - IsLocalFrameOn IB F n (VectorBundle.gramSchmidt s) u where +def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : + IsLocalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where linearIndependent := by intro x hx - exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) + sorry -- exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) generating := by intro x hx - simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] - using hs.generating hx - contMDiffOn i := gramSchmidt_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| + sorry -- simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] + -- using hs.generating hx + contMDiffOn i := gramSchmidtNormed_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective -/-- Applying the Gram-Schmidt procedure to an orthogonal local frame yields -another orthogonal local frame. -/ -def IsOrthogonalFrameOn.gramSchmidt (hs : IsOrthogonalFrameOn IB F n s u) : - IsOrthogonalFrameOn IB F n (VectorBundle.gramSchmidt s) u where - toIsLocalFrameOn := hs.toIsLocalFrameOn.gramSchmidt - orthogonal {_ _ x} hij _hx := VectorBundle.gramSchmidt_orthogonal s hij x +/-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields +another orthonormal local frame. -/ +def IsOrthonormalFrameOn.gramSchmidtNormed (hs : IsOrthonormalFrameOn IB F n s u) : + IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where + toIsLocalFrameOn := hs.toIsLocalFrameOn.gramSchmidtNormed + orthogonal {_ _ x} hij _hx := sorry -- VectorBundle.gramSchmidt_orthogonal s hij x + normalised := sorry -- TODO: need to use the normalisation property! /-! # Determining smoothness of a section via its local frame coefficients @@ -97,17 +100,17 @@ simple form in orthgonal frames. section smoothness -namespace IsOrthogonalFrameOn +namespace IsOrthonormalFrameOn -variable (hs : IsOrthogonalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} +variable (hs : IsOrthonormalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} set_option linter.style.commandStart false variable (t) in -lemma repr_eq_inner (hs : IsOrthogonalFrameOn IB F n s u) +lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) {x} (hx : x ∈ u) (i : ι) : hs.repr i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by - -- should be a general lemma: orthogonal basis, have this identity + -- use #check OrthonormalBasis.repr_apply_apply sorry /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ @@ -172,7 +175,7 @@ lemma contMDiffOn_iff_repr' [Fintype ι] : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (fun x ↦ ⟪s i x, t x⟫) := sorry -- similar to the above lemma -end IsOrthogonalFrameOn +end IsOrthonormalFrameOn end smoothness @@ -190,12 +193,12 @@ variable (b e) in this is obtained by applying the Gram-Schmidt orthonormalisation procedure to `b.localFrame e`. In particular, if x is outside of `e.baseSet`, this returns the junk value 0. -/ noncomputable def orthonormalFrame : ι → (x : B) → E x := - VectorBundle.gramSchmidt (b.localFrame e) + VectorBundle.gramSchmidtNormed (b.localFrame e) omit [IsManifold IB n B] in /-- An orthonormal frame w.r.t. a local trivialisation is a local frame. -/ lemma orthonormalFrame_isLocalFrameOn : IsLocalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := - (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidt + (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidtNormed omit [IsManifold IB n B] in variable (b e) in @@ -222,7 +225,8 @@ lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e. @[simp] lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : b.orthonormalFrame e i x = 0 := by - simp only [orthonormalFrame, VectorBundle.gramSchmidt_apply] + simp only [orthonormalFrame, VectorBundle.gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed] + simp convert InnerProductSpace.gramSchmidt_zero ℝ i apply localFrame_apply_of_notMem e b hx From 770321b3d826d24cfe877b5903cb02cee215cf0e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 20:53:45 +0200 Subject: [PATCH 228/601] Fix differentiability sorry in GramSchmidtOrtho --- .../VectorBundle/GramSchmidtOrtho.lean | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 33e33d84e3ecb9..0c70fe6740ded9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -266,7 +266,7 @@ set_option linter.style.commandStart false variable [IsContMDiffRiemannianBundle IB n F E] -- TODO: give a much better name! -lemma contMDiffWithinAt_aux {s t : (x : B) → E x} {u : Set B} {x : B} +lemma contMDiffWithinAt_aux {s t : (x : B) → E x} {u : Set B} {x : B} (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : CMDiffAt[u] n (fun x ↦ ⟪s x, t x⟫ / (‖s x‖ ^ 2)) x := by suffices ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (fun x ↦ ⟪s x, t x⟫ / ⟪s x, s x⟫) u x by @@ -329,6 +329,19 @@ lemma gramSchmidt_contMDiff {s : ι → (x : B) → E x} (i : ι) CMDiff n (T% (VectorBundle.gramSchmidt s i)) := fun x ↦ gramSchmidt_contMDiffAt _ (fun i ↦ hs i x) (hs' x) +lemma contMDiffWithinAt_inner {s : (x : B) → E x} {u : Set B} {x : B} + (hs : CMDiffAt[u] n (T% s) x) (hs' : s x ≠ 0) : + CMDiffAt[u] n (‖s ·‖) x := by + let F (x) := ⟪s x, s x⟫ + have aux : ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (Real.sqrt ∘ F) u x := by + have h1 : CMDiffAt[(F '' u)] n (Real.sqrt) (F x) := by + apply ContMDiffAt.contMDiffWithinAt + rw [contMDiffAt_iff_contDiffAt] + exact Real.contDiffAt_sqrt (by simp [F, hs']) + exact h1.comp x (hs.inner_bundle hs) (Set.mapsTo_image _ u) + convert aux + simp [F, ← norm_eq_sqrt_real_inner] + lemma gramSchmidtNormed_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : Set B} {x : B} (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : @@ -337,25 +350,9 @@ lemma gramSchmidtNormed_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) (fun x ↦ ‖VectorBundle.gramSchmidt s i x‖⁻¹ • VectorBundle.gramSchmidt s i x)) x := by refine ContMDiffWithinAt.smul_section ?_ (gramSchmidt_contMDiffWithinAt i hs hs') refine ContMDiffWithinAt.inv₀ ?_ ?_ - · let F (x) := ⟪VectorBundle.gramSchmidt s i x, VectorBundle.gramSchmidt s i x⟫ - have aux : ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (Real.sqrt ∘ F) u x := by - have h1 : CMDiffAt[(F '' u)] n (Real.sqrt) - ⟪VectorBundle.gramSchmidt s i x, VectorBundle.gramSchmidt s i x⟫ := by - apply ContMDiffAt.contMDiffWithinAt - rw [contMDiffAt_iff_contDiffAt] - apply Real.contDiffAt_sqrt - simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' - have h2 : CMDiffAt[u] n F x := by - unfold F - -- have : CMDiffAt[u] n (T% (fun x ↦ VectorBundle.gramSchmidt s i x)) x := by - -- sorry -- did this already - sorry --apply this.inner_bundle this - exact h1.comp x (h2) (Set.mapsTo_image _ u) - apply aux.congr - · intro x hx - sorry - sorry - simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' + · refine contMDiffWithinAt_inner (gramSchmidt_contMDiffWithinAt i hs hs') ?_ + simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' + · simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' exact this.congr (fun y hy ↦ by congr) (by congr) lemma gramSchmidtNormed_contMDiffAt {s : ι → (x : B) → E x} (i : ι) {x : B} From 96533dcc2260301b80f416e9946e044c8a8bb31b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 21:18:30 +0200 Subject: [PATCH 229/601] feat: gramSchmidtNormed_linearIndependent --- .../Analysis/InnerProductSpace/GramSchmidtOrtho.lean | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 1721e2c3c0fdb1..2827ab3e6905a7 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -296,6 +296,16 @@ theorem span_gramSchmidtNormed_range (f : ι → E) : span 𝕜 (range (gramSchmidtNormed 𝕜 f)) = span 𝕜 (range (gramSchmidt 𝕜 f)) := by simpa only [image_univ.symm] using span_gramSchmidtNormed f univ +/-- `gramSchmidtNormed` produces linearly independent vectors when given linearly independent +vectors. -/ +theorem gramSchmidtNormed_linearIndependent {f : ι → E} (h₀ : LinearIndependent 𝕜 f) : + LinearIndependent 𝕜 (gramSchmidtNormed 𝕜 f) := by + unfold gramSchmidtNormed + have (i : ι) : IsUnit (‖gramSchmidt 𝕜 f i‖⁻¹ : 𝕜) := + isUnit_iff_ne_zero.mpr (by simp [gramSchmidt_ne_zero i h₀]) + let w : ι → 𝕜ˣ := fun i ↦ (this i).unit + apply (gramSchmidt_linearIndependent h₀).units_smul (w := fun i ↦ (this i).unit) + section OrthonormalBasis variable [Fintype ι] [FiniteDimensional 𝕜 E] (h : finrank 𝕜 E = Fintype.card ι) (f : ι → E) From 5a0d02907b1e378bf1d238b78ac9300597b99ac6 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 21:24:50 +0200 Subject: [PATCH 230/601] Vector bundle version --- .../Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 0c70fe6740ded9..52ea18894a4294 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -251,6 +251,12 @@ open Submodule Set Order -- span 𝕜 (range (gramSchmidtNormed 𝕜 f)) = span 𝕜 (range (gramSchmidt 𝕜 f)) := by -- simpa only [image_univ.symm] using span_gramSchmidtNormed f univ +/-- `gramSchmidtNormed` applied to linearly independent sections at a point `x` produces +sections which are linearly independent at `x`. -/ +theorem gramSchmidtNormed_linearIndependent (h₀ : LinearIndependent ℝ (s · x)) : + LinearIndependent ℝ (gramSchmidtNormed s · x) := by + simp [gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed_linearIndependent h₀] + end VectorBundle -- When given a local frame, this produces an orthonormal local frame... From 1d18915e1b4a9558915f38310fe2bc069eed3879 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 21:33:55 +0200 Subject: [PATCH 231/601] Fix easy sorries in OrthonormalFrame --- .../Manifold/VectorBundle/OrthonormalFrame.lean | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 1ef1ace7274c34..447b7d6095b32d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -66,10 +66,11 @@ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : IsLocalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where linearIndependent := by intro x hx - sorry -- exact VectorBundle.gramSchmidt_linearIndependent (hs.linearIndependent hx) + exact VectorBundle.gramSchmidtNormed_linearIndependent <| hs.linearIndependent hx generating := by intro x hx - sorry -- simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] + sorry + -- simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] -- using hs.generating hx contMDiffOn i := gramSchmidtNormed_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective @@ -79,8 +80,12 @@ another orthonormal local frame. -/ def IsOrthonormalFrameOn.gramSchmidtNormed (hs : IsOrthonormalFrameOn IB F n s u) : IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where toIsLocalFrameOn := hs.toIsLocalFrameOn.gramSchmidtNormed - orthogonal {_ _ x} hij _hx := sorry -- VectorBundle.gramSchmidt_orthogonal s hij x - normalised := sorry -- TODO: need to use the normalisation property! + -- TODO: combine these two fields into one? + orthogonal {_ _ x} hij hx := + (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).inner_eq_zero hij + normalised := by + intro i x hx + exact (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).norm_eq_one i /-! # Determining smoothness of a section via its local frame coefficients From 96f9e737eaa2b1922a29e4e205a8609dec576192 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 23:17:18 +0200 Subject: [PATCH 232/601] Fix merge; clean up VectorBundle/GramSchmidtOrtho --- .../InnerProductSpace/GramSchmidtOrtho.lean | 2 +- .../VectorBundle/GramSchmidtOrtho.lean | 112 +++++++++--------- .../VectorBundle/OrthonormalFrame.lean | 2 +- 3 files changed, 55 insertions(+), 61 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 5b1c92b7ed7ebc..c73b220db04044 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -23,7 +23,7 @@ and outputs a set of orthogonal vectors which have the same span. then so are the output vectors. - `gramSchmidt_ne_zero`: if the input vectors of `gramSchmidt` are linearly independent, then the output vectors are non-zero. -- `gramSchmidt_basis`: the basis produced by the Gram-Schmidt process when given a basis as input +- `gramSchmidtBasis`: the basis produced by the Gram-Schmidt process when given a basis as input - `gramSchmidtNormed`: the normalized `gramSchmidt` (i.e each vector in `gramSchmidtNormed` has unit length.) - `gramSchmidt_orthonormal`: `gramSchmidtNormed` produces an orthornormal system of vectors. diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 52ea18894a4294..c22f25ee7446c1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -259,10 +259,7 @@ theorem gramSchmidtNormed_linearIndependent (h₀ : LinearIndependent ℝ (s · end VectorBundle --- When given a local frame, this produces an orthonormal local frame... --- nothing new to prove; will prove in the frames file - --- Continuity and smoothness. +/-! The Gram-Schmidt process preserves smoothness of sections -/ variable {n : WithTop ℕ∞} @@ -271,25 +268,28 @@ set_option linter.style.commandStart false variable [IsContMDiffRiemannianBundle IB n F E] +section helper + +variable {s t : (x : B) → E x} {u : Set B} {x : B} + -- TODO: give a much better name! -lemma contMDiffWithinAt_aux {s t : (x : B) → E x} {u : Set B} {x : B} +lemma contMDiffWithinAt_aux (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : CMDiffAt[u] n (fun x ↦ ⟪s x, t x⟫ / (‖s x‖ ^ 2)) x := by - suffices ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (fun x ↦ ⟪s x, t x⟫ / ⟪s x, s x⟫) u x by - apply this.congr - · intro y hy - simp [inner_self_eq_norm_sq_to_K] - · congr - rw [← real_inner_self_eq_norm_sq] - exact (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) - -lemma contMDiffAt_aux {s t : (x : B) → E x} {x : B} - (hs : CMDiffAt n (T% s) x) (ht : CMDiffAt n (T% t) x) (hs' : s x ≠ 0) : + have := (hs.inner_bundle ht).smul ((hs.inner_bundle hs).inv₀ (inner_self_ne_zero.mpr hs')) + apply this.congr + · intro y hy + congr + simp [inner_self_eq_norm_sq_to_K] + · congr + rw [← real_inner_self_eq_norm_sq] + +lemma contMDiffAt_aux (hs : CMDiffAt n (T% s) x) (ht : CMDiffAt n (T% t) x) (hs' : s x ≠ 0) : CMDiffAt n (fun x ↦ ⟪s x, t x⟫ / (‖s x‖ ^ 2)) x := by rw [← contMDiffWithinAt_univ] at hs ht ⊢ exact contMDiffWithinAt_aux hs ht hs' -def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} +def ContMDiffWithinAt.orthogonalProjection (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).orthogonalProjection (t x); @@ -297,9 +297,24 @@ def contMDiffWithinAt_myproj {s t : (x : B) → E x} {u : Set B} {x : B} simp_rw [Submodule.orthogonalProjection_singleton] exact (contMDiffWithinAt_aux hs ht hs').smul_section hs -lemma gramSchmidt_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : Set B} {x : B} - (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) - (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : +lemma contMDiffWithinAt_inner (hs : CMDiffAt[u] n (T% s) x) (hs' : s x ≠ 0) : + CMDiffAt[u] n (‖s ·‖) x := by + let F (x) := ⟪s x, s x⟫ + have aux : CMDiffAt[u] n (Real.sqrt ∘ F) x := by + have h1 : CMDiffAt[(F '' u)] n (Real.sqrt) (F x) := by + apply ContMDiffAt.contMDiffWithinAt + rw [contMDiffAt_iff_contDiffAt] + exact Real.contDiffAt_sqrt (by simp [F, hs']) + exact h1.comp x (hs.inner_bundle hs) (Set.mapsTo_image _ u) + convert aux + simp [F, ← norm_eq_sqrt_real_inner] + +end helper + +variable {s : ι → (x : B) → E x} {u : Set B} {x : B} {i : ι} + +lemma gramSchmidt_contMDiffWithinAt (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) + {i : ι} (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by simp_rw [VectorBundle.gramSchmidt_def] apply (hs i).sub_section @@ -311,70 +326,49 @@ lemma gramSchmidt_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : S apply hs'.comp aux intro ⟨x, hx⟩ ⟨x', hx'⟩ h simp_all only [Subtype.mk.injEq, aux] - apply contMDiffWithinAt_myproj (gramSchmidt_contMDiffWithinAt i' hs this) (hs i) + apply ContMDiffWithinAt.orthogonalProjection (gramSchmidt_contMDiffWithinAt hs this) (hs i) apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i -decreasing_by - exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' +decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' -lemma gramSchmidt_contMDiffAt {s : ι → (x : B) → E x} (i : ι) {x : B} - (hs : ∀ i, CMDiffAt n (T% (s i)) x) - (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) - : CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := - contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt _ (fun i ↦ hs i) hs' +lemma gramSchmidt_contMDiffAt (hs : ∀ i, CMDiffAt n (T% (s i)) x) + (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : + CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := + contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt (fun i ↦ hs i) hs' -lemma gramSchmidt_contMDiffOn {s : ι → (x : B) → E x} (i : ι) (u : Set B) - (hs : ∀ i, CMDiff[u] n (T% (s i))) +lemma gramSchmidt_contMDiffOn (hs : ∀ i, CMDiff[u] n (T% (s i))) (hs' : ∀ x ∈ u, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff[u] n (T% (VectorBundle.gramSchmidt s i)) := - fun x hx ↦ gramSchmidt_contMDiffWithinAt _ (fun i ↦ hs i x hx) (hs' _ hx) + fun x hx ↦ gramSchmidt_contMDiffWithinAt (fun i ↦ hs i x hx) (hs' _ hx) -lemma gramSchmidt_contMDiff {s : ι → (x : B) → E x} (i : ι) - (hs : ∀ i, CMDiff n (T% (s i))) +lemma gramSchmidt_contMDiff (hs : ∀ i, CMDiff n (T% (s i))) (hs' : ∀ x, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff n (T% (VectorBundle.gramSchmidt s i)) := - fun x ↦ gramSchmidt_contMDiffAt _ (fun i ↦ hs i x) (hs' x) - -lemma contMDiffWithinAt_inner {s : (x : B) → E x} {u : Set B} {x : B} - (hs : CMDiffAt[u] n (T% s) x) (hs' : s x ≠ 0) : - CMDiffAt[u] n (‖s ·‖) x := by - let F (x) := ⟪s x, s x⟫ - have aux : ContMDiffWithinAt IB 𝓘(ℝ, ℝ) n (Real.sqrt ∘ F) u x := by - have h1 : CMDiffAt[(F '' u)] n (Real.sqrt) (F x) := by - apply ContMDiffAt.contMDiffWithinAt - rw [contMDiffAt_iff_contDiffAt] - exact Real.contDiffAt_sqrt (by simp [F, hs']) - exact h1.comp x (hs.inner_bundle hs) (Set.mapsTo_image _ u) - convert aux - simp [F, ← norm_eq_sqrt_real_inner] + fun x ↦ gramSchmidt_contMDiffAt (fun i ↦ hs i x) (hs' x) -lemma gramSchmidtNormed_contMDiffWithinAt {s : ι → (x : B) → E x} (i : ι) {u : Set B} {x : B} - (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) +lemma gramSchmidtNormed_contMDiffWithinAt (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidtNormed s i)) x := by have : CMDiffAt[u] n (T% (fun x ↦ ‖VectorBundle.gramSchmidt s i x‖⁻¹ • VectorBundle.gramSchmidt s i x)) x := by - refine ContMDiffWithinAt.smul_section ?_ (gramSchmidt_contMDiffWithinAt i hs hs') + refine ContMDiffWithinAt.smul_section ?_ (gramSchmidt_contMDiffWithinAt hs hs') refine ContMDiffWithinAt.inv₀ ?_ ?_ - · refine contMDiffWithinAt_inner (gramSchmidt_contMDiffWithinAt i hs hs') ?_ + · refine contMDiffWithinAt_inner (gramSchmidt_contMDiffWithinAt hs hs') ?_ simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' · simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' exact this.congr (fun y hy ↦ by congr) (by congr) -lemma gramSchmidtNormed_contMDiffAt {s : ι → (x : B) → E x} (i : ι) {x : B} - (hs : ∀ i, CMDiffAt n (T% (s i)) x) +lemma gramSchmidtNormed_contMDiffAt (hs : ∀ i, CMDiffAt n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt n (T% (VectorBundle.gramSchmidtNormed s i)) x := - contMDiffWithinAt_univ.mpr <| gramSchmidtNormed_contMDiffWithinAt _ (fun i ↦ hs i) hs' + contMDiffWithinAt_univ.mpr <| gramSchmidtNormed_contMDiffWithinAt (fun i ↦ hs i) hs' -lemma gramSchmidtNormed_contMDiffOn {s : ι → (x : B) → E x} (i : ι) (u : Set B) - (hs : ∀ i, CMDiff[u] n (T% (s i))) +lemma gramSchmidtNormed_contMDiffOn (hs : ∀ i, CMDiff[u] n (T% (s i))) (hs' : ∀ x ∈ u, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff[u] n (T% (VectorBundle.gramSchmidtNormed s i)) := - fun x hx ↦ gramSchmidtNormed_contMDiffWithinAt _ (fun i ↦ hs i x hx) (hs' _ hx) + fun x hx ↦ gramSchmidtNormed_contMDiffWithinAt (fun i ↦ hs i x hx) (hs' _ hx) -lemma gramSchmidtNormed_contMDiff {s : ι → (x : B) → E x} (i : ι) - (hs : ∀ i, CMDiff n (T% (s i))) +lemma gramSchmidtNormed_contMDiff (hs : ∀ i, CMDiff n (T% (s i))) (hs' : ∀ x, LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiff n (T% (VectorBundle.gramSchmidtNormed s i)) := - fun x ↦ gramSchmidtNormed_contMDiffAt _ (fun i ↦ hs i x) (hs' x) + fun x ↦ gramSchmidtNormed_contMDiffAt (fun i ↦ hs i x) (hs' x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 447b7d6095b32d..0b96bcd8a6a123 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -72,7 +72,7 @@ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : sorry -- simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] -- using hs.generating hx - contMDiffOn i := gramSchmidtNormed_contMDiffOn i u (fun i ↦ hs.contMDiffOn i) <| + contMDiffOn i := gramSchmidtNormed_contMDiffOn (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective /-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields From 1f7235a1316459fa871cf1878c7ef184303bbdf0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 23:29:34 +0200 Subject: [PATCH 233/601] Towards uniqueness of the Levi-Civita connection --- .../Geometry/Manifold/VectorBundle/LocalFrame.lean | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index ebb8c6583e78d9..6e3fe867169b0e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -176,7 +176,7 @@ lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x eventually_of_mem hu'' fun _ hx ↦ hs.repr_sum_eq _ hx /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma repr_congr (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} +lemma repr_congr (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} (htt' : t x = t' x) (i : ι) : hs.repr i t x = hs.repr i t' x := by by_cases hxe : x ∈ u @@ -194,6 +194,13 @@ lemma repr_eq_of_eq (hs : IsLocalFrameOn I F n s u) (hs' : IsLocalFrameOn I F n simp_all [toBasisAt] · simp [repr, hxe] +/-- Two sections `s` and `t` are equal at `x` if and only if their coefficients w.r.t. some local +frame at `x` agree. -/ +lemma eq_iff_repr [Fintype ι] (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} (hx : x ∈ u) : + t x = t' x ↔ ∀ i, hs.repr i t x = hs.repr i t' x := + ⟨fun h i ↦ hs.repr_congr h i, fun h ↦ by + simp +contextual [h, hs.repr_sum_eq t hx, hs.repr_sum_eq t' hx]⟩ + lemma repr_apply_zero_at (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} (ht : t x = 0) (i : ι) : hs.repr i t x = 0 := by simp [hs.repr_congr (t' := 0) ht] @@ -431,8 +438,8 @@ Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : b.localFrame_repr I e i s x = b.repr (e (s x)).2 i := by - simp only [localFrame_repr] - sorry -- simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] + --simp only [localFrame_repr] + simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] end Basis From b60728df0ef2a49cbb1c552fe23d7be44945bde7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 10 Jul 2025 23:58:59 +0200 Subject: [PATCH 234/601] We have everything for uniqueness of Levi-Civita now! A few TODOs and clean-up remain for tomorrow. --- .../Manifold/VectorBundle/LeviCivita.lean | 33 ++++++++++++++++--- .../VectorBundle/OrthonormalFrame.lean | 15 +++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index ee6de84d1ce7bb..7c03af852870c3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative +import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Riemannian @@ -289,11 +290,33 @@ variable {I} in vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by - -- any vector bundle with a bundle metric has local orthonormal frames (not just a local frame) - -- -> apply Gram-Schmidt to a local frame; prove orthonormality w.r.t. bundle metric - -- prove: local orthonormal frame is C^k when the bundle metric is - -- use this to prove this lemma - sorry + ext x + letI b := Basis.ofVectorSpace ℝ E + letI t := trivializationAt E (TangentSpace I : M → Type _) x + have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + -- TODO: think about this question and solve it somehow! + haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + haveI : WellFoundedLT ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + haveI : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g + let real := b.orthonormalFrame t + have hframe := b.orthonormalFrame_isLocalFrameOn (e := t) (F := E) (IB := I) (n := 1) + have hframe' := b.orthonormalFrame_isOrthonormalFrameOn (e := t) (F := E) (IB := I) (n := 1) + rw [hframe.eq_iff_repr hx] + intro i + + have h₁ : ⟪X, real i⟫ x = (hframe.repr i) X x := by + rw [hframe'.repr_eq_inner' _ hx] + simp [real, real_inner_comm] + have h₂ : ⟪X', real i⟫ x = (hframe.repr i) X' x := by + rw [hframe'.repr_eq_inner' _ hx] + simp [real, real_inner_comm] + -- this would work, except that h is unapplied, but my results are applied... + --simp_rw [hframe'.repr_eq_inner' _ hx] + --specialize h (real i) + --simp [real_inner_comm] + rw [← h₁, ← h₂, h (real i)] /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 0b96bcd8a6a123..725a834f9d2573 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -61,6 +61,7 @@ lemma IsOrthonormalFrameOn.mono (hs : IsOrthonormalFrameOn IB F n s u) (huu' : u orthogonal hij hx := hs.orthogonal hij (huu' hx) normalised hx := hs.normalised (huu' hx) +-- TODO: upgrade to an orthonormal frame! /-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : IsLocalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where @@ -111,6 +112,12 @@ variable (hs : IsOrthonormalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} set_option linter.style.commandStart false +-- TODO: remove repr_eq_inner in favour of this version! +variable (t) in +lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) + {x} (hx : x ∈ u) (i : ι) : + hs.repr i t x = ⟪s i x, t x⟫ := by sorry + variable (t) in lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) {x} (hx : x ∈ u) (i : ι) : @@ -205,6 +212,14 @@ omit [IsManifold IB n B] in lemma orthonormalFrame_isLocalFrameOn : IsLocalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidtNormed +/-- An orthonormal frame w.r.t. a local trivialisation is an orthonormal local frame. -/ +lemma orthonormalFrame_isOrthonormalFrameOn : + IsOrthonormalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := by + unfold Basis.orthonormalFrame + have aux := (b.localFrame_isLocalFrameOn_baseSet IB n e) + -- apply aux.gramSchmidtNormed -- need to upgrade that lemma + sorry + omit [IsManifold IB n B] in variable (b e) in /-- Each orthonormal frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local From d3d75cc6b4ce917122ed710ab97bf03012fac70d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 09:43:28 +0200 Subject: [PATCH 235/601] First kind of API changes --- .../VectorBundle/OrthonormalFrame.lean | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 725a834f9d2573..ad8a0c09263220 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -61,10 +61,9 @@ lemma IsOrthonormalFrameOn.mono (hs : IsOrthonormalFrameOn IB F n s u) (huu' : u orthogonal hij hx := hs.orthogonal hij (huu' hx) normalised hx := hs.normalised (huu' hx) --- TODO: upgrade to an orthonormal frame! -/-- Applying the Gram-Schmidt procedure to a local frame yields another local frame. -/ +/-- Applying the Gram-Schmidt procedure to a local frame yields an orthonormal local frame. -/ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : - IsLocalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where + IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where linearIndependent := by intro x hx exact VectorBundle.gramSchmidtNormed_linearIndependent <| hs.linearIndependent hx @@ -75,19 +74,18 @@ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : -- using hs.generating hx contMDiffOn i := gramSchmidtNormed_contMDiffOn (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective - -/-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields -another orthonormal local frame. -/ -def IsOrthonormalFrameOn.gramSchmidtNormed (hs : IsOrthonormalFrameOn IB F n s u) : - IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where - toIsLocalFrameOn := hs.toIsLocalFrameOn.gramSchmidtNormed - -- TODO: combine these two fields into one? orthogonal {_ _ x} hij hx := (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).inner_eq_zero hij normalised := by intro i x hx exact (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).norm_eq_one i +-- XXX: is this one necessary? +/-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields +another orthonormal local frame. -/ +def IsOrthonormalFrameOn.gramSchmidtNormed (hs : IsOrthonormalFrameOn IB F n s u) : + IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u := + hs.toIsLocalFrameOn.gramSchmidtNormed /-! # Determining smoothness of a section via its local frame coefficients @@ -208,25 +206,20 @@ noncomputable def orthonormalFrame : ι → (x : B) → E x := VectorBundle.gramSchmidtNormed (b.localFrame e) omit [IsManifold IB n B] in -/-- An orthonormal frame w.r.t. a local trivialisation is a local frame. -/ -lemma orthonormalFrame_isLocalFrameOn : IsLocalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := - (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidtNormed - +variable (b e) in /-- An orthonormal frame w.r.t. a local trivialisation is an orthonormal local frame. -/ lemma orthonormalFrame_isOrthonormalFrameOn : - IsOrthonormalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := by - unfold Basis.orthonormalFrame - have aux := (b.localFrame_isLocalFrameOn_baseSet IB n e) - -- apply aux.gramSchmidtNormed -- need to upgrade that lemma - sorry + IsOrthonormalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := + (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidtNormed omit [IsManifold IB n B] in variable (b e) in /-- Each orthonormal frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_orthonormalFrame_baseSet (i : ι) : - CMDiff[e.baseSet] n (T% b.orthonormalFrame e i) := - orthonormalFrame_isLocalFrameOn.contMDiffOn _ + CMDiff[e.baseSet] n (T% b.orthonormalFrame e i) := by + apply IsLocalFrameOn.contMDiffOn + exact (b.orthonormalFrame_isOrthonormalFrameOn e).toIsLocalFrameOn omit [IsManifold IB n B] in variable (b e) in @@ -251,5 +244,3 @@ lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : apply localFrame_apply_of_notMem e b hx end Basis - -/- next lemma: uniqueness (what I need for torsion) -/ From d53bcfe285dc917d4e859f82b337d99ca1150a01 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 09:49:16 +0200 Subject: [PATCH 236/601] chore(VectorBundle/GramSchmidtOrtho): comment on some omitted API --- .../VectorBundle/GramSchmidtOrtho.lean | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index c22f25ee7446c1..b896946a525d63 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -183,20 +183,9 @@ theorem gramSchmidt_ne_zero (n : ι) {x} (h₀ : LinearIndependent ℝ (s · x)) gramSchmidt s n x ≠ 0 := InnerProductSpace.gramSchmidt_ne_zero _ h₀ --- not needed at the moment: I want a point-wise version, along the lines --- "if s i x is a basis, then gramSchmidt s i x is a triangular matrix" -/- -/-- At each point, when given a basis, `gramSchmidt` produces a triangular matrix of section -values. -/ -theorem gramSchmidt_triangular {x} {i j : ι} (hij : i < j) (b : Basis ι ℝ (E x)) : - b.repr (gramSchmidt b i x) j = 0 := sorry - b.repr (gramSchmidt b i) j = 0 := by - have : gramSchmidt ℝ b i ∈ span ℝ (gramSchmidt ℝ b '' Set.Iio j) := - subset_span ((Set.mem_image _ _ _).2 ⟨i, hij, rfl⟩) - have : gramSchmidt ℝ b i ∈ span ℝ (b '' Set.Iio j) := by rwa [← span_gramSchmidt_Iio ℝ b j] - have : ↑(b.repr (gramSchmidt ℝ b i)).support ⊆ Set.Iio j := - Basis.repr_support_subset_of_mem_span b (Set.Iio j) this - exact (Finsupp.mem_supported' _ _).1 ((Finsupp.mem_supported ℝ _).2 this) j Set.notMem_Iio_self-/ +-- No version of `gramSchmidt_triangular` at the moment, for technical reasons: it would expect a +-- `Basis` (of vectors in `E x`) as input, whereas we would want a hypothesis "the section values +-- `s i x` form a basis" instead. /-- `gramSchmidt` produces point-wise linearly independent sections when given linearly independent sections. -/ @@ -204,6 +193,9 @@ theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x) LinearIndependent ℝ (gramSchmidt s · x) := InnerProductSpace.gramSchmidt_linearIndependent h₀ +-- No definition `gramSchmidtBasis` for technical reasons: it would expect a `Basis` as input, +-- whereas we would want a notion "the section values `s i x` form a basis". + noncomputable def gramSchmidtNormed [WellFoundedLT ι] (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ InnerProductSpace.gramSchmidtNormed ℝ (s · x) n From 11267e7c3c02662185ed97d636c2d0a583d26bec Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 10:03:57 +0200 Subject: [PATCH 237/601] In fact, do define this API because it's not hard --- .../VectorBundle/GramSchmidtOrtho.lean | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index b896946a525d63..ecfe194578cc52 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -145,13 +145,11 @@ theorem span_gramSchmidt_Iio (c : ι) (x) : span ℝ ((gramSchmidt s · x) '' Set.Iio c) = span ℝ ((s · x) '' Set.Iio c) := InnerProductSpace.span_gramSchmidt_Iio _ _ _ --- variable (s) in --- /-- `gramSchmidt` preserves the point-wise span of sections. -/ --- theorem span_gramSchmidt (x) : span ℝ (range (gramSchmidt ℝ (s · x))) = span ℝ (range (s · x)) := --- span_eq_span (range_subset_iff.2 fun _ ↦ --- span_mono (image_subset_range _ _) <| gramSchmidt_mem_span _ _ le_rfl) <| --- range_subset_iff.2 fun _ ↦ --- span_mono (image_subset_range _ _) <| mem_span_gramSchmidt _ _ le_rfl +variable (s) in +/-- `gramSchmidt` preserves the point-wise span of sections. -/ +theorem span_gramSchmidt (x : B) : + span ℝ (range (gramSchmidt s · x)) = Submodule.span ℝ (range (s · x)) := + InnerProductSpace.span_gramSchmidt ℝ (s · x) theorem gramSchmidt_of_orthogonal {x} (hs : Pairwise fun i j ↦ ⟪s i x, s j x⟫ = 0) : ∀ i₀, gramSchmidt s i₀ x = s i₀ x:= by @@ -193,8 +191,17 @@ theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x) LinearIndependent ℝ (gramSchmidt s · x) := InnerProductSpace.gramSchmidt_linearIndependent h₀ --- No definition `gramSchmidtBasis` for technical reasons: it would expect a `Basis` as input, --- whereas we would want a notion "the section values `s i x` form a basis". +/-- When the sections `s` form a basis at `x`, so do the sections `gramSchmidt s`. -/ +noncomputable def gramSchmidtBasis {x} (hs : LinearIndependent ℝ (s · x)) + (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + Basis ι ℝ (E x) := + Basis.mk (gramSchmidt_linearIndependent hs) + ((span_gramSchmidt s x).trans (eq_top_iff'.mpr fun _ ↦ hs' trivial)).ge + +theorem coe_gramSchmidtBasis {x} (hs : LinearIndependent ℝ (s · x)) + (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + (gramSchmidtBasis hs hs') = (gramSchmidt s · x) := + Basis.coe_mk _ _ noncomputable def gramSchmidtNormed [WellFoundedLT ι] (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ @@ -234,14 +241,15 @@ theorem gramSchmidtNormed_orthonormal' (x) : open Submodule Set Order --- Statement needs to be changed a bit to make it type-check. --- variable (s) in --- theorem span_gramSchmidtNormed (t : Set ι) : --- span ℝ (gramSchmidtNormed s '' t) = span ℝ (gramSchmidt s '' t) := sorry +variable (s) in +theorem span_gramSchmidtNormed (t : Set ι) (x) : + span ℝ ((gramSchmidtNormed s · x) '' t) = span ℝ ((gramSchmidt s · x) '' t) := + InnerProductSpace.span_gramSchmidtNormed (s · x) t --- theorem span_gramSchmidtNormed_range (f : ι → E) : --- span 𝕜 (range (gramSchmidtNormed 𝕜 f)) = span 𝕜 (range (gramSchmidt 𝕜 f)) := by --- simpa only [image_univ.symm] using span_gramSchmidtNormed f univ +variable (s) in +theorem span_gramSchmidtNormed_range (x) : + span ℝ (range (gramSchmidtNormed s · x)) = span ℝ (range (gramSchmidt s · x)) := by + simpa only [image_univ.symm] using span_gramSchmidtNormed s Set.univ x /-- `gramSchmidtNormed` applied to linearly independent sections at a point `x` produces sections which are linearly independent at `x`. -/ From c2f432c8bdb02fd016d5602577f95edb9994800c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 10:35:08 +0200 Subject: [PATCH 238/601] wip: produce an orthonormal basis in vector bundle Gram-Schmidt --- .../VectorBundle/GramSchmidtOrtho.lean | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index ecfe194578cc52..2be876050389fc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -257,6 +257,35 @@ theorem gramSchmidtNormed_linearIndependent (h₀ : LinearIndependent ℝ (s · LinearIndependent ℝ (gramSchmidtNormed s · x) := by simp [gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed_linearIndependent h₀] +-- TODO: comment on the different design compared to `InnerProductSpace.gramSchmidtOrthonormalBasis` + +/-- When the sections `s` form a basis at `x`, so do the sections `gramSchmidtNormed s`. + +Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ +noncomputable def gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x)) + (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + Basis ι ℝ (E x) := + Basis.mk (v := fun i ↦ gramSchmidtNormed s i x) (gramSchmidtNormed_linearIndependent hs) + (by rw [span_gramSchmidtNormed_range s x, span_gramSchmidt s x]; exact hs') + +/-- Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ +theorem coe_gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x)) + (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + (gramSchmidtNormedBasis hs hs') = (gramSchmidtNormed s · x) := + Basis.coe_mk _ _ + +noncomputable def gramSchmidtOrthonormalBasis {x} [Fintype ι] + (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + OrthonormalBasis ι ℝ (E x) := by + apply (gramSchmidtNormedBasis hs hs').toOrthonormalBasis + simp only [coe_gramSchmidtNormedBasis] -- TODO: missing API! + apply gramSchmidtNormed_orthonormal hs + +theorem coe_gramSchmidtOrthonormalBasis_coe [Fintype ι] {x} (hs : LinearIndependent ℝ (s · x)) + (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + (gramSchmidtOrthonormalBasis hs hs') = (gramSchmidtNormed s · x) := by + sorry -- TODO: make sure things work by proving this! + end VectorBundle /-! The Gram-Schmidt process preserves smoothness of sections -/ From aac01a0ed0944e9727401698086fba6ff9bfa740 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 10:44:04 +0200 Subject: [PATCH 239/601] Getting close to proving the repr result --- .../Manifold/VectorBundle/OrthonormalFrame.lean | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index ad8a0c09263220..4524ac27668b62 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -112,9 +112,22 @@ set_option linter.style.commandStart false -- TODO: remove repr_eq_inner in favour of this version! variable (t) in -lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) +lemma repr_eq_inner' [Fintype ι] (hs : IsOrthonormalFrameOn IB F n s u) {x} (hx : x ∈ u) (i : ι) : - hs.repr i t x = ⟪s i x, t x⟫ := by sorry + hs.repr i t x = ⟪s i x, t x⟫ := by + let b := VectorBundle.gramSchmidtOrthonormalBasis (hs.linearIndependent hx) (hs.generating hx) + --have : hs.repr i t x = b.repr (t x) := sorry + have beq (i : ι) : b i = s i x := sorry + have aux := b.repr_apply_apply (t x) i + rw [beq] at aux + rw [← aux] + simp only [IsLocalFrameOn.repr] + dsimp + simp only [hx, ↓reduceDIte] + --congr 3 + --simp [beq] + -- missing API lemma about these basis... + sorry variable (t) in lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) From d857dd04e9911c60079e423ab4e9b5ccd5edda76 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 10:44:58 +0200 Subject: [PATCH 240/601] Fix the build --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 7c03af852870c3..4acf5f2ddc4ade 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -301,16 +301,15 @@ lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} haveI : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g let real := b.orthonormalFrame t - have hframe := b.orthonormalFrame_isLocalFrameOn (e := t) (F := E) (IB := I) (n := 1) - have hframe' := b.orthonormalFrame_isOrthonormalFrameOn (e := t) (F := E) (IB := I) (n := 1) + have hframe := b.orthonormalFrame_isOrthonormalFrameOn (e := t) (F := E) (IB := I) (n := 1) rw [hframe.eq_iff_repr hx] intro i have h₁ : ⟪X, real i⟫ x = (hframe.repr i) X x := by - rw [hframe'.repr_eq_inner' _ hx] + rw [hframe.repr_eq_inner' _ hx] simp [real, real_inner_comm] have h₂ : ⟪X', real i⟫ x = (hframe.repr i) X' x := by - rw [hframe'.repr_eq_inner' _ hx] + rw [hframe.repr_eq_inner' _ hx] simp [real, real_inner_comm] -- this would work, except that h is unapplied, but my results are applied... --simp_rw [hframe'.repr_eq_inner' _ hx] From 1f9426f1b987daeae56259a9a81b35650fe3324a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 12:17:18 +0200 Subject: [PATCH 241/601] feat: gramSchmidt{Normal,OrthonormalBasis} preserve orthonormal sections --- .../InnerProductSpace/GramSchmidtOrtho.lean | 1 + .../VectorBundle/GramSchmidtOrtho.lean | 29 +++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index c73b220db04044..6950b3d56ee0aa 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -161,6 +161,7 @@ theorem span_gramSchmidt (f : ι → E) : span 𝕜 (range (gramSchmidt 𝕜 f)) range_subset_iff.2 fun _ => span_mono (image_subset_range _ _) <| mem_span_gramSchmidt _ _ le_rfl +/-- If given an orthogonal set of vectors, `gramSchmidt` fixes its input. -/ theorem gramSchmidt_of_orthogonal {f : ι → E} (hf : Pairwise fun i j => ⟪f i, f j⟫ = 0) : gramSchmidt 𝕜 f = f := by ext i diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 2be876050389fc..43263f7d332643 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -151,6 +151,7 @@ theorem span_gramSchmidt (x : B) : span ℝ (range (gramSchmidt s · x)) = Submodule.span ℝ (range (s · x)) := InnerProductSpace.span_gramSchmidt ℝ (s · x) +/-- If the section values `s i x` are orthogonal, `gramSchmidt` yields the same values at `x`. -/ theorem gramSchmidt_of_orthogonal {x} (hs : Pairwise fun i j ↦ ⟪s i x, s j x⟫ = 0) : ∀ i₀, gramSchmidt s i₀ x = s i₀ x:= by intro i @@ -257,6 +258,16 @@ theorem gramSchmidtNormed_linearIndependent (h₀ : LinearIndependent ℝ (s · LinearIndependent ℝ (gramSchmidtNormed s · x) := by simp [gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed_linearIndependent h₀] +lemma gramSchmidtNormed_apply_of_orthogonal (hs : Pairwise fun i j ↦ ⟪s i x, s j x⟫ = 0) {i : ι} : + gramSchmidtNormed s i x = (‖s i x‖⁻¹ : ℝ) • s i x := by + simp_rw [gramSchmidtNormed_coe, gramSchmidt_of_orthogonal hs i] + +/-- If the section values `s i x` are orthonormal, applying `gramSchmidtNormed` yields the same +values at `x`. -/ +lemma gramSchmidtNormed_apply_of_orthonormal {x} (hs : Orthonormal ℝ (s · x)) (i : ι) : + gramSchmidtNormed s i x = s i x := by + simp [gramSchmidtNormed_apply_of_orthogonal hs.2, hs.1 i] + -- TODO: comment on the different design compared to `InnerProductSpace.gramSchmidtOrthonormalBasis` /-- When the sections `s` form a basis at `x`, so do the sections `gramSchmidtNormed s`. @@ -269,22 +280,28 @@ noncomputable def gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x (by rw [span_gramSchmidtNormed_range s x, span_gramSchmidt s x]; exact hs') /-- Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ +@[simp] theorem coe_gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : - (gramSchmidtNormedBasis hs hs') = (gramSchmidtNormed s · x) := + (gramSchmidtNormedBasis hs hs' : ι → E x) = (gramSchmidtNormed s · x) := Basis.coe_mk _ _ noncomputable def gramSchmidtOrthonormalBasis {x} [Fintype ι] (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : OrthonormalBasis ι ℝ (E x) := by apply (gramSchmidtNormedBasis hs hs').toOrthonormalBasis - simp only [coe_gramSchmidtNormedBasis] -- TODO: missing API! - apply gramSchmidtNormed_orthonormal hs + simp [gramSchmidtNormed_orthonormal hs] -theorem coe_gramSchmidtOrthonormalBasis_coe [Fintype ι] {x} (hs : LinearIndependent ℝ (s · x)) +@[simp] +theorem gramSchmidtOrthonormalBasis_coe [Fintype ι] {x} (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : - (gramSchmidtOrthonormalBasis hs hs') = (gramSchmidtNormed s · x) := by - sorry -- TODO: make sure things work by proving this! + (gramSchmidtOrthonormalBasis hs hs' : ι → E x) = (gramSchmidtNormed s · x) := by + simp [gramSchmidtOrthonormalBasis] + +theorem gramSchmidtOrthonormalBasis_apply_of_orthonormal [Fintype ι] {x} + (hs : Orthonormal ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : + (gramSchmidtOrthonormalBasis hs.linearIndependent hs') = (s · x) := by + simp [gramSchmidtNormed_apply_of_orthonormal hs] end VectorBundle From 77b975e3666b0e2cc8b89898753f743c970c8ec9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 12:24:42 +0200 Subject: [PATCH 242/601] refactor: make IsOrthonormalFrameOn require orthonormality instead --- .../VectorBundle/OrthonormalFrame.lean | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 4524ac27668b62..6a56e76ee89919 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -48,9 +48,10 @@ variable {s : ι → (x : B) → E x} {u u' : Set B} variable (IB F n) in structure IsOrthonormalFrameOn (s : ι → (x : B) → E x) (u : Set B) extends IsLocalFrameOn IB F n s u where - /-- Any two distinct sections are point-wise orthogonal on `u`. -/ - orthogonal {i j : ι} {x : B} : i ≠ j → x ∈ u → ⟪s i x, s j x⟫ = 0 - normalised {i : ι} {x : B} : x ∈ u → ‖s i x‖ = 1 + orthonormal {x} : x ∈ u → Orthonormal ℝ (s · x) + -- /-- Any two distinct sections are point-wise orthogonal on `u`. -/ + -- orthogonal {i j : ι} {x : B} : i ≠ j → x ∈ u → ⟪s i x, s j x⟫ = 0 + -- normalised {i : ι} {x : B} : x ∈ u → ‖s i x‖ = 1 omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] @@ -58,8 +59,7 @@ omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] lemma IsOrthonormalFrameOn.mono (hs : IsOrthonormalFrameOn IB F n s u) (huu' : u' ⊆ u) : IsOrthonormalFrameOn IB F n s u' where toIsLocalFrameOn := hs.toIsLocalFrameOn.mono huu' - orthogonal hij hx := hs.orthogonal hij (huu' hx) - normalised hx := hs.normalised (huu' hx) + orthonormal hx := hs.orthonormal (huu' hx) /-- Applying the Gram-Schmidt procedure to a local frame yields an orthonormal local frame. -/ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : @@ -74,11 +74,13 @@ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : -- using hs.generating hx contMDiffOn i := gramSchmidtNormed_contMDiffOn (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective - orthogonal {_ _ x} hij hx := - (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).inner_eq_zero hij - normalised := by - intro i x hx - exact (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).norm_eq_one i + orthonormal hx := (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)) + + -- orthogonal {_ _ x} hij hx := + -- (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).inner_eq_zero hij + -- normalised := by + -- intro i x hx + -- exact (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).norm_eq_one i -- XXX: is this one necessary? /-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields From d833854fb64d7575ea61a6049aeda53fc77f512f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 14:15:53 +0200 Subject: [PATCH 243/601] Fix sorries in OrthonormalFrame; clean up --- .../VectorBundle/OrthonormalFrame.lean | 90 +++++++------------ 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 6a56e76ee89919..c0f20003add86c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -108,51 +108,45 @@ section smoothness namespace IsOrthonormalFrameOn +omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] +variable [Fintype ι] + variable (hs : IsOrthonormalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} set_option linter.style.commandStart false --- TODO: remove repr_eq_inner in favour of this version! +omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] in variable (t) in -lemma repr_eq_inner' [Fintype ι] (hs : IsOrthonormalFrameOn IB F n s u) - {x} (hx : x ∈ u) (i : ι) : +lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : hs.repr i t x = ⟪s i x, t x⟫ := by let b := VectorBundle.gramSchmidtOrthonormalBasis (hs.linearIndependent hx) (hs.generating hx) - --have : hs.repr i t x = b.repr (t x) := sorry - have beq (i : ι) : b i = s i x := sorry + have beq (i : ι) : b i = s i x := by + simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] + have heq' : b.toBasis = hs.toBasisAt hx := by + ext i + simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] have aux := b.repr_apply_apply (t x) i rw [beq] at aux - rw [← aux] - simp only [IsLocalFrameOn.repr] - dsimp - simp only [hx, ↓reduceDIte] - --congr 3 - --simp [beq] - -- missing API lemma about these basis... - sorry + simp [← aux, IsLocalFrameOn.repr, hx, ← heq'] -variable (t) in -lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) - {x} (hx : x ∈ u) (i : ι) : - hs.repr i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by - -- use #check OrthonormalBasis.repr_apply_apply - sorry +-- This lemma would hold more generally for an *orthogonal frame*. +-- variable (t) in +-- lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : +-- hs.repr i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by +-- sorry -- need a versio of b.repr_apply_apply for *orthogonal* bases /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : - CMDiffAt[u] n (hs.repr i t) x := by - have aux : CMDiffAt[u] n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := - contMDiffWithinAt_aux ((hs.contMDiffOn i) x hx) ht <| (hs.linearIndependent hx).ne_zero _ - exact aux.congr_of_mem (fun y hy ↦ hs.repr_eq_inner _ hy _) hx + CMDiffAt[u] n (hs.repr i t) x := + ((hs.contMDiffOn i x hx).inner_bundle ht).congr_of_mem (fun _ hy ↦ hs.repr_eq_inner' _ hy _) hx +omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] in /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : - CMDiffAt n (hs.repr i t) x := by - have aux : CMDiffAt n (fun x ↦ ⟪s i x, t x⟫ / (‖s i x‖ ^ 2)) x := - contMDiffAt_aux ((hs.contMDiffOn i).contMDiffAt hu) ht <| - (hs.linearIndependent (mem_of_mem_nhds hu)).ne_zero _ - exact aux.congr_of_eventuallyEq <| - Filter.eventually_of_mem hu fun x hx ↦ hs.repr_eq_inner _ hx _ + CMDiffAt n (hs.repr i t) x := + (((hs.contMDiffOn i).contMDiffAt hu).inner_bundle ht).congr_of_eventuallyEq <| + Filter.eventually_of_mem hu fun _ hx ↦ hs.repr_eq_inner' _ hx _ -- Future: prove the same result for all local frames -- if `{s i}` is a local frame on `u`, and `{s' i}` are the corresponding orthogonalised frame, @@ -168,35 +162,26 @@ lemma contMDiffOn_repr (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.repr /-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal local frame near `x` is. -/ -lemma contMDiffAt_iff_repr [Fintype ι] - (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.repr i t) x := +lemma contMDiffAt_iff_repr (hu : u ∈ 𝓝 x) : + CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.repr i t) x := ⟨fun h i ↦ hs.contMDiffAt_repr hu h i, fun h ↦ hs.contMDiffAt_of_repr h hu⟩ /-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff each of its coefficients `hs.repr i s` w.r.t. the local frame `{s i}` is. -/ -lemma contMDiffOn_iff_repr [Fintype ι] : - CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.repr i t) := +lemma contMDiffOn_iff_repr : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.repr i t) := ⟨fun h i ↦ hs.contMDiffOn_repr h i, fun hi ↦ hs.contMDiffOn_of_repr hi⟩ -- unused, just stating for convenience/nice API include hs in -lemma contMDiffAt_iff_repr' [Fintype ι] - (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫) x := by - trans ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫/ (‖s i x‖ ^ 2)) x - · rw [hs.contMDiffAt_iff_repr hu] - have (i : ι) := Filter.eventually_of_mem hu fun x hx ↦ (hs.repr_eq_inner t hx i) - exact ⟨fun h i ↦ (h i).congr_of_eventuallyEq <| Filter.EventuallyEq.symm (this i), - fun h i ↦ (h i).congr_of_eventuallyEq (this i)⟩ - · peel with i - refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ - · sorry -- similar to other direction below - · apply h.smul - refine ContMDiffAt.inv₀ ?_ ?_ - · sorry -- rewrite ‖ ‖² = ⟨s, s⟩ - · sorry -- neq 0 +lemma contMDiffAt_iff_repr' (hu : u ∈ 𝓝 x) : + CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫) x := by + rw [hs.contMDiffAt_iff_repr hu] + have (i : ι) := Filter.eventually_of_mem hu fun x hx ↦ (hs.repr_eq_inner' t hx i) + exact ⟨fun h i ↦ (h i).congr_of_eventuallyEq <| Filter.EventuallyEq.symm (this i), + fun h i ↦ (h i).congr_of_eventuallyEq (this i)⟩ -- unused, just stating for convenience/nice API -lemma contMDiffOn_iff_repr' [Fintype ι] : +lemma contMDiffOn_iff_repr' : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (fun x ↦ ⟪s i x, t x⟫) := sorry -- similar to the above lemma @@ -206,13 +191,10 @@ end smoothness namespace Basis --- bad, for prototyping variable {b : Basis ι ℝ F} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} [MemTrivializationAtlas e] {x : B} -- (hx : x ∈ e.baseSet) --- noncomputable def orthonormalFrame_toBasis_at : Basis ι ℝ (E x) := sorry - variable (b e) in /-- The orthonormal frame associated to the basis `b` and the trivialisation `e`: this is obtained by applying the Gram-Schmidt orthonormalisation procedure to `b.localFrame e`. @@ -244,12 +226,6 @@ lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e. -- #check' contMDiffOn_orthonormalFrame_baseSet (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx --- variable (b e) in --- @[simp] --- lemma orthonormalFrame_apply_of_mem_baseSet {i : ι} (hx : x ∈ e.baseSet) : --- b.orthonormalFrame e i x = b.orthonormalFrame_toBasis_at e hx i := by --- simp [orthonormalFrame, hx] - @[simp] lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : b.orthonormalFrame e i x = 0 := by From 1197497b7ccf33923d4aed1e1c54c0c3fe17cfd4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 14:22:17 +0200 Subject: [PATCH 244/601] Good enough; next file! --- .../Manifold/VectorBundle/OrthonormalFrame.lean | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index c0f20003add86c..de7df4720420ac 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -69,19 +69,12 @@ def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : exact VectorBundle.gramSchmidtNormed_linearIndependent <| hs.linearIndependent hx generating := by intro x hx - sorry - -- simpa only [VectorBundle.gramSchmidt_apply, InnerProductSpace.span_gramSchmidt ℝ (s · x)] - -- using hs.generating hx + simpa only [VectorBundle.span_gramSchmidtNormed_range, VectorBundle.gramSchmidt_apply, + InnerProductSpace.span_gramSchmidt] using hs.generating hx contMDiffOn i := gramSchmidtNormed_contMDiffOn (fun i ↦ hs.contMDiffOn i) <| fun x hx ↦ (hs.linearIndependent hx).comp _ Subtype.val_injective orthonormal hx := (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)) - -- orthogonal {_ _ x} hij hx := - -- (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).inner_eq_zero hij - -- normalised := by - -- intro i x hx - -- exact (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)).norm_eq_one i - -- XXX: is this one necessary? /-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields another orthonormal local frame. -/ From acc95fc521351f76e86334a2e1c99c58dfe3f07b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 14:34:15 +0200 Subject: [PATCH 245/601] Comment on Levi-Civita sorries. --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 4acf5f2ddc4ade..928c1559b0e96c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -183,6 +183,8 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : -- solve for ⟪cov X Y, Z⟫ and obtain the claim simp only [leviCivita_rhs] -- - D - E + F ext x + -- sorry is because there are different "2"s here; + -- the first is a function M → ℝ, the second a natural number have almost := isolate_aux (X := rhs_aux I X Y Z) (Y := rhs_aux I Y Z X) (Z := rhs_aux I Z X Y) (A := A) (D := D) (E := E) (F := F) (h := by simp [this]; sorry) sorry -- obvious: if 2 • A = stuff, A = 1/2 stuff @@ -304,7 +306,6 @@ lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} have hframe := b.orthonormalFrame_isOrthonormalFrameOn (e := t) (F := E) (IB := I) (n := 1) rw [hframe.eq_iff_repr hx] intro i - have h₁ : ⟪X, real i⟫ x = (hframe.repr i) X x := by rw [hframe.repr_eq_inner' _ hx] simp [real, real_inner_comm] From 1206c72c250b201042fdf6eb847cb03e6eeccfac Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 15:19:53 +0200 Subject: [PATCH 246/601] chore: fix a few linter warnings --- .../Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 6 +++++- Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 27018791627d04..e0e6f875d13178 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -705,7 +705,7 @@ lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @[simp] -lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} (v : V x) : +lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} (v : V x) : extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in @@ -986,6 +986,8 @@ variable (X) in @[simp] lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp +set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer + variable (Y) in lemma torsion_add_left_apply [CompleteSpace E] {x : M} (hX : MDiffAt (T% X) x) @@ -1063,6 +1065,8 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] · intro σ τ τ' hτ hτ' exact cov.torsion_add_right_apply hτ hτ' +set_option linter.style.commandStart true + variable (cov) in /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ def IsTorsionFree : Prop := torsion cov = 0 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 374c912d92ac13..529caf3749368f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -227,7 +227,7 @@ variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] -- be named `coordChange` instead? lemma MDifferentiableWithinAt.change_section_trivialization {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] - {e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e'] + {e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) (he'f : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀) From 0b1fcb254830a204bb90e3f5dd21f7b41784a5b5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 16:15:05 +0200 Subject: [PATCH 247/601] chore(LeviCivita): re-order computation lemmas --- .../Manifold/VectorBundle/LeviCivita.lean | 112 +++++++++--------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 928c1559b0e96c..4264e10de4f0d4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -108,6 +108,17 @@ end product set_option linter.style.commandStart false -- custom elaborators not handled well yet +/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` +yields an error +synthesized type class instance is not definitionally equal to expression inferred by typing rules, +synthesized + fun x ↦ instNormedAddCommGroupOfRiemannianBundle x +inferred + fun b ↦ inst✝⁷ -/ +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := + MDifferentiable.inner_bundle hY hZ + namespace CovariantDerivative -- Let `cov` be a covariant derivative on `TM`. @@ -129,6 +140,52 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree variable (X Y Z) in noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x)) +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] + +variable (X Y Z Z') in +lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by + unfold rhs_aux + ext x + rw [product_add_right, mfderiv_add ((foo hY hZ) x) ((foo hY hZ') x)]; simp; congr + +omit [IsManifold I ∞ M] in +variable (X X' Y Z) in +lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by + ext x + simp [rhs_aux] + +variable (X Y Y' Z) in +lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : + rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by + ext x + simp only [rhs_aux] + rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] + simp; congr + +variable (X Y Z) in +lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by + ext x + simp [rhs_aux] + +variable (X Y Z) in +lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by + ext x + simp only [rhs_aux] + rw [product_smul_right] + -- XXX: not true, the product rule gives us two terms + -- and there is missing API in mathlib! + -- only holds given enough smoothness! + sorry + +variable (X Y Z Z') in +lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by + ext x + simp [rhs_aux] + rw [product_smul_left] + -- TODO: get a second term from the product rule! + sorry + -- XXX: inlining rhs_aux makes things not typecheck any more! variable (X Y Z) in @@ -191,61 +248,6 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` -yields an error -synthesized type class instance is not definitionally equal to expression inferred by typing rules, -synthesized - fun x ↦ instNormedAddCommGroupOfRiemannianBundle x -inferred - fun b ↦ inst✝⁷ -/ -variable {I} in -lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := - MDifferentiable.inner_bundle hY hZ - -variable (X Y Z Z') in -lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by - unfold rhs_aux - ext x - rw [product_add_right, mfderiv_add ((foo hY hZ) x) ((foo hY hZ') x)]; simp; congr - -omit [IsManifold I ∞ M] in -variable (X X' Y Z) in -lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by - ext x - simp [rhs_aux] - -variable (X Y Y' Z) in -lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : - rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by - ext x - simp only [rhs_aux] - rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] - simp; congr - -variable (X Y Z) in -lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by - ext x - simp only [rhs_aux] - rw [product_smul_right] - -- XXX: not true, the product rule gives us two terms - -- and there is missing API in mathlib! - -- only holds given enough smoothness! - sorry - -variable (X Y Z) in -lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by - ext x - simp [rhs_aux] - -variable (X Y Z Z') in -lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by - ext x - simp [rhs_aux] - rw [product_smul_left] - -- TODO: get a second term from the product rule! - sorry - lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by From afb81a1900e26d6e98144b84884efd04d16ac360 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 16:21:12 +0200 Subject: [PATCH 248/601] Golf a proof --- .../Manifold/VectorBundle/LeviCivita.lean | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 4264e10de4f0d4..5447733534cf71 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -140,6 +140,13 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree variable (X Y Z) in noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x)) +omit [IsManifold I ∞ M] in +lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by + ext x + simp only [rhs_aux] + congr + exact product_swap I Z Y + variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] variable (X Y Z Z') in @@ -163,31 +170,27 @@ lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] simp; congr +omit [IsManifold I ∞ M] in variable (X Y Z) in lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by ext x simp [rhs_aux] -variable (X Y Z) in -lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by - ext x - simp only [rhs_aux] - rw [product_smul_right] - -- XXX: not true, the product rule gives us two terms - -- and there is missing API in mathlib! - -- only holds given enough smoothness! - sorry - variable (X Y Z Z') in lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by ext x simp [rhs_aux] rw [product_smul_left] - -- TODO: get a second term from the product rule! + -- XXX: not true, the product rule gives us two terms + -- and there is missing API in mathlib! + -- only holds given enough smoothness! sorry --- XXX: inlining rhs_aux makes things not typecheck any more! +variable (X Y Z) in +lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by + rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap] +-- XXX: inlining rhs_aux here makes things not typecheck any more! variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If ∇ is a Levi-Civita connection on `TM`, then From 6c5ae39a1a0d6d191c70b7feb58b860777f332a8 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 11 Jul 2025 17:49:24 +0200 Subject: [PATCH 249/601] Refactor more covariant derivative stuff --- Mathlib/Geometry/Manifold/Elaborators.lean | 2 +- .../VectorBundle/CovariantDerivative.lean | 212 ++++++++++-------- 2 files changed, 119 insertions(+), 95 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 735be6cdf81696..248b33bc27e7a8 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -31,7 +31,7 @@ def _root_.Lean.Expr.getUniverse (e : Expr) : TermElabM (Level) := do @[match_pattern] def mkApp12 (f a b c d e g e₁ e₂ e₃ e₄ e₅ e₆ : Expr) := mkApp6 (mkApp6 f a b c d e g) e₁ e₂ e₃ e₄ e₅ e₆ -elab "T%" t:term : term => do +elab "T% " t:term : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars match etype with diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e0e6f875d13178..54e01f35153604 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -20,6 +20,37 @@ TODO: add a more complete doc-string -/ +section -- Building continuous bilinear maps + +structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] (f : E → F → G) : Prop where + add_left : ∀ (x₁ x₂ : E) (y : F), f (x₁ + x₂) y = f x₁ y + f x₂ y + smul_left : ∀ (c : R) (x : E) (y : F), f (c • x) y = c • f x y + add_right : ∀ (x : E) (y₁ y₂ : F), f x (y₁ + y₂) = f x y₁ + f x y₂ + smul_right : ∀ (c : R) (x : E) (y : F), f x (c • y) = c • f x y + +def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] {f : E → F → G} (hf : IsBilinearMap R f) : + E →ₗ[R] F →ₗ[R] G := + LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right + +def IsBilinearMap.toContinuousLinearMap + {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + {F : Type*} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] + {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] + [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] + {f : E → F → G} (h : IsBilinearMap 𝕜 f) : E →L[𝕜] F →L[𝕜] G := + IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) + (by constructor <;> (intros;simp)) |>.toContinuousLinearMap +end + open Bundle Filter Function Topology Set open scoped Bundle Manifold ContDiff @@ -118,6 +149,15 @@ structure IsCovariantDerivativeOn smul_const_σ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) {x} (hx : x ∈ s := by trivial) : f X (a • σ) x = a • f X σ x +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in +lemma IsCovariantDerivativeOn.smul_const_X + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {s : Set M} (h : IsCovariantDerivativeOn F V f s) {x} (a : 𝕜) + (X : Π x, TangentSpace I x) (σ : Π x, V x) (hx : x ∈ s := by trivial) : + f (a • X) σ x = a • f X σ x := + h.smulX .. + @[ext] structure CovariantDerivative where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) @@ -760,18 +800,51 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M apply _root_.contMDiff_section_of_smul_smoothBumpFunction _ ?_ t.open_baseSet hψ.1 le_rfl apply contMDiffOn_localExtensionOn _ hx +variable (F I) in omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : MDiff (T% extend I F σ₀) := contMDiff_extend σ₀ |>.mdifferentiable (by simp) +omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul ℝ (V x)] in +lemma isBilinearMap_differenceAux + [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] + [ContMDiffVectorBundle ∞ F V I] {s : Set M} {cov cov'} {x : M} + (hcov : IsCovariantDerivativeOn F V cov s) + (hcov' : IsCovariantDerivativeOn F V cov' s) (hx : x ∈ s := by trivial) : + IsBilinearMap ℝ (fun (X₀ : TangentSpace I x) (σ₀ : V x) ↦ + differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x) where + add_left u v w := by + simp only [differenceAux, extend_add, Pi.sub_apply, hcov.addX, hcov'.addX] + abel + add_right u v w := by + have hv := mdifferentiable_extend I F v x + have hw := mdifferentiable_extend I F w x + simp only [differenceAux, extend_add, Pi.sub_apply] + rw [hcov.addσ _ hv hw, hcov'.addσ _ hv hw] + abel + smul_left a u v := by + unfold differenceAux + simp only [extend_smul, Pi.sub_apply, hcov.smul_const_X, hcov'.smul_const_X] + module + smul_right a u v := by + unfold differenceAux + simp only [extend_smul, Pi.sub_apply, hcov.smul_const_σ, hcov'.smul_const_σ] + module + /-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference - [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I 1 M] - (cov cov' : CovariantDerivative I F V) : - Π x : M, TangentSpace I x → V x → V x := - fun x X₀ σ₀ ↦ differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x +noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] + [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] + [FiniteDimensional ℝ E] [ContMDiffVectorBundle ∞ F V I] + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {s : Set M} {x : M} + (hcov : IsCovariantDerivativeOn F V cov s) + (hcov' : IsCovariantDerivativeOn F V cov' s) + (hx : x ∈ s := by trivial) : TangentSpace I x →L[ℝ] V x →L[ℝ] V x := + haveI : FiniteDimensional ℝ (TangentSpace I x) := by assumption + (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap -- -- Note: we conciously register this lemma in unapplied form, -- -- but differenceAux_apply: this means the applied form should simplify down all the way, @@ -785,13 +858,32 @@ noncomputable def difference -- show? the map differenceAux to difference is injective -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -@[simp] -lemma difference_apply [FiniteDimensional ℝ F] [IsManifold I 1 M] [T2Space M] - (cov cov' : CovariantDerivative I F V) (x : M) (X₀ : TangentSpace I x) (σ₀ : V x) : - difference cov cov' x X₀ σ₀ = +lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] + [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] + [ContMDiffVectorBundle ∞ F V I] + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {s : Set M} {x : M} + (hcov : IsCovariantDerivativeOn F V cov s) + (hcov' : IsCovariantDerivativeOn F V cov' s) + (hx : x ∈ s := by trivial) (X₀ : TangentSpace I x) (σ₀ : V x) : + difference hcov hcov' hx X₀ σ₀ = cov (extend I E X₀) (extend I F σ₀) x - cov' (extend I E X₀) (extend I F σ₀) x := rfl +@[simp] +lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] + [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] + [ContMDiffVectorBundle ∞ F V I] + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {s : Set M} {x : M} + (hcov : IsCovariantDerivativeOn F V cov s) + (hcov' : IsCovariantDerivativeOn F V cov' s) + (hx : x ∈ s := by trivial) (X : Π x, TangentSpace I x) {σ : Π x, V x} + (hσ : MDiffAt (T% σ) x) : + difference hcov hcov' hx (X x) (σ x) = + cov X σ x - cov' X σ x := + hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hσ (extend_apply_self _) + (extend_apply_self _) hx + -- The classification of real connections over a trivial bundle section classification @@ -807,62 +899,6 @@ theorem contDiff_extend {E : Type*} rw [← contMDiffAt_iff_contDiffAt] simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') y x' -@[simps] -noncomputable def endomorph_of_trivial_aux [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] - (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x X : E) : E' →ₗ[ℝ] E' where - toFun := difference cov (CovariantDerivative.trivial E E') x X - map_add' y y' := by - have A : fderiv ℝ ((extend 𝓘(ℝ, E) E' y (x := x)) + extend 𝓘(ℝ, E) E' y' (x := x)) x = - fderiv ℝ (extend 𝓘(ℝ, E) E' y (x := x)) x + fderiv ℝ (extend 𝓘(ℝ, E) E' y' (x := x)) x := by - rw [fderiv_add] <;> exact (contDiff_extend x _).contDiffAt.differentiableAt (by simp) - have B : cov (extend 𝓘(ℝ, E) E X (x := x)) - (extend 𝓘(ℝ, E) E' y (x := x) + extend 𝓘(ℝ, E) E' y' (x := x)) x = - cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y (x := x)) x + - cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' y' (x := x)) x := by - apply cov.isCovariantDerivativeOn.addσ - · exact (contMDiff_extend _ _).mdifferentiableAt (n := ∞) (hn := by norm_num) - · apply (contMDiff_extend _ _).mdifferentiableAt (n := ∞) (hn := by norm_num) - simp [A, B] - module - map_smul' a v := by - have := cov.isCovariantDerivativeOn.smul_const_σ (extend 𝓘(ℝ, E) E X (x := x)) - (extend 𝓘(ℝ, E) E' v (x := x)) a (x := x) - simp [fderiv_const_smul_of_field, difference, this] - module - -@[simps!] -noncomputable def endomorph_of_trivial_aux' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] - (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x X : E) : E' →L[ℝ] E' where - toLinearMap := cov.endomorph_of_trivial_aux x X - cont := LinearMap.continuous_of_finiteDimensional _ - --- Not marked simp, as unfolding this is not always desirable. -noncomputable def endomorph_of_trivial_aux'' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] - (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x : E) : E →ₗ[ℝ] E' →L[ℝ] E' where - toFun X := cov.endomorph_of_trivial_aux' x X - map_add' X Y := by - ext Z - simp [cov.isCovariantDerivativeOn.addX (extend 𝓘(ℝ, E) E X (x := x)) - (extend 𝓘(ℝ, E) E Y (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x))] - module - map_smul' t X := by - ext Z - simp only [endomorph_of_trivial_aux'_apply, extend_smul, map_smul, RingHom.id_apply, - ContinuousLinearMap.coe_smul', Pi.smul_apply] - -- The following lines should ideally mold into the simp call above. - trans t • (cov (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) x) - - t • (fderiv ℝ (extend 𝓘(ℝ, E) E' Z (x := x)) x) X - swap; · module - have := cov.isCovariantDerivativeOn.smulX - (extend 𝓘(ℝ, E) E X (x := x)) (extend 𝓘(ℝ, E) E' Z (x := x)) (fun x ↦ t) (x := x) - simpa - -@[simps!] -noncomputable def endomorph_of_trivial_aux''' [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] - (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) (x : E) : E →L[ℝ] E' →L[ℝ] E' where - toLinearMap := cov.endomorph_of_trivial_aux'' x - cont := LinearMap.continuous_of_finiteDimensional _ - /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term @@ -880,25 +916,13 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] ∀ X : (x : E) → TangentSpace 𝓘(ℝ, E) x, ∀ σ : (x : E) → Trivial E E' x, ∀ x : E, MDiffAt (T% σ) x → cov X σ x = (CovariantDerivative.of_endomorphism A) X σ x := by - use cov.endomorph_of_trivial_aux''' + use fun x ↦ difference cov.isCovariantDerivativeOn + (CovariantDerivative.trivial E E').isCovariantDerivativeOn (mem_univ x) intro X σ x hσ - -- TODO: this is unfolding too much; need to fix this manually below... - -- think about a better design that actually works... - simp only [of_endomorphism, endomorph_of_trivial_aux'''_apply_apply] - rw [← CovariantDerivative.trivial_toFun] - have h₁ : cov X σ x - (trivial E E') X σ x = cov.difference (trivial E E') x (X x) (σ x) := by - -- Do not unfold differenceAux: we use the tensoriality of differenceAux. - rw [difference] - apply cov.isCovariantDerivativeOn.differenceAux_tensorial - (trivial E E').isCovariantDerivativeOn hσ ?_ (extend_apply_self (X x)).symm - (extend_apply_self (σ x)).symm - exact ((contMDiff_extend _).contMDiffAt).mdifferentiableAt (by norm_num) - have h₂ : cov.difference (trivial E E') x (X x) (σ x) = - cov (extend 𝓘(ℝ, E) E (X x)) (extend 𝓘(ℝ, E) E' (σ x)) x - - (fderiv ℝ (extend 𝓘(ℝ, E) E' (σ x) (x := x)) x) (X x) := by - simp - rw [← h₂, ← h₁] - module + simp only [of_endomorphism] + erw [difference_apply cov.isCovariantDerivativeOn + (CovariantDerivative.trivial E E').isCovariantDerivativeOn _ X hσ, trivial] + abel end classification @@ -922,20 +946,20 @@ end from_trivialization section horiz -def proj (cov : CovariantDerivative I F V) (e : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) e →L[ℝ] V e.proj := by +def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := by sorry -noncomputable def horiz (cov : CovariantDerivative I F V) (e : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) e) := - LinearMap.ker (cov.proj e) +noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := + LinearMap.ker (cov.proj v) -noncomputable def _root_.Bundle.vert (e : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) e) := - LinearMap.ker (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj e) +noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := + LinearMap.ker (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v) -lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (e : TotalSpace F V) : - IsCompl (cov.horiz e) (vert e) := by +lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + IsCompl (cov.horiz v) (vert v) := by sorry variable [IsManifold I 1 M] From 0f1cd55a36eee51f4b20c4b150eecbf908509eb7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 16:55:18 +0200 Subject: [PATCH 250/601] Make computations slightly less sketchy --- .../Manifold/VectorBundle/LeviCivita.lean | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 5447733534cf71..0d6506496a4c72 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -277,20 +277,32 @@ lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tang simp only [leviCivita_rhs] simp [rhs_aux_smulX, rhs_aux_smulY, rhs_aux_smulZ] ext x - simp only [Pi.mul_apply, /-Pi.inv_apply, Pi.ofNat_apply,-/ Pi.add_apply /-, Pi.sub_apply-/] - -- Only kind of true: get extra mfderiv's, which will cancel in the end... + simp only [Pi.mul_apply, Pi.add_apply] have h1 : VectorField.mlieBracket I X (f • Z) = - f • VectorField.mlieBracket I X Z := by + f • VectorField.mlieBracket I X Z + (fun x ↦ mfderiv I 𝓘(ℝ, ℝ) f x (X x)) • Z := by ext x - rw [VectorField.mlieBracket_smul_right (hf x) (hZ x)]; simp; sorry + rw [VectorField.mlieBracket_smul_right (hf x) (hZ x), add_comm] + simp have h2 : VectorField.mlieBracket I (f • Z) Y = - f • VectorField.mlieBracket I Z Y := by + -(fun x ↦ mfderiv I 𝓘(ℝ, ℝ) f x (Y x)) • Z + f • VectorField.mlieBracket I Z Y := by ext x - rw [VectorField.mlieBracket_smul_left (hf x) (hZ x)]; simp; sorry - simp [h1, h2] - rw [product_smul_left, product_smul_right] - simp only [Pi.smul_apply', smul_eq_mul]; abel_nf - sorry -- easy computation + rw [VectorField.mlieBracket_smul_left (hf x) (hZ x)] + simp + simp only [h1, Pi.smul_apply, Pi.sub_apply, Pi.add_apply, Pi.mul_apply, smul_eq_mul, h2] + set A := rhs_aux I X Y Z x + set B := rhs_aux I Y Z X x + set C := rhs_aux I Z X Y x + set D := (fun x ↦ (mfderiv I 𝓘(ℝ, ℝ) f x) (X x)) • Z + + rw [product_add_right, product_add_right] + -- These are all science fiction, and not fully true! + rw [product_smul_left, product_smul_right, product_smul_right] + set E := ⟪Z, VectorField.mlieBracket I X Y⟫ + set F := ⟪Y, VectorField.mlieBracket I X Z⟫ + set G := ⟪X, VectorField.mlieBracket I Z Y⟫ + -- apart from science fiction mistakes, this is "an easy computation" + simp; abel_nf + sorry variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all From 62e0d9fc50175a901104e7342c999cbb71e088f9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 17:16:08 +0200 Subject: [PATCH 251/601] feat: missing order instances Thanks, Aaron and Yael, for your help on zulip! --- .../Manifold/VectorBundle/LeviCivita.lean | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 0d6506496a4c72..8b200e257989b2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -307,20 +307,27 @@ lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tang variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ -lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} +-- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! +lemma congr_of_forall_product [FiniteDimensional ℝ E] {X X' : Π x : M, TangentSpace I x} (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by + classical ext x letI b := Basis.ofVectorSpace ℝ E letI t := trivializationAt E (TangentSpace I : M → Type _) x have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - -- TODO: think about this question and solve it somehow! - haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - haveI : WellFoundedLT ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - haveI : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g + have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry -- need to impose! + haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by + -- use Fin.instLinearOrder + sorry + haveI : OrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toOrderBot _ + haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by + apply Fintype.toLocallyFiniteOrder + haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + + -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g let real := b.orthonormalFrame t - have hframe := b.orthonormalFrame_isOrthonormalFrameOn (e := t) (F := E) (IB := I) (n := 1) + have hframe := b.orthonormalFrame_isOrthonormalFrameOn t (F := E) (IB := I) (n := 1) rw [hframe.eq_iff_repr hx] intro i have h₁ : ⟪X, real i⟫ x = (hframe.repr i) X x := by @@ -338,7 +345,8 @@ lemma congr_of_forall_product {X X' : Π x : M, TangentSpace I x} /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ -- (probably not everywhere, as addition rules apply only for differentiable vector fields?) -theorem isLeviCivita_uniqueness {cov cov' : CovariantDerivative I E (TangentSpace I : M → Type _)} +theorem isLeviCivita_uniqueness [FiniteDimensional ℝ E] + {cov cov' : CovariantDerivative I E (TangentSpace I : M → Type _)} (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) : -- almost, only agree on smooth functions cov = cov' := by From d0b0aee91ef4d252b405731c12ba37680f19bf44 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 17:56:09 +0200 Subject: [PATCH 252/601] chore: missing order instance (up to one sorry) --- .../Manifold/VectorBundle/LeviCivita.lean | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 8b200e257989b2..65db3b0aebda7f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -304,6 +304,32 @@ lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tang simp; abel_nf sorry +-- TODO: move to Algebra/Group/TransferInstance, around line 110 +section order + +variable {α β : Type*} (e : α ≃ β) + +protected abbrev _root_.Equiv.preorder [Preorder β] : Preorder α where + le a b := (e a) ≤ (e b) + le_refl a := le_refl (e a) + le_trans a b c h h' := Preorder.le_trans (e a) (e b) (e c) h h' + +def foo {α β : Type*} {a b : α} (f : α → β) (h : Decidable (a = b)) : Decidable (f a = f b) := by + sorry + +protected noncomputable abbrev _root_.Equiv.linearOrder [instβ: LinearOrder β] : LinearOrder α where + toPreorder := e.preorder + le_antisymm a b h h' := by + rw [← e.left_inv a, ← e.left_inv b, _root_.Equiv.toFun_as_coe, instβ.le_antisymm _ _ h h'] + le_total a b := instβ.le_total (e a) (e b) + toDecidableEq a b := by + rw [← e.left_inv a, ← e.left_inv b] + apply foo e.symm (instβ.toDecidableEq ..) + -- exact Classical.propDecidable (e.invFun ( + toDecidableLE a b := instβ.toDecidableLE .. + +end order + variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ From 9b18c4bf2669849680fe3f32752ab9b23994ba2d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 18:26:13 +0200 Subject: [PATCH 253/601] Virtually done with the order theory --- .../Manifold/VectorBundle/LeviCivita.lean | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 65db3b0aebda7f..dc7a773ef8fab9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -325,7 +325,6 @@ protected noncomputable abbrev _root_.Equiv.linearOrder [instβ: LinearOrder β] toDecidableEq a b := by rw [← e.left_inv a, ← e.left_inv b] apply foo e.symm (instβ.toDecidableEq ..) - -- exact Classical.propDecidable (e.invFun ( toDecidableLE a b := instβ.toDecidableLE .. end order @@ -336,16 +335,21 @@ vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ -- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! lemma congr_of_forall_product [FiniteDimensional ℝ E] {X X' : Π x : M, TangentSpace I x} (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by - classical + by_cases hE : Subsingleton E + · sorry ext x letI b := Basis.ofVectorSpace ℝ E letI t := trivializationAt E (TangentSpace I : M → Type _) x have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry -- need to impose! - haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by - -- use Fin.instLinearOrder - sorry + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := by + by_contra! + have : IsEmpty ↑(Basis.ofVectorSpaceIndex ℝ E) := not_nonempty_iff.mp this + have : Subsingleton E := by + sorry + apply hE this + haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := + Equiv.linearOrder (e := Fintype.equivFin ↑(Basis.ofVectorSpaceIndex ℝ E)) haveI : OrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toOrderBot _ haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by apply Fintype.toLocallyFiniteOrder From 233d0c06ffd54d941b5299b243d881d39f0826e0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 18:28:29 +0200 Subject: [PATCH 254/601] Complete definition of candidate of L-C connection. Overall, this is just missing - one last order theory sorry `foo` - some computations with torsion and too much defeq abuse - the non-emptiness sorry --- .../Manifold/VectorBundle/LeviCivita.lean | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index dc7a773ef8fab9..4087ff4b87431a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -351,8 +351,7 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] {X X' : Π x : M, Tangen haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Equiv.linearOrder (e := Fintype.equivFin ↑(Basis.ofVectorSpaceIndex ℝ E)) haveI : OrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toOrderBot _ - haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by - apply Fintype.toLocallyFiniteOrder + haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toLocallyFiniteOrder haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g @@ -393,10 +392,16 @@ noncomputable def existence_candidate_aux [FiniteDimensional ℝ E] (x : M) → TangentSpace I x := fun x ↦ -- Choose a trivialisation of TM near x. letI b := Basis.ofVectorSpace ℝ E - --letI t := trivializationAt E (TangentSpace I : M → Type _) x - -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g - -- TODO: this is only a local frame; not orthonormal yet! placeholder definition! - letI frame := b.localFrame e + -- Case distinction: if E is trivial, there is only one choice anyway; + -- otherwise, b must be non-trivial. + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance + haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := + Equiv.linearOrder (e := Fintype.equivFin ↑(Basis.ofVectorSpaceIndex ℝ E)) + haveI : OrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toOrderBot _ + haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toLocallyFiniteOrder + haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector ∇ X Y x w.r.t. s i -- is given by leviCivita_rhs X Y s i. ∑ i, ((leviCivita_rhs I X Y (frame i)) x) • (frame i x) @@ -407,17 +412,9 @@ variable (M) in the candidate definition for the Levi-Civita connection on `TM`. -/ noncomputable def existence_candidate [FiniteDimensional ℝ E] : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - fun X Y x ↦ - -- -- Choose a trivialisation of TM near x. - -- letI b := Basis.ofVectorSpace ℝ E - letI t := trivializationAt E (TangentSpace I : M → Type _) x - -- -- choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g - -- -- TODO: this is only a local frame; not orthonormal yet! placeholder definition! - -- letI frame := b.localFrame t - -- -- The coefficient of the desired tangent vector ∇ X Y x w.r.t. s i - -- -- is given by leviCivita_rhs X Y s i. - -- ∑ i, ((leviCivita_rhs I X Y (frame i)) x) • (frame i x) - existence_candidate_aux I X Y t x + -- Use the preferred trivialisation at x to write down a candidate for the existence. + -- to write down a candidate for the existence. + fun X Y x ↦ existence_candidate_aux I X Y (trivializationAt E (TangentSpace I : M → Type _) x) x variable (X Y) in -- The above definition behaves well: for each compatible trivialisation e, From d6635d90188260a67da263b8db08ec7f55faafb3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 11 Jul 2025 19:03:12 +0200 Subject: [PATCH 255/601] chore(CovariantDerivatives): move prerequisites to a new file ... which should be dissolved as well, but at least CovariantDerivatives becomes a bit clearer --- Mathlib.lean | 1 + .../VectorBundle/CovariantDerivative.lean | 88 +------------ .../Geometry/Manifold/VectorBundle/Misc.lean | 124 ++++++++++++++++++ 3 files changed, 126 insertions(+), 87 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Misc.lean diff --git a/Mathlib.lean b/Mathlib.lean index 494618e0be8c18..5b26e197b37fbf 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3735,6 +3735,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Hom import Mathlib.Geometry.Manifold.VectorBundle.LeviCivita import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorBundle.Misc import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Pullback import Mathlib.Geometry.Manifold.VectorBundle.Riemannian diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 54e01f35153604..4522cf69f8ffa3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -8,7 +8,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorBundle.Misc import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.Elaborators @@ -20,37 +20,6 @@ TODO: add a more complete doc-string -/ -section -- Building continuous bilinear maps - -structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] - [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] - [Module R E] [Module R F] [Module R G] (f : E → F → G) : Prop where - add_left : ∀ (x₁ x₂ : E) (y : F), f (x₁ + x₂) y = f x₁ y + f x₂ y - smul_left : ∀ (c : R) (x : E) (y : F), f (c • x) y = c • f x y - add_right : ∀ (x : E) (y₁ y₂ : F), f x (y₁ + y₂) = f x y₁ + f x y₂ - smul_right : ∀ (c : R) (x : E) (y : F), f x (c • y) = c • f x y - -def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] - [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] - [Module R E] [Module R F] [Module R G] {f : E → F → G} (hf : IsBilinearMap R f) : - E →ₗ[R] F →ₗ[R] G := - LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right - -def IsBilinearMap.toContinuousLinearMap - {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - {F : Type*} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] - {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] - [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] - {f : E → F → G} (h : IsBilinearMap 𝕜 f) : E →L[𝕜] F →L[𝕜] G := - IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) - (by constructor <;> (intros;simp)) |>.toContinuousLinearMap -end - open Bundle Filter Function Topology Set open scoped Bundle Manifold ContDiff @@ -75,61 +44,6 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] -- `V` vector bundle -section prerequisites - -def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where - toFun v := v - invFun v := v - map_add' := by simp - map_smul' := by simp - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -@[simp] -theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : - MDiffAt (T% σ) e ↔ - DifferentiableAt 𝕜 σ e := by - simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] - -attribute [simp] mdifferentiableAt_iff_differentiableAt - -lemma FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) - [TopologicalSpace B] [TopologicalSpace F] - (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] - [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := - (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] - [(x : M) → AddCommGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -variable {I F V x} in -/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -if one is differentiable at `x` then so is the other. -Issue: EventuallyEq does not work for dependent functions. -/ -lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ₁ : MDiffAt (T% σ) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : - MDiffAt (T% σ') x := by - apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ - -- TODO: split off a lemma? - apply Set.EqOn.eventuallyEq_of_mem _ hs - intro x hx - simp [hσ₂, hx] - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [(x : M) → AddCommGroup (V x)] in -variable {I F V x} in -/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -one is differentiable at `x` iff the other is. -/ -lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ : ∀ x ∈ s, σ x = σ' x) : - MDiffAt (T% σ) x ↔ - MDiffAt (T% σ') x := - ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, - fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ - -end prerequisites - variable {I} in structure IsCovariantDerivativeOn (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean new file mode 100644 index 00000000000000..4dbbdf00b05397 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -0,0 +1,124 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.Elaborators +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable + +/-! +# Miscellaneous pre-requisites for covariant derivatives + +TODO: this file should not exist; move everything in here to a proper place +(and PR it accordingly) + +-/ + +section -- Building continuous bilinear maps + +structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] (f : E → F → G) : Prop where + add_left : ∀ (x₁ x₂ : E) (y : F), f (x₁ + x₂) y = f x₁ y + f x₂ y + smul_left : ∀ (c : R) (x : E) (y : F), f (c • x) y = c • f x y + add_right : ∀ (x : E) (y₁ y₂ : F), f x (y₁ + y₂) = f x y₁ + f x y₂ + smul_right : ∀ (c : R) (x : E) (y : F), f x (c • y) = c • f x y + +def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] {f : E → F → G} (hf : IsBilinearMap R f) : + E →ₗ[R] F →ₗ[R] G := + LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right + +def IsBilinearMap.toContinuousLinearMap + {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + {F : Type*} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] + {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] + [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] + {f : E → F → G} (h : IsBilinearMap 𝕜 f) : E →L[𝕜] F →L[𝕜] G := + IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) + (by constructor <;> (intros;simp)) |>.toContinuousLinearMap + +end + +section prerequisites + +open Bundle Filter Function Topology Set + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] + -- `V` vector bundle + +def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where + toFun v := v + invFun v := v + map_add' := by simp + map_smul' := by simp + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +@[simp] +theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : + MDiffAt (T% σ) e ↔ + DifferentiableAt 𝕜 σ e := by + simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] + +attribute [simp] mdifferentiableAt_iff_differentiableAt + +lemma FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) + [TopologicalSpace B] [TopologicalSpace F] + (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] + [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := + (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [(x : M) → AddCommGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in +variable {I F V x} in +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +if one is differentiable at `x` then so is the other. +Issue: EventuallyEq does not work for dependent functions. -/ +lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) + (hσ₁ : MDiffAt (T% σ) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : + MDiffAt (T% σ') x := by + apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ + -- TODO: split off a lemma? + apply Set.EqOn.eventuallyEq_of_mem _ hs + intro x hx + simp [hσ₂, hx] + +omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [(x : M) → AddCommGroup (V x)] in +variable {I F V x} in +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +one is differentiable at `x` iff the other is. -/ +lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) + (hσ : ∀ x ∈ s, σ x = σ' x) : + MDiffAt (T% σ) x ↔ + MDiffAt (T% σ') x := + ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, + fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ + +end prerequisites From 292f2380cfebdd86f4acbc23e2f7834e832ee1e8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 01:33:41 +0200 Subject: [PATCH 256/601] Clean up order instances, following zulip discussion. --- .../Manifold/VectorBundle/LeviCivita.lean | 41 +++++-------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 4087ff4b87431a..d65d20308008f1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -304,30 +304,16 @@ lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tang simp; abel_nf sorry --- TODO: move to Algebra/Group/TransferInstance, around line 110 -section order +-- TODO: move to Data.Fintype.EquivFin +/-- Choose an arbitrary linear order on a `Fintype`: this is not an instance because in most +situations, choosing a linear order extending a given preorder, or a particular linear order +is preferred over choosing *any* linear order. -/ +noncomputable def Fintype.instLinearOrder {α : Type*} [Fintype α] : LinearOrder α := + LinearOrder.lift' _ (Fintype.equivFin α).injective -variable {α β : Type*} (e : α ≃ β) +section -protected abbrev _root_.Equiv.preorder [Preorder β] : Preorder α where - le a b := (e a) ≤ (e b) - le_refl a := le_refl (e a) - le_trans a b c h h' := Preorder.le_trans (e a) (e b) (e c) h h' - -def foo {α β : Type*} {a b : α} (f : α → β) (h : Decidable (a = b)) : Decidable (f a = f b) := by - sorry - -protected noncomputable abbrev _root_.Equiv.linearOrder [instβ: LinearOrder β] : LinearOrder α where - toPreorder := e.preorder - le_antisymm a b h h' := by - rw [← e.left_inv a, ← e.left_inv b, _root_.Equiv.toFun_as_coe, instβ.le_antisymm _ _ h h'] - le_total a b := instβ.le_total (e a) (e b) - toDecidableEq a b := by - rw [← e.left_inv a, ← e.left_inv b] - apply foo e.symm (instβ.toDecidableEq ..) - toDecidableLE a b := instβ.toDecidableLE .. - -end order +attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder Fintype.instLinearOrder variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all @@ -341,17 +327,12 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] {X X' : Π x : M, Tangen letI b := Basis.ofVectorSpace ℝ E letI t := trivializationAt E (TangentSpace I : M → Type _) x have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := by by_contra! have : IsEmpty ↑(Basis.ofVectorSpaceIndex ℝ E) := not_nonempty_iff.mp this have : Subsingleton E := by sorry apply hE this - haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := - Equiv.linearOrder (e := Fintype.equivFin ↑(Basis.ofVectorSpaceIndex ℝ E)) - haveI : OrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toOrderBot _ - haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toLocallyFiniteOrder haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g @@ -396,10 +377,6 @@ noncomputable def existence_candidate_aux [FiniteDimensional ℝ E] -- otherwise, b must be non-trivial. have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance - haveI : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := - Equiv.linearOrder (e := Fintype.equivFin ↑(Basis.ofVectorSpaceIndex ℝ E)) - haveI : OrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toOrderBot _ - haveI : LocallyFiniteOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Fintype.toLocallyFiniteOrder haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector ∇ X Y x w.r.t. s i @@ -429,6 +406,8 @@ lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] IsCovariantDerivativeOn E (TangentSpace I) (existence_candidate I M) e.baseSet := by sorry +end + -- deduce: this defines a covariant derivative -- TODO: make g part of the notation! From f5c20b8a2d8cfa2aad7ad3d2dc6e5b34697d3e73 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 01:44:39 +0200 Subject: [PATCH 257/601] Some glue sorries --- .../Manifold/VectorBundle/LeviCivita.lean | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index d65d20308008f1..9a6339731bf3fc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -408,21 +408,25 @@ lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] end --- deduce: this defines a covariant derivative - -- TODO: make g part of the notation! variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: this is unique up to the value on non-differentiable vector fields. If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ -def LeviCivitaConnection : CovariantDerivative I E (TangentSpace I : M → Type _) := +noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : + CovariantDerivative I E (TangentSpace I : M → Type _) where -- This is the existence part of the proof: take the formula derived above -- and prove it satisfies all the conditions. - - -- use isCovariantDerivativeOn_existence_candidate plus (future) API lemmas about - -- IsCovariantDerivativeOn - sorry - -lemma baz : (LeviCivitaConnection I M).IsLeviCivitaConnection := sorry + toFun := existence_candidate I M + isCovariantDerivativeOn := by + rw [← iUnion_source_chartAt H M] + let t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x + apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ + apply isCovariantDerivativeOn_existence_candidate I _ + +lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by + refine ⟨?_, ?_⟩ + · sorry -- compatible + · sorry -- torsion-free end CovariantDerivative From 65aede4ab78f264befac8de7d790f39c348b1779 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 01:49:10 +0200 Subject: [PATCH 258/601] workaround: solve one computation sorry, by avoid (2 : N)* A in favour of A + A --- .../Manifold/VectorBundle/LeviCivita.lean | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 9a6339731bf3fc..656a3ca35fb685 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -211,8 +211,8 @@ lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] lemma isolate_aux {α : Type*} [AddCommGroup α] - (X Y Z A D E F : α) (h : X + Y - Z = 2 * A + D + E - F) : - 2 * A = X + Y - Z - D - E + F := by + (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : + A + A = X + Y - Z - D - E + F := by trans (X + Y - Z) - D - E + F · rw [h]; abel · abel @@ -235,19 +235,15 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : have eq3 : rhs_aux I Z X Y = B + C + F := by simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] -- add (I) and (II), subtract (III) - have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = 2 * A + D + E - F := by - rw [eq1, eq2, eq3] - abel_nf - grind [zsmul_eq_mul, Int.cast_ofNat, Int.reduceNeg, neg_smul, one_smul] + have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by + rw [eq1, eq2, eq3]; abel -- solve for ⟪cov X Y, Z⟫ and obtain the claim simp only [leviCivita_rhs] -- - D - E + F ext x - -- sorry is because there are different "2"s here; - -- the first is a function M → ℝ, the second a natural number - have almost := isolate_aux (X := rhs_aux I X Y Z) (Y := rhs_aux I Y Z X) (Z := rhs_aux I Z X Y) - (A := A) (D := D) (E := E) (F := F) (h := by simp [this]; sorry) - sorry -- obvious: if 2 • A = stuff, A = 1/2 stuff + have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) + (by simp [this]) + sorry -- obvious: if A + A = stuff, A = 1/2 stuff variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] From 25c52a9aecbeea33f61959c3e5086bbd57d187e1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 09:49:44 +0200 Subject: [PATCH 259/601] doc: long doc-string for the custom elaborators --- Mathlib/Geometry/Manifold/Elaborators.lean | 52 +++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 248b33bc27e7a8..1e76146137e4c6 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -11,13 +11,60 @@ import Mathlib.Geometry.Manifold.Traces /-! # Elaborators for differential geometry -TODO: add a more complete doc-string +This file defines custom elaborators for differential geometry, to allow for more compact notation. +There are two classes of elaborators. The first provides more compact notation for differentiability +and continuous differentiability on manifolds, including inference of the model with corners. +They allow writing +- `MDiff f` for `MDifferentiable I J f` +- `MDiffAt f x` for `MDifferentiableAt I J f x` +- `MDiff[u] f` for `MDifferentiableOn I J f u` +- `MDiffAt[u] f` for `DifferentiableWithinAt I J f u x` +- `CMDiff n f` for `ContMDiff I J n f` +- `CMDiffAt n f x` for `ContMDiffAt I J n f x` +- `CMDiff[u] n f` for `ContMDiffOn I J n f u` +- `CMDiffAt[u] n f` for `ContMDiffWithinAt I J n f u x`. + +In each of these cases, the models with corners are inferred from the domain and codomain of `f`. +The search for models with corners uses the local context and is (almost) only syntactic, hence +hopefully fast enough to always run. + +Secondly, this space adds an elaborator to ease working with sections in a vector bundle, +converting a section `s : Π x : M, Π V x` to a non-dependent function into the total space of the +bundle. +```lean +-- omitted: let `V` be a vector bundle over `M` +variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} + +-- outputs `fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V` +#check T% σ + +-- outputs `fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E')` +-- Note how the name of the bound variable `x` is preserved. +#check T% σ' + +-- outputs `fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E')` +#check T% s +``` + +These elaborators can be combined: `CMDiffAt[u] n (T% s) x` + +**Warning.** These elaborators are a proof of concept; the implementation should be considered a +prototype. Don't rewrite all of mathlib to use it just yet. Notable bugs and limitations include +the following. + +## TODO +- extend the feature to infer e.g. models with corners on product manifolds + (this has to make a guess, hence cannot always be correct: but it could make the guess that + is correct 90% of the time) +- fix pretty-printing: currently, the `commandStart` linter expects some different formatting +- better error messages: forgetting e.g. the `T%` elaborator yields cryptic errors +- further testing and fixing of edge cases +- added tests for all of the above -/ open scoped Bundle Manifold ContDiff - section open Lean Meta Elab Tactic open Mathlib.Tactic @@ -31,6 +78,7 @@ def _root_.Lean.Expr.getUniverse (e : Expr) : TermElabM (Level) := do @[match_pattern] def mkApp12 (f a b c d e g e₁ e₂ e₃ e₄ e₅ e₆ : Expr) := mkApp6 (mkApp6 f a b c d e g) e₁ e₂ e₃ e₄ e₅ e₆ +-- TODO: document this elaborator, including its algorithm elab "T% " t:term : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars From 1800c3f533d84168a08a0655b6298f212105dd44 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 09:57:30 +0200 Subject: [PATCH 260/601] chore: remove two unused elaborators; tweak documentation --- Mathlib/Geometry/Manifold/Elaborators.lean | 28 ++----------------- .../VectorBundle/CovariantDerivative.lean | 1 + 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 1e76146137e4c6..060a761eb4ca98 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -58,7 +58,9 @@ the following. is correct 90% of the time) - fix pretty-printing: currently, the `commandStart` linter expects some different formatting - better error messages: forgetting e.g. the `T%` elaborator yields cryptic errors +- make all these elaborators scoped to the `Manifold` namespace - further testing and fixing of edge cases +- add test for the difference between `CMDiff` and `ContMDiff%` (and decide on one behaviour) - added tests for all of the above -/ @@ -283,17 +285,6 @@ elab:max "MDiff" t:term:arg : term => do return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] | _ => throwError m!"Term {e} is not a function." --- TODO: remove in favour of MDiff -elab:max "MDifferentiable%" t:term:arg : term => do - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] - | _ => throwError m!"Term {e} is not a function." - -- `CMDiffAt[s] n f` elaborates to `ContMDiffWithinAt I J n f s` elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none @@ -352,7 +343,7 @@ elab:max "CMDiff" nt:term:arg t:term:arg : term => do return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." --- TODO: remove in favour of CMDiff +-- TODO: remove in favour of CMDiff (after aligning their behaviour and adding a test for it!) elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none @@ -365,17 +356,4 @@ elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." --- TODO: remove in favour of CMDiffAt -elab:max "ContMDiffAt%" nt:term:arg t:term:arg : term => do - let e ← Term.elabTerm t none - let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTermEnsuringType nt wtn - let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] - | _ => throwError m!"Term {e} is not a function." - end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 4522cf69f8ffa3..6e794b658d4512 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -165,6 +165,7 @@ This is a class so typeclass inference can deduce this automatically. class _root_.IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, CMDiff (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → + -- TODO: CMDiff does not work here! ContMDiff% k (T% (cov X σ)) -- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection From ff070def6455b6d03c6cd95951ba9981d28c29e8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 10:02:57 +0200 Subject: [PATCH 261/601] More documentation for the elaborators --- Mathlib/Geometry/Manifold/Elaborators.lean | 42 ++++++++++++++++------ 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index 060a761eb4ca98..af964f4662e85a 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -28,11 +28,11 @@ In each of these cases, the models with corners are inferred from the domain and The search for models with corners uses the local context and is (almost) only syntactic, hence hopefully fast enough to always run. -Secondly, this space adds an elaborator to ease working with sections in a vector bundle, +Secondly, this space adds an elaborator to ease working with sections in a fibre bundle, converting a section `s : Π x : M, Π V x` to a non-dependent function into the total space of the bundle. ```lean --- omitted: let `V` be a vector bundle over `M` +-- omitted: let `V` be a fibre bundle over `M` variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} -- outputs `fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V` @@ -71,16 +71,28 @@ section open Lean Meta Elab Tactic open Mathlib.Tactic +/-- Try to infer the universe of an expression `e` -/ def _root_.Lean.Expr.getUniverse (e : Expr) : TermElabM (Level) := do if let .sort (.succ u) ← inferType e >>= instantiateMVars then return u else throwError m!"Could not find universe of {e}." +/-- Call `mkApp` recursively with 12 arguments -/ @[match_pattern] def mkApp12 (f a b c d e g e₁ e₂ e₃ e₄ e₅ e₆ : Expr) := mkApp6 (mkApp6 f a b c d e g) e₁ e₂ e₃ e₄ e₅ e₆ --- TODO: document this elaborator, including its algorithm +/-- Elaborator for sections in a fibre bundle: converts a section as a dependent function +to a non-dependent function into the total space. This handles the cases of +- sections of a trivial bundle +- vector fields on a manifold (i.e., sections of the tangent bundle) +- sections of an explicit fibre bundle +- turning a bare function `E → E'` into a section of the trivial bundle `Bundle.Trivial E E'` + +This elaborator operates purely syntactically, by analysing the local contexts for suitable +hypothesis for the above cases. Therefore, it is (hopefully) fast enough to always run. +-/ +-- TODO: document how this elaborator works, any gotchas, etc. elab "T% " t:term : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars @@ -119,9 +131,18 @@ elab "T% " t:term : term => do | _ => pure () return e --- Tests in MathlibTest/DifferentialGeometry/Elaborators.lean. +/-- Try to find a `ModelWithCorners` instance on an expression `e`, using the local context +to infer the expected type. This supports the following cases: +- the model with corners on the total space of a vector bundle +- a model with corners on a manifold +- the trivial model `𝓘(𝕜, E)` on a normed space +- if the above are not found, try to find a `NontriviallyNormedField` instance on the type of `e`, + and if successful, return `𝓘(𝕜)`. --- FIXME: better failure when trying to find a normedfield instance +Further cases can be added as necessary. +This implementation is not maximally robust yet, but already useful. +-/ +-- FIXME: better failure when trying to find a `NormedField` instance def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do trace[MDiffElab] m!"Searching a model for: {e}" if let mkApp3 (.const `Bundle.TotalSpace _) _ F V := e then @@ -219,9 +240,9 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM -- TODO: scope all these elaborators to the `Manifold` namespace --- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, --- trying to determine `I` and `J` from the local context. --- The argument x can be omitted. +/-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, +trying to determine `I` and `J` from the local context. +The argument x can be omitted. -/ elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none @@ -235,8 +256,9 @@ elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do return ← mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] | _ => throwError m!"Term {ef} is not a function." --- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, --- trying to determine `I` and `J` from the local context. +/-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, +trying to determine `I` and `J` from the local context. -/ +-- XXX: can `x` be omitted? elab:max "MDiffAt" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars From 0cf8c977dea885e72039a72883b66fdc9900e7ca Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 10:02:57 +0200 Subject: [PATCH 262/601] More documentation for the elaborators --- Mathlib/Geometry/Manifold/Elaborators.lean | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index af964f4662e85a..c49814b40dc9b7 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -257,8 +257,8 @@ elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do | _ => throwError m!"Term {ef} is not a function." /-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, -trying to determine `I` and `J` from the local context. -/ --- XXX: can `x` be omitted? +trying to determine `I` and `J` from the local context. +The argument `x` can be omitted. -/ elab:max "MDiffAt" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars @@ -280,8 +280,8 @@ elab:max "MDifferentiableAt%" t:term:arg : term => do return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] | _ => throwError m!"Term {e} is not a function." --- `MDiff[s] f` elaborates to `MDifferentiableOn I J f`, trying to determine `I` and `J` from the --- local context. +/-- `MDiff[s] f` elaborates to `MDifferentiableOn I J f`, +trying to determine `I` and `J` from the local context. -/ elab:max "MDiff[" s:term:arg "]" t:term:arg : term => do let es ← Term.elabTerm s none let et ← Term.elabTerm t none @@ -295,8 +295,8 @@ elab:max "MDiff[" s:term:arg "]" t:term:arg : term => do return ← mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] | _ => throwError m!"Term {et} is not a function." --- `MDiff f` elaborates to `MDifferentiable I J f`, --- trying to determine `I` and `J` from the local context. +/-- `MDiff f` elaborates to `MDifferentiable I J f`, +trying to determine `I` and `J` from the local context. -/ elab:max "MDiff" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars @@ -307,7 +307,9 @@ elab:max "MDiff" t:term:arg : term => do return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] | _ => throwError m!"Term {e} is not a function." --- `CMDiffAt[s] n f` elaborates to `ContMDiffWithinAt I J n f s` +-- TODO: say something about the expected type of `n` being in ℕ or WithTop ℕ∞! +/-- `CMDiffAt[s] n f` elaborates to `ContMDiffWithinAt I J n f s`, +trying to determine `I` and `J` from the local context. -/ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none @@ -323,7 +325,8 @@ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do return ← mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] | _ => throwError m!"Term {ef} is not a function." --- `CMDiffAt n f` elaborates to `ContMDiffAt I J n f s` +/-- `CMDiffAt n f` elaborates to `ContMDiffAt I J n f s` +trying to determine `I` and `J` from the local context. -/ elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none @@ -336,7 +339,8 @@ elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." --- `CMDiff[s] n f` elaborates to `ContMDiffOn I J n f s` +/-- `CMDiff[s] n f` elaborates to `ContMDiffOn I J n f s`, +trying to determine `I` and `J` from the local context. -/ elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none @@ -352,7 +356,8 @@ elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do return ← mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] | _ => throwError m!"Term {ef} is not a function." --- `CMDiff n f` elaborates to `ContMDiff I J n f` +/-- `CMDiff n f` elaborates to `ContMDiff I J n f`, +trying to determine `I` and `J` from the local context. -/ elab:max "CMDiff" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none From 5ccfc4110cbd9e196930a5c304037f18b8ac6340 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 10:41:42 +0200 Subject: [PATCH 263/601] chore: add (failing) test for another elaborator quirk --- .../DifferentialGeometry/Elaborators.lean | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/MathlibTest/DifferentialGeometry/Elaborators.lean b/MathlibTest/DifferentialGeometry/Elaborators.lean index 352b7873e7a6f0..66bf1c5a8806a0 100644 --- a/MathlibTest/DifferentialGeometry/Elaborators.lean +++ b/MathlibTest/DifferentialGeometry/Elaborators.lean @@ -44,6 +44,45 @@ variable {σ : Π x : M, V x} #guard_msgs in #check T% σ +set_option linter.style.commandStart true + +-- TODO: investigate this! +/-- +error: Application type mismatch: In the application + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) Set.univ +the argument + Set.univ +has type + Set.{?u.13540} ?m.13541 : Type ?u.13540 +but is expected to have type + Set.{u_4} M : Type u_4 +-/ +#guard_msgs in +example {x : M} : MDiffAt[Set.univ] (T% σ) x := sorry + +-- Interaction with auto-implicits. +/-- +error: Application type mismatch: In the application + MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) Set.univ +the argument + Set.univ +has type + Set.{?u.17364} ?m.17365 : Type ?u.17364 +but is expected to have type + Set.{u_4} M : Type u_4 +-/ +#guard_msgs in +set_option autoImplicit true in +example : MDiffAt[Set.univ] (T% σ) x := sorry + +/-- warning: declaration uses 'sorry' -/ +#guard_msgs in +example {x : M} : MDiffAt[(Set.univ : Set M)] (T% σ) x := sorry + +/-- warning: declaration uses 'sorry' -/ +#guard_msgs in +example {u : Set M} {x : M} : CMDiffAt[u] 2 (T% σ) x := sorry + -- Note how the name of the bound variable `x` resp. `y` is preserved. /-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ #guard_msgs in From 5dd96f317607177d543abc8a59f97f1d61b6d7a4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 14:50:50 +0200 Subject: [PATCH 264/601] Further scaffolding towards existence --- .../Manifold/VectorBundle/LeviCivita.lean | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 656a3ca35fb685..a0512ad0babcae 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -363,10 +363,10 @@ theorem isLeviCivita_uniqueness [FiniteDimensional ℝ E] · exact cov.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov · exact (cov'.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov').symm -variable (X Y) in -noncomputable def existence_candidate_aux [FiniteDimensional ℝ E] +noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - (x : M) → TangentSpace I x := fun x ↦ + ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := + fun X Y x ↦ -- Choose a trivialisation of TM near x. letI b := Basis.ofVectorSpace ℝ E -- Case distinction: if E is trivial, there is only one choice anyway; @@ -383,23 +383,29 @@ variable (M) in -- TODO: make g part of the notation! /-- Given two vector fields X and Y on TM, compute the candidate definition for the Levi-Civita connection on `TM`. -/ -noncomputable def existence_candidate [FiniteDimensional ℝ E] : +noncomputable def lcCandidate [FiniteDimensional ℝ E] : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := -- Use the preferred trivialisation at x to write down a candidate for the existence. -- to write down a candidate for the existence. - fun X Y x ↦ existence_candidate_aux I X Y (trivializationAt E (TangentSpace I : M → Type _) x) x + fun X Y x ↦ lcCandidate_aux I (trivializationAt E (TangentSpace I : M → Type _) x) X Y x variable (X Y) in -- The above definition behaves well: for each compatible trivialisation e, -- using e on e.baseSet yields the same result as above. lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) : - existence_candidate I M X Y x = existence_candidate_aux I X Y e x := sorry + lcCandidate I M X Y x = lcCandidate_aux I e X Y x := sorry + +-- The candidate definition is a covariant derivative on each local frame's domain. +lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : + IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate_aux I (M := M) e) e.baseSet := by + sorry -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn E (TangentSpace I) (existence_candidate I M) e.baseSet := by + IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate I M) e.baseSet := by sorry end @@ -413,7 +419,7 @@ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : CovariantDerivative I E (TangentSpace I : M → Type _) where -- This is the existence part of the proof: take the formula derived above -- and prove it satisfies all the conditions. - toFun := existence_candidate I M + toFun := lcCandidate I M isCovariantDerivativeOn := by rw [← iUnion_source_chartAt H M] let t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x From 33620b28f064b6b770a8724a9a3c7c7e3e4d24c5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 12 Jul 2025 15:14:41 +0200 Subject: [PATCH 265/601] Boilerplate for the covariant derivative, first condition --- .../Manifold/VectorBundle/LeviCivita.lean | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index a0512ad0babcae..182378b1358267 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -202,6 +202,8 @@ noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • ( + ⟪X, (VectorField.mlieBracket I Z Y)⟫ ) +-- XXX: is introducing leviCivita_rhs' which is twice the previous quantity useful? + variable (X Y Z) in lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by @@ -247,7 +249,26 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] +variable (X X' Y Z) in +lemma leviCivita_rhs_addX' : (2 : ℝ) • leviCivita_rhs I (X + X') Y Z = + (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y Z := by + have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp + simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] + -- Now, continue without the scalar multiplication. + -- similar to the addZ proof below... + sorry + +variable (X X' Y Z) in +lemma leviCivita_rhs_addX : leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by + sorry -- divide the previous equation by 2 + +variable (X Y Z) in +lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : + leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by + -- TODO: do I need to assume X is differentiable? + sorry + +lemma leviCivita_rhs_addZ (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by -- A bit too painful, and have missing differentiability assumptions. @@ -267,7 +288,7 @@ lemma leviCivita_rhs_add (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] simp [h1, h2, rhs_aux_addX] -- rhs_aux_addY, rhs_aux_addZ sorry -- module -lemma leviCivita_rhs_smul [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} +lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs] @@ -399,14 +420,40 @@ lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate_aux I (M := M) e) e.baseSet := by - sorry + IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate_aux I (M := M) e) e.baseSet where + addX X X' σ x := by + intro hx + unfold lcCandidate_aux + simp [← Finset.sum_add_distrib, ← add_smul, leviCivita_rhs_addX] + smulX X σ g x hx := by + unfold lcCandidate_aux + dsimp + have hX : MDiff (T% X) := sorry -- might need this (hopefully not!) + have hg : MDiff g := sorry -- might need this (hopefully not!) + rw [Finset.smul_sum] + congr; ext i + rw [leviCivita_rhs_smulX _ _ _ _ hg hX] + simp [← smul_assoc] + smul_const_σ X σ a x hx := by + unfold lcCandidate_aux + dsimp + rw [Finset.smul_sum]; congr; ext i + -- want leviCivita_rhs_smulY (with a constant) + sorry + addσ X σ σ' x hσ hσ' hx := by + unfold lcCandidate_aux + dsimp + simp [← Finset.sum_add_distrib, ← add_smul] + -- want leviCivita_addY + sorry + leibniz := by + sorry -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate I M) e.baseSet := by - sorry + sorry -- need some IsCovariantDerivativeOn_congr + lemma bar end From 2f22266e9507d66c4a6c52649adeb43f164117b0 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Sun, 13 Jul 2025 17:49:25 +0200 Subject: [PATCH 266/601] Some more generalization to all trivial bundles --- .../VectorBundle/CovariantDerivative.lean | 88 +++++++++++++++---- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 6e794b658d4512..77756b81eac1e5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -352,33 +352,86 @@ lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset -- Future: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] +section trivial_bundle + +omit [IsManifold I 0 M] in +lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : + mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by + by_cases hs : MDifferentiableAt% s x + · have hs' := hs.const_smul a + suffices + (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = + a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) + (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] + change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ + rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] + rfl + · by_cases ha : a = 0 + · have : a • s = 0 := by ext; simp [ha] + rw [this, ha] + change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ + simp + have hs' : ¬ MDifferentiableAt I 𝓘(𝕜, F) (a • s) x := + fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) + rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] + simp + rfl + +lemma mfderiv_smul {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) + (hs : MDiffAt s x) (v : TangentSpace I x) : + letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v + letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v + mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by + sorry -variable (E E') in -/-- The trivial connection on a trivial bundle, given by the directional derivative -/ +variable (I M F) in @[simps] -noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' - (Bundle.Trivial E E') where - toFun X s := fun x ↦ fderiv 𝕜 s x (X x) +noncomputable def trivial : CovariantDerivative I F (Trivial M F) where + toFun X s := fun x ↦ mfderiv I 𝓘(𝕜, F) s x (X x) isCovariantDerivativeOn := { addX X X' σ x _ := by simp smulX X σ c' x _ := by simp addσ X σ σ' x hσ hσ' hx := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' - rw [fderiv_add hσ hσ'] + rw [mdifferentiableAt_section] at hσ hσ' + -- TODO: specialize mdifferentiableAt_section to trivial bundles? + change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ + change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' + rw [mfderiv_add hσ hσ'] rfl - smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] + smul_const_σ X σ a x hx := by + rw [mfderiv_const_smul] leibniz X σ f x hσ hf hx := by - have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := - fderiv_smul (by simp_all) (by simp_all) - simp [this, bar] - rfl } + rw [mdifferentiableAt_section] at hσ + exact mfderiv_smul hσ hf (X x) } +end trivial_bundle + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +-- variable (E E') in +-- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ +-- @[simps] +-- noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' +-- (Bundle.Trivial E E') where +-- toFun X s := fun x ↦ fderiv 𝕜 s x (X x) +-- isCovariantDerivativeOn := +-- { addX X X' σ x _ := by simp +-- smulX X σ c' x _ := by simp +-- addσ X σ σ' x hσ hσ' hx := by +-- rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' +-- rw [fderiv_add hσ hσ'] +-- rfl +-- smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] +-- leibniz X σ f x hσ hf hx := by +-- have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := +-- fderiv_smul (by simp_all) (by simp_all) +-- simp [this, bar] +-- rfl } -- TODO: does it make sense to speak of analytic connections? if so, change the definition of -- regularity and use ∞ from `open scoped ContDiff` instead. /-- The trivial connection on the trivial bundle is smooth -/ -lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial E E') (⊤ : ℕ∞) where +lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where regularity {X σ} hX hσ := by -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well simp only [trivial] @@ -832,12 +885,13 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] MDiffAt (T% σ) x → cov X σ x = (CovariantDerivative.of_endomorphism A) X σ x := by use fun x ↦ difference cov.isCovariantDerivativeOn - (CovariantDerivative.trivial E E').isCovariantDerivativeOn (mem_univ x) + (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn (mem_univ x) intro X σ x hσ simp only [of_endomorphism] erw [difference_apply cov.isCovariantDerivativeOn - (CovariantDerivative.trivial E E').isCovariantDerivativeOn _ X hσ, trivial] - abel + (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn _ X hσ, trivial] + simp only [mfderiv_eq_fderiv] + module end classification From 175e4f8ea08e3e26f5fc95a7d3237b8098618ca8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 13 Jul 2025 22:31:05 +0200 Subject: [PATCH 267/601] Some inessential sorries --- .../VectorBundle/CovariantDerivative.lean | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 77756b81eac1e5..5ea79a71ad6700 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -287,15 +287,23 @@ def _root_.IsCovariantDerivativeOn.convexCombination' {ι : Type*} {s : Finset leibniz X σ g x hσ hg hx := by calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x - + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := - sorry -- rewrite using (cov i).leibniz - _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x - + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x) := by + + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x) := by + congr + ext i + rw [(h i).leibniz _ hσ hg] + simp_rw [Pi.smul_apply', smul_add, add_left_inj] + rw [smul_comm] + _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x) + + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by rw [Finset.sum_add_distrib] - simp; sorry - _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜, 𝕜) g x) (X x)) • σ x := - -- use hf and pull out g... - sorry + _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by + -- There has to be a shorter proof! + simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, add_right_inj] + set B := (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x + trans (∑ i ∈ s, f i x) • B + · rw [Finset.sum_smul] + have : ∑ i ∈ s, f i x = 1 := by convert congr_fun hf x; simp + rw [this, one_smul] simp /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ From eefafa1007c78a8c02d1af90ae8033a580bda42a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 13 Jul 2025 22:45:03 +0200 Subject: [PATCH 268/601] Cleanup, smooth bump function lemmas One lemmas has upstreamed property; remove its old version from CovariantDerivatives. Move its unused cousin to SmoothSection also, and generalise it to match. --- .../VectorBundle/CovariantDerivative.lean | 34 +------------------ .../Manifold/VectorBundle/SmoothSection.lean | 11 ++++++ 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 5ea79a71ad6700..05bedfd010667e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -730,38 +730,6 @@ omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ simpa [extend] using localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -/-- If `ψ: M → ℝ` a smooth bump function and `s` is a section of a smooth vector bundle `V → M`, -the scalar product `ψ s` is `C^n` if `s` is `C^n` on an open set containing `tsupport ψ`. -This is a vector bundle analogue of `contMDiff_of_tsupport`: the total space of `V` has no zero, -but we only consider sections of the form `ψ s`. -/ -lemma _root_.contMDiff_section_of_smul_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] - {s : Π (x : M), V x} {ψ : SmoothBumpFunction I x} {t : Set M} - (hs : ContMDiffOn I (I.prod 𝓘(ℝ, F)) n (T% s) t) - (ht : IsOpen t) (ht' : tsupport ψ ⊆ t) (hn : n ≤ ∞) : - ContMDiff I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) := by - apply contMDiff_of_contMDiffOn_union_of_isOpen - ((ψ.contMDiff.of_le hn).contMDiffOn.smul_section hs) ?_ ?_ ht - (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) - · apply ((contMDiff_zeroSection _ _).contMDiffOn (s := (tsupport ψ)ᶜ)).congr - intro y hy - simp [image_eq_zero_of_notMem_tsupport hy, zeroSection] - · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr ht' - --- unused, but might be nice to have -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -/-- If `ψ: M → ℝ` a smooth bump function and `s` is a section of a smooth vector bundle `V → M`, -the scalar product `ψ s` is `C^n` if `s` is `C^n` at each `x ∈ tsupport ψ`. -This is a vector bundle analogue of `contMDiff_of_tsupport`: the total space of `V` has no zero, -but we only consider sections of the form `ψ s`. -/ -lemma _root_.contMDiff_section_of_smul_smoothBumpFunction' [T2Space M] [IsManifold I ∞ M] - {s : Π (x : M), V x} {ψ : SmoothBumpFunction I x} (hn : n ≤ ∞) - (hs : ∀ x ∈ tsupport ψ, - ContMDiffAt I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) n (T% fun x ↦ (ψ x • s x)) := by - -- apply contMDiff_of_smul_smoothBumpFunction (s := s) (hn := hn) --?_ ?_ ?_ ?_ - sorry - omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : @@ -773,7 +741,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M -- XXX: extract ψ and hψ as helper declarations, perhaps private to prevent API leakage? let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - apply _root_.contMDiff_section_of_smul_smoothBumpFunction _ ?_ t.open_baseSet hψ.1 le_rfl + apply ψ.contMDiff.contMDiffOn.smul_section_of_tsupport t.open_baseSet hψ.1 apply contMDiffOn_localExtensionOn _ hx variable (F I) in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 9b9bc91234b34d..4e3c16dd517f3d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -227,6 +227,17 @@ lemma ContMDiffOn.smul_section_of_tsupport {s : Π (x : M), V x} {ψ : M → simp [image_eq_zero_of_notMem_tsupport hy, zeroSection] · exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr ht' +-- unused +/-- The scalar product `ψ • s` of a `C^k` function `ψ: M → 𝕜` and a section `s` of a vector +bundle `V → M` is `C^k` once `s` is `C^k` at each point in `tsupport ψ`. + +This is a vector bundle analogue of `contMDiff_of_tsupport`. -/ +lemma ContMDiffOn.smul_section_of_tsupport' {s : Π (x : M), V x} {ψ : M → 𝕜} {u : Set M} + (hs : ∀ x ∈ tsupport ψ, + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) x) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by + sorry + end operations /-- Bundled `n` times continuously differentiable sections of a vector bundle. From dcf0db8c179537145971d6fe48d6c61358e7990e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 13 Jul 2025 22:49:19 +0200 Subject: [PATCH 269/601] Minor --- Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 05bedfd010667e..7e3538a920a44b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -738,7 +738,6 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - -- XXX: extract ψ and hψ as helper declarations, perhaps private to prevent API leakage? let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht apply ψ.contMDiff.contMDiffOn.smul_section_of_tsupport t.open_baseSet hψ.1 From 3a1842cf20e649f20ef022831644f0e1098e706e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 13 Jul 2025 23:03:19 +0200 Subject: [PATCH 270/601] Use product rule for mfderiv in LeviCivita. --- .../Manifold/VectorBundle/LeviCivita.lean | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 182378b1358267..4e42a411aa2df3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -149,13 +149,6 @@ lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -variable (X Y Z Z') in -lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by - unfold rhs_aux - ext x - rw [product_add_right, mfderiv_add ((foo hY hZ) x) ((foo hY hZ') x)]; simp; congr - omit [IsManifold I ∞ M] in variable (X X' Y Z) in lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by @@ -170,6 +163,13 @@ lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] simp; congr +variable (X Y Z Z') in +lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by + unfold rhs_aux + ext x + rw [product_add_right, mfderiv_add ((foo hY hZ) x) ((foo hY hZ') x)]; simp; congr + omit [IsManifold I ∞ M] in variable (X Y Z) in lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by @@ -177,18 +177,19 @@ lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I simp [rhs_aux] variable (X Y Z Z') in -lemma rhs_aux_smulY (f : M → ℝ) : rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z := by +lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + letI A (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) + rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by ext x - simp [rhs_aux] - rw [product_smul_left] - -- XXX: not true, the product rule gives us two terms - -- and there is missing API in mathlib! - -- only holds given enough smoothness! - sorry + rw [rhs_aux, product_smul_left, mfderiv_smul (foo hY hZ x) (hf x)] + congr variable (X Y Z) in -lemma rhs_aux_smulZ (f : M → ℝ) : rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z := by - rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap] +lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + letI A (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) + rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by + rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] + exacts [hf, hZ, hY] -- XXX: inlining rhs_aux here makes things not typecheck any more! variable (X Y Z) in @@ -259,7 +260,8 @@ lemma leviCivita_rhs_addX' : (2 : ℝ) • leviCivita_rhs I (X + X') Y Z = sorry variable (X X' Y Z) in -lemma leviCivita_rhs_addX : leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by +lemma leviCivita_rhs_addX : leviCivita_rhs I (X + X') Y Z = + leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by sorry -- divide the previous equation by 2 variable (X Y Z) in @@ -292,7 +294,7 @@ lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tan (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs] - simp [rhs_aux_smulX, rhs_aux_smulY, rhs_aux_smulZ] + simp [rhs_aux_smulX]--, rhs_aux_smulY, rhs_aux_smulZ] ext x simp only [Pi.mul_apply, Pi.add_apply] have h1 : VectorField.mlieBracket I X (f • Z) = From 531218b458b5394758c85141cb82ff52ed2f0f8d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 14 Jul 2025 10:11:39 +0200 Subject: [PATCH 271/601] chore(LeviCivita): put big computations into separate sections --- .../Manifold/VectorBundle/LeviCivita.lean | 96 +++++++++++-------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 4e42a411aa2df3..47e12d1cdfd2de 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -140,6 +140,8 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree variable (X Y Z) in noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x)) +section rhs_aux + omit [IsManifold I ∞ M] in lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by ext x @@ -191,6 +193,8 @@ lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDi rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] +end rhs_aux + -- XXX: inlining rhs_aux here makes things not typecheck any more! variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: @@ -205,48 +209,7 @@ noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • ( -- XXX: is introducing leviCivita_rhs' which is twice the previous quantity useful? -variable (X Y Z) in -lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = - ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by - trans ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ - · ext x - exact h.1 X Y Z x - · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] - -lemma isolate_aux {α : Type*} [AddCommGroup α] - (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : - A + A = X + Y - Z - D - E + F := by - trans (X + Y - Z) - D - E + F - · rw [h]; abel - · abel - -variable (X Y Z) in -/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term -⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ -lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : - ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by - set A := ⟪cov X Y, Z⟫ - set B := ⟪cov Z X, Y⟫ - set C := ⟪cov Y Z, X⟫ - set D := ⟪Y, VectorField.mlieBracket I X Z⟫ with D_eq - set E := ⟪Z, VectorField.mlieBracket I Y X⟫ with E_eq - set F := ⟪X, VectorField.mlieBracket I Z Y⟫ with F_eq - have eq1 : rhs_aux I X Y Z = A + B + D := by - simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (cov Z X)] - have eq2 : rhs_aux I Y Z X = C + A + E := by - simp only [aux I Y Z X cov h, A, C, E, product_swap _ (cov X Y) Z] - have eq3 : rhs_aux I Z X Y = B + C + F := by - simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] - -- add (I) and (II), subtract (III) - have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by - rw [eq1, eq2, eq3]; abel - - -- solve for ⟪cov X Y, Z⟫ and obtain the claim - simp only [leviCivita_rhs] -- - D - E + F - ext x - have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) - (by simp [this]) - sorry -- obvious: if A + A = stuff, A = 1/2 stuff +section leviCivita_rhs variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] @@ -323,6 +286,51 @@ lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, Tan simp; abel_nf sorry +end leviCivita_rhs + +variable (X Y Z) in +lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = + ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by + trans ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ + · ext x + exact h.1 X Y Z x + · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] + +lemma isolate_aux {α : Type*} [AddCommGroup α] + (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : + A + A = X + Y - Z - D - E + F := by + trans (X + Y - Z) - D - E + F + · rw [h]; abel + · abel + +variable (X Y Z) in +/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term +⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ +lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : + ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by + set A := ⟪cov X Y, Z⟫ + set B := ⟪cov Z X, Y⟫ + set C := ⟪cov Y Z, X⟫ + set D := ⟪Y, VectorField.mlieBracket I X Z⟫ with D_eq + set E := ⟪Z, VectorField.mlieBracket I Y X⟫ with E_eq + set F := ⟪X, VectorField.mlieBracket I Z Y⟫ with F_eq + have eq1 : rhs_aux I X Y Z = A + B + D := by + simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (cov Z X)] + have eq2 : rhs_aux I Y Z X = C + A + E := by + simp only [aux I Y Z X cov h, A, C, E, product_swap _ (cov X Y) Z] + have eq3 : rhs_aux I Z X Y = B + C + F := by + simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] + -- add (I) and (II), subtract (III) + have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by + rw [eq1, eq2, eq3]; abel + + -- solve for ⟪cov X Y, Z⟫ and obtain the claim + simp only [leviCivita_rhs] -- - D - E + F + ext x + have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) + (by simp [this]) + sorry -- obvious: if A + A = stuff, A = 1/2 stuff + -- TODO: move to Data.Fintype.EquivFin /-- Choose an arbitrary linear order on a `Fintype`: this is not an instance because in most situations, choosing a linear order extending a given preorder, or a particular linear order @@ -334,6 +342,8 @@ section attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder Fintype.instLinearOrder +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] + variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ @@ -459,6 +469,8 @@ lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] end +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] + -- TODO: make g part of the notation! variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: From c7ebb9e4f51992c6935bb6f811b491fce12a47e2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 14 Jul 2025 10:34:40 +0200 Subject: [PATCH 272/601] chore/feat(LeviCivita): fix variable implicitness, re-use variables --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 47e12d1cdfd2de..4c543d71cc6519 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -157,7 +157,7 @@ lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z ext x simp [rhs_aux] -variable (X Y Y' Z) in +variable (X) in lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by ext x @@ -165,7 +165,7 @@ lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] simp; congr -variable (X Y Z Z') in +variable (X) in lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by unfold rhs_aux @@ -178,7 +178,7 @@ lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I ext x simp [rhs_aux] -variable (X Y Z Z') in +variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : letI A (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by @@ -186,7 +186,7 @@ lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDi rw [rhs_aux, product_smul_left, mfderiv_smul (foo hY hZ x) (hf x)] congr -variable (X Y Z) in +variable (X) in lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : letI A (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by @@ -348,7 +348,7 @@ variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ -- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! -lemma congr_of_forall_product [FiniteDimensional ℝ E] {X X' : Π x : M, TangentSpace I x} +lemma congr_of_forall_product [FiniteDimensional ℝ E] (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by by_cases hE : Subsingleton E · sorry From a9a88586fa1d897b0d2e1104fe8eddccf31a0af2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 14 Jul 2025 10:35:01 +0200 Subject: [PATCH 273/601] feat: complete leviCivita_addZ computation --- .../Manifold/VectorBundle/LeviCivita.lean | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 4c543d71cc6519..34e2b0e7682b9f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -233,28 +233,48 @@ lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : -- TODO: do I need to assume X is differentiable? sorry -lemma leviCivita_rhs_addZ (Z Z' : Π x : M, TangentSpace I x) [CompleteSpace E] - (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by - -- A bit too painful, and have missing differentiability assumptions. - simp only [leviCivita_rhs] - set A : M → ℝ := (1 : M → ℝ) / 2 - --rw [← left_distrib] - --apply congrArg +variable (X Z) in +lemma leviCivita_rhs_addY' [CompleteSpace E] (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) : + (2 : ℝ) • leviCivita_rhs I X (Y + Y') Z = + (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y' Z := by + have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp + simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] + -- continue without scalar multiplication + sorry + +variable (X Z) in +lemma leviCivita_rhs_addY [CompleteSpace E] (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) : + leviCivita_rhs I X (Y + Y') Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y' Z := by + sorry -- divide the previous equation by 2 + +lemma leviCivita_rhs_addZ' [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + (2 : ℝ) • leviCivita_rhs I X Y (Z + Z') = + (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y Z' := by + have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp + simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] + -- continue without scalar multiplication ext x - have h1 : VectorField.mlieBracket I X (Z + Z') = + have h : VectorField.mlieBracket I X (Z + Z') = VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := by ext x simp [VectorField.mlieBracket_add_right (V := X) (hZ x) (hZ' x)] - have h2 : VectorField.mlieBracket I (Z + Z') Y = + have h' : VectorField.mlieBracket I (Z + Z') Y = VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z' Y := by ext x simp [VectorField.mlieBracket_add_left (W := Y) (hZ x) (hZ' x)] - simp [h1, h2, rhs_aux_addX] -- rhs_aux_addY, rhs_aux_addZ - sorry -- module + simp only [rhs_aux_addX, h, h', Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_addY, rhs_aux_addZ] <;> try assumption + rw [product_add_left, product_add_right, product_add_right] + simp only [Pi.add_apply] + abel + +lemma leviCivita_rhs_addZ [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by + sorry -- divide previous equation by two -lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} {Z' : Π x : M, TangentSpace I x} - (hf : MDiff f) (hZ : MDiff (T% Z)) : +lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs] simp [rhs_aux_smulX]--, rhs_aux_smulY, rhs_aux_smulZ] From 4a88cf5c9470db997c84dc0086637dc6fff069ee Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 14 Jul 2025 10:59:22 +0200 Subject: [PATCH 274/601] Prove leviCivita_rhs_addX; adapt downstream: will need more scaffolding Need a local version of the above, and stronger hypotheses on my connection! --- .../Manifold/VectorBundle/LeviCivita.lean | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 34e2b0e7682b9f..ac6a7e0cdda88c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -213,18 +213,31 @@ section leviCivita_rhs variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -variable (X X' Y Z) in -lemma leviCivita_rhs_addX' : (2 : ℝ) • leviCivita_rhs I (X + X') Y Z = - (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y Z := by +lemma leviCivita_rhs_addX' [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + (2 : ℝ) • leviCivita_rhs I (X + X') Y Z = + (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X' Y Z := by have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] -- Now, continue without the scalar multiplication. - -- similar to the addZ proof below... - sorry + ext x + have h : VectorField.mlieBracket I (X + X') Y = + VectorField.mlieBracket I X Y + VectorField.mlieBracket I X' Y := by + ext x + simp [VectorField.mlieBracket_add_left (W := Y) (hX x) (hX' x)] + have h' : VectorField.mlieBracket I (X + X') Z = + VectorField.mlieBracket I X Z + VectorField.mlieBracket I X' Z := by + ext x + simp [VectorField.mlieBracket_add_left (W := Z) (hX x) (hX' x)] + simp only [rhs_aux_addX, h, h', Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_addY, rhs_aux_addZ] <;> try assumption + rw [product_add_left, product_add_right, product_add_right] + simp only [Pi.add_apply] + abel -variable (X X' Y Z) in -lemma leviCivita_rhs_addX : leviCivita_rhs I (X + X') Y Z = - leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by +lemma leviCivita_rhs_addX [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by sorry -- divide the previous equation by 2 variable (X Y Z) in @@ -454,9 +467,22 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate_aux I (M := M) e) e.baseSet where addX X X' σ x := by + have hX : MDiff (T% X) := sorry -- seems necessary now! + have hX' : MDiff (T% X') := sorry + have hσ : MDiff (T% σ) := sorry intro hx unfold lcCandidate_aux - simp [← Finset.sum_add_distrib, ← add_smul, leviCivita_rhs_addX] + simp [← Finset.sum_add_distrib, ← add_smul] + congr; ext i + rw [leviCivita_rhs_addX] <;> try assumption + · abel + · have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have : MDiffAt (T% f) x := -- missing API lemma! + (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) + |>.mdifferentiableAt le_rfl + -- TODO: need a local version of leviCivita_rhs_addX! + sorry smulX X σ g x hx := by unfold lcCandidate_aux dsimp From 5ae79729ba16177f835b497aabf6d71c0f036cd8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 14 Jul 2025 11:13:35 +0200 Subject: [PATCH 275/601] feat: add leviCivita_rhs_addY and hook up to the overall sorry --- .../Manifold/VectorBundle/LeviCivita.lean | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index ac6a7e0cdda88c..cd0d57e4ce05e7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -246,17 +246,32 @@ lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : -- TODO: do I need to assume X is differentiable? sorry -variable (X Z) in -lemma leviCivita_rhs_addY' [CompleteSpace E] (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) : +lemma leviCivita_rhs_addY' [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : (2 : ℝ) • leviCivita_rhs I X (Y + Y') Z = (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y' Z := by have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] -- continue without scalar multiplication - sorry + ext x + have h : VectorField.mlieBracket I X (Y + Y') = + VectorField.mlieBracket I X Y + VectorField.mlieBracket I X Y' := by + ext x + simp [VectorField.mlieBracket_add_right (V := X) (hY x) (hY' x)] + have h' : VectorField.mlieBracket I Z (Y + Y') = + VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z Y' := by + ext x + simp only [Pi.add_apply] + rw [VectorField.mlieBracket_add_right (V := Z) (hY x) (hY' x)] + simp only [rhs_aux_addX, h, h', Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_addY, rhs_aux_addZ] <;> try assumption + rw [product_add_left, product_add_right, product_add_right] + simp only [Pi.add_apply] + abel variable (X Z) in -lemma leviCivita_rhs_addY [CompleteSpace E] (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) : +lemma leviCivita_rhs_addY [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : leviCivita_rhs I X (Y + Y') Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y' Z := by sorry -- divide the previous equation by 2 @@ -467,7 +482,8 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate_aux I (M := M) e) e.baseSet where addX X X' σ x := by - have hX : MDiff (T% X) := sorry -- seems necessary now! + -- these three sorries seem to be necessary! + have hX : MDiff (T% X) := sorry have hX' : MDiff (T% X') := sorry have hσ : MDiff (T% σ) := sorry intro hx @@ -499,11 +515,23 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] -- want leviCivita_rhs_smulY (with a constant) sorry addσ X σ σ' x hσ hσ' hx := by + have hX : MDiff (T% X) := sorry -- missing assumption! + -- TODO: these should not be necessary with a local version of addY! + have hσ2 : MDiff (T% σ) := sorry + have hσ'2 : MDiff (T% σ') := sorry unfold lcCandidate_aux dsimp simp [← Finset.sum_add_distrib, ← add_smul] - -- want leviCivita_addY - sorry + congr; ext i + rw [leviCivita_rhs_addY] <;> try assumption + · abel + · have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have : MDiffAt (T% f) x := -- missing API lemma! + (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) + |>.mdifferentiableAt le_rfl + -- TODO: need a local version of leviCivita_rhs_addX! + sorry leibniz := by sorry From a89fff25db3130c64c58f7a81d4dc8871bc8dbcb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 14 Jul 2025 14:06:49 +0200 Subject: [PATCH 276/601] wip: refactor LC computations to add point-wise versions --- .../Manifold/VectorBundle/LeviCivita.lean | 72 ++++++++----------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index cd0d57e4ce05e7..781d0b18123573 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -195,32 +195,40 @@ lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDi end rhs_aux +variable {x : M} + -- XXX: inlining rhs_aux here makes things not typecheck any more! variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If ∇ is a Levi-Civita connection on `TM`, then `⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ -noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • ( +noncomputable def leviCivita_rhs' : M → ℝ := rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y - ⟪Y ,(VectorField.mlieBracket I X Z)⟫ - ⟪Z, (VectorField.mlieBracket I X Y)⟫ + ⟪X, (VectorField.mlieBracket I Z Y)⟫ - ) --- XXX: is introducing leviCivita_rhs' which is twice the previous quantity useful? +variable (X Y Z) in +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If ∇ is a Levi-Civita connection on `TM`, then +`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ +noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • leviCivita_rhs' I X Y Z + +omit [IsManifold I ∞ M] in +lemma leviCivita_rhs_apply : leviCivita_rhs I X Y Z x = (1 / 2 : ℝ) • leviCivita_rhs' I X Y Z x := + rfl section leviCivita_rhs variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -lemma leviCivita_rhs_addX' [CompleteSpace E] +-- TODO: relax assumptions; I only need differentiability at x! +@[simp] +lemma leviCivita_rhs'_addX_apply [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - (2 : ℝ) • leviCivita_rhs I (X + X') Y Z = - (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X' Y Z := by - have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp - simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] - -- Now, continue without the scalar multiplication. - ext x + leviCivita_rhs' I (X + X') Y Z x = + leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X' Y Z x := by + simp only [leviCivita_rhs'] have h : VectorField.mlieBracket I (X + X') Y = VectorField.mlieBracket I X Y + VectorField.mlieBracket I X' Y := by ext x @@ -235,6 +243,13 @@ lemma leviCivita_rhs_addX' [CompleteSpace E] simp only [Pi.add_apply] abel +lemma leviCivita_rhs'_addX [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivita_rhs' I (X + X') Y Z = + leviCivita_rhs' I X Y Z + leviCivita_rhs' I X' Y Z := by + ext x + simp [leviCivita_rhs'_addX_apply _ hX hX' hY hZ] + lemma leviCivita_rhs_addX [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by @@ -246,42 +261,17 @@ lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : -- TODO: do I need to assume X is differentiable? sorry -lemma leviCivita_rhs_addY' [CompleteSpace E] - (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : - (2 : ℝ) • leviCivita_rhs I X (Y + Y') Z = - (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y' Z := by - have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp - simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] - -- continue without scalar multiplication - ext x - have h : VectorField.mlieBracket I X (Y + Y') = - VectorField.mlieBracket I X Y + VectorField.mlieBracket I X Y' := by - ext x - simp [VectorField.mlieBracket_add_right (V := X) (hY x) (hY' x)] - have h' : VectorField.mlieBracket I Z (Y + Y') = - VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z Y' := by - ext x - simp only [Pi.add_apply] - rw [VectorField.mlieBracket_add_right (V := Z) (hY x) (hY' x)] - simp only [rhs_aux_addX, h, h', Pi.add_apply, Pi.sub_apply] - rw [rhs_aux_addY, rhs_aux_addZ] <;> try assumption - rw [product_add_left, product_add_right, product_add_right] - simp only [Pi.add_apply] - abel - variable (X Z) in lemma leviCivita_rhs_addY [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : leviCivita_rhs I X (Y + Y') Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y' Z := by sorry -- divide the previous equation by 2 -lemma leviCivita_rhs_addZ' [CompleteSpace E] +lemma leviCivita_rhs'_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - (2 : ℝ) • leviCivita_rhs I X Y (Z + Z') = - (2 : ℝ) • leviCivita_rhs I X Y Z + (2 : ℝ) • leviCivita_rhs I X Y Z' := by - have : ((2 : ℝ) • (2 : ℝ)⁻¹) = 1 := by simp - simp only [leviCivita_rhs, one_div, ← smul_assoc, this, one_smul] - -- continue without scalar multiplication + leviCivita_rhs' I X Y (Z + Z') = + leviCivita_rhs' I X Y Z + leviCivita_rhs' I X Y Z' := by + simp only [leviCivita_rhs'] ext x have h : VectorField.mlieBracket I X (Z + Z') = VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := by @@ -304,7 +294,7 @@ lemma leviCivita_rhs_addZ [CompleteSpace E] lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by - simp only [leviCivita_rhs] + simp only [leviCivita_rhs, leviCivita_rhs'] simp [rhs_aux_smulX]--, rhs_aux_smulY, rhs_aux_smulZ] ext x simp only [Pi.mul_apply, Pi.add_apply] @@ -488,7 +478,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have hσ : MDiff (T% σ) := sorry intro hx unfold lcCandidate_aux - simp [← Finset.sum_add_distrib, ← add_smul] + simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivita_rhs_addX] <;> try assumption · abel From f104e34cdf4858027576f71b6a32d985fdc6de29 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 14 Jul 2025 15:36:02 +0200 Subject: [PATCH 277/601] Generalize of_endomorphism to IsCovariantDerivativeOn.add_one_form --- .../VectorBundle/CovariantDerivative.lean | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 7e3538a920a44b..de045a5e363544 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -270,7 +270,7 @@ def _root_.IsCovariantDerivativeOn.convexCombination' {ι : Type*} {s : Finset ext i simp [(h i).smulX] module - addσ X σ σ' x hx hσ hσ' := by + addσ X σ σ' x hσ hσ' hx := by -- XXX: is this nicer using induction? classical induction s using Finset.induction with @@ -360,6 +360,28 @@ lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset -- Future: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) +section add_one_form + +omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] in +lemma _root_.IsCovariantDerivativeOn.add_one_form (hf : IsCovariantDerivativeOn F V f s) + (A : Π x : M, TangentSpace I x →L[𝕜] V x →L[𝕜] V x) : + IsCovariantDerivativeOn F V (fun X σ x ↦ f X σ x + A x (X x) (σ x)) s where + addX X X' σ x hx := by + simp [hf.addX] + module + smulX X σ g x hx := by + simp [hf.smulX] + addσ X σ σ' x hσ hσ' hx := by + simp [hf.addσ X hσ hσ'] + module + smul_const_σ X {σ a} x hx := by + simp [hf.smul_const_σ] + leibniz X σ g x hσ hg hx := by + simp [hf.leibniz X hσ hg] + module + +end add_one_form + section trivial_bundle omit [IsManifold I 0 M] in @@ -395,7 +417,7 @@ lemma mfderiv_smul {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) variable (I M F) in @[simps] noncomputable def trivial : CovariantDerivative I F (Trivial M F) where - toFun X s := fun x ↦ mfderiv I 𝓘(𝕜, F) s x (X x) + toFun X s x := mfderiv I 𝓘(𝕜, F) s x (X x) isCovariantDerivativeOn := { addX X X' σ x _ := by simp smulX X σ c' x _ := by simp @@ -462,33 +484,20 @@ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E -- or perhaps a contMDiffOn version of this lemma? sorry - -lemma of_endomorophism_isCovariantDerivativeOn (A : E → E →L[𝕜] E' →L[𝕜] E') : - IsCovariantDerivativeOn E' (Bundle.Trivial E E') - (fun (X : Π x : E, TangentSpace 𝓘(𝕜, E) x) (σ : E → E') x ↦ - fderiv 𝕜 σ x (X x) + A x (X x) (σ x)) univ where - addX X X' σ x _ := by - by_cases h : DifferentiableAt 𝕜 σ x - · simp [map_add]; abel - · simp [fderiv_zero_of_not_differentiableAt h] - smulX X σ c' := by simp - addσ X σ σ' x hσ hσ' hx := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' - simp [fderiv_add hσ hσ'] - abel - smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] - leibniz X σ f x hσ hf hx := by - rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ - rw [mdifferentiableAt_iff_differentiableAt] at hf - have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := - fderiv_smul (by simp_all) (by simp_all) - simp [this, bar] - module +lemma of_endomorophism_isCovariantDerivativeOn (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : + IsCovariantDerivativeOn F (Trivial M F) + (fun (X : Π x : M, TangentSpace I x) (s : M → F) x ↦ + letI d : F := mfderiv I 𝓘(𝕜, F) s x (X x) + d + A x (X x) (s x)) univ := + trivial I M F |>.isCovariantDerivativeOn.add_one_form A noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : - CovariantDerivative 𝓘(𝕜, E) E' (Bundle.Trivial E E') where + CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) - isCovariantDerivativeOn := of_endomorophism_isCovariantDerivativeOn A + isCovariantDerivativeOn := by + convert of_endomorophism_isCovariantDerivativeOn (I := 𝓘(𝕜, E)) A + ext f x v + rw [mfderiv_eq_fderiv] section real From b9eef6de30891d5a7f0b61ed1da527cc4d638fdf Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 14 Jul 2025 18:00:11 +0200 Subject: [PATCH 278/601] Massive reordering of CovariantDerivative and variable cleanup --- .../VectorBundle/CovariantDerivative.lean | 978 +++++++++--------- .../Manifold/VectorBundle/LeviCivita.lean | 4 +- 2 files changed, 514 insertions(+), 468 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index de045a5e363544..ee660de22ec558 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -20,21 +20,21 @@ TODO: add a more complete doc-string -/ -open Bundle Filter Function Topology Set +open Bundle Filter Topology Set open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -section +section general_lemmas -- those lemmas should move variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `F` model fiber (n : WithTop ℕ∞) (V : M → Type*) [TopologicalSpace (TotalSpace F V)] @@ -44,7 +44,138 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] -- `V` vector bundle -variable {I} in +lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : + mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by + by_cases hs : MDifferentiableAt% s x + · have hs' := hs.const_smul a + suffices + (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = + a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) + (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] + change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ + rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] + rfl + · by_cases ha : a = 0 + · have : a • s = 0 := by ext; simp [ha] + rw [this, ha] + change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ + simp + have hs' : ¬ MDifferentiableAt I 𝓘(𝕜, F) (a • s) x := + fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) + rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] + simp + rfl + +lemma mfderiv_smul {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) + (hs : MDiffAt s x) (v : TangentSpace I x) : + letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v + letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v + mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by + sorry + +end general_lemmas + +section extend +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] + -- `V` vector bundle + +-- TODO: either change `localFrame` to make sure it is everywhere smooth +-- or introduce a cut-off here. First option is probaly better. +-- TODO: comment why we chose the second option in the end, and adapt the definition accordingly +-- new definition: smooth a bump function, then smul with localExtensionOn +/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ +noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + (x' : M) → V x' := + letI b := Basis.ofVectorSpace ℝ F + letI t := trivializationAt F V x + -- Choose a smooth bump function ψ near `x`, supported within t.baseSet + -- and return ψ • V₀ instead. + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + ψ.toFun • localExtensionOn b t x v + +variable {I F} + +-- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for +-- *well-chosen* extensions (such as ours). +-- so, one may argue this is mathematically wrong, but it encodes the "choice some extension +-- with this and that property" nicely +-- a different proof would be to argue only the value at a point matters for cov +@[simp] +lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : + extend I F (v + v') = extend I F v + extend I F v' := by + simp [extend, localExtensionOn_add] + +@[simp] +lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : + extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module + +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + extend I F v x = v := by + simpa [extend] using + localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v + +variable (I F) + +lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% extend I F σ₀) := by + letI t := trivializationAt F V x + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + let hψ := + Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + apply ψ.contMDiff.contMDiffOn.smul_section_of_tsupport t.open_baseSet hψ.1 + apply contMDiffOn_localExtensionOn _ hx + +lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + MDiff (T% extend I F σ₀) := + contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) + +theorem contDiff_extend + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] + (x : E) (y : E') : ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by + rw [contDiff_iff_contDiffAt] + intro x' + rw [← contMDiffAt_iff_contDiffAt] + simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' + +end extend + +section any_field +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -- [FiniteDimensional 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] + -- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] --[VectorBundle 𝕜 F V] + -- `V` vector bundle + structure IsCovariantDerivativeOn (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (s : Set M := Set.univ) : Prop where @@ -63,38 +194,40 @@ structure IsCovariantDerivativeOn smul_const_σ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) {x} (hx : x ∈ s := by trivial) : f X (a • σ) x = a • f X σ x -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -lemma IsCovariantDerivativeOn.smul_const_X - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {s : Set M} (h : IsCovariantDerivativeOn F V f s) {x} (a : 𝕜) - (X : Π x, TangentSpace I x) (σ : Π x, V x) (hx : x ∈ s := by trivial) : - f (a • X) σ x = a • f X σ x := - h.smulX .. +/-- +A covariant derivative ∇ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) + (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) + (u : Set M) where + regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, + CMDiff[u] (k + 1) (T% σ) → CMDiff[u] k (T% X) → + CMDiff[u] k (T% (cov X σ)) -@[ext] -structure CovariantDerivative where - toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) - isCovariantDerivativeOn : IsCovariantDerivativeOn F V toFun Set.univ +variable {F} + +namespace IsCovariantDerivativeOn -variable {I F V} +section changing_set +/-! Changing set -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -lemma IsCovariantDerivativeOn.mono +In this changing we change `s` in `IsCovariantDerivativeOn F f s`. + +-/ +lemma mono {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s t : Set M} - (hf : IsCovariantDerivativeOn F V f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F V f s where + (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where addX X X' σ _ hx := hf.addX X X' σ (hst hx) smulX X σ f _ hx := hf.smulX X σ f (hst hx) addσ X _ _ _ hσ hσ' hx := hf.addσ X hσ hσ' (hst hx) leibniz X _ _ _ hσ hf' hx := hf.leibniz X hσ hf' (hst hx) smul_const_σ X σ a _ hx := hf.smul_const_σ X σ a (hst hx) -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -lemma IsCovariantDerivativeOn.iUnion {ι : Type*} +lemma iUnion {ι : Type*} {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : ι → Set M} - (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) : IsCovariantDerivativeOn F V f (⋃ i, s i) where + (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) : IsCovariantDerivativeOn F f (⋃ i, s i) where addX X X' σ x hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).addX .. @@ -110,105 +243,34 @@ lemma IsCovariantDerivativeOn.iUnion {ι : Type*} smul_const_σ X σ a x hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).smul_const_σ .. -namespace CovariantDerivative - -attribute [coe] toFun - -/-- Coercion of a `CovariantDerivative` to function -/ -instance : CoeFun (CovariantDerivative I F V) - fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := - ⟨fun e ↦ e.toFun⟩ -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -instance (cov : CovariantDerivative I F V) {s : Set M} : - IsCovariantDerivativeOn F V cov s := by - apply cov.isCovariantDerivativeOn.mono (fun ⦃a⦄ a ↦ trivial) +end changing_set -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -/-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant derivative on each set in an open cover, -it is a covariant derivative. -/ -def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) (hs : ⋃ i, s i = Set.univ) : - CovariantDerivative I F V := - ⟨f, hs ▸ IsCovariantDerivativeOn.iUnion hf⟩ +section computational_properties -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -@[simp] -lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set M} +lemma smul_const_X {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (hf : ∀ i, IsCovariantDerivativeOn F V f (s i)) (hs : ⋃ i, s i = Set.univ) : - of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl - -variable (F) in -/-- -A covariant derivative ∇ is called of class `C^k` iff, -whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. -This is a class so typeclass inference can deduce this automatically. --/ -class _root_.ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) - (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) - (u : Set M) where - regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - CMDiff[u] (k + 1) (T% σ) → CMDiff[u] k (T% X) → - CMDiff[u] k (T% (cov X σ)) - --- TODO: relative the definition below to the above one -/-- -A covariant derivative ∇ is called of class `C^k` iff, -whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. -This is a class so typeclass inference can deduce this automatically. --/ -class _root_.IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where - regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - CMDiff (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → - -- TODO: CMDiff does not work here! - ContMDiff% k (T% (cov X σ)) - --- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection --- is of class C^k (up to off-by-one errors) + {s : Set M} (h : IsCovariantDerivativeOn F f s) {x} (a : 𝕜) + (X : Π x, TangentSpace I x) (σ : Π x, V x) (hx : x ∈ s := by trivial) : + f (a • X) σ x = a • f X σ x := + h.smulX .. variable {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in @[simp] -lemma _root_.IsCovariantDerivativeOn.zeroX (hf : IsCovariantDerivativeOn F V f s) +lemma zeroX (hf : IsCovariantDerivativeOn F f s) {x : M} (hx : x ∈ s := by trivial) (σ : Π x : M, V x) : f 0 σ x = 0 := by simpa using IsCovariantDerivativeOn.addX f hf 0 0 σ hx -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in @[simp] -lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = 0 := by - ext x - apply cov.isCovariantDerivativeOn.zeroX - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -@[simp] -lemma _root_.IsCovariantDerivativeOn.zeroσ (hf : IsCovariantDerivativeOn F V f s) +lemma zeroσ [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) (X : Π x : M, TangentSpace I x) {x} (hx : x ∈ s := by trivial) : f X 0 x = 0 := by simpa using (hf.addσ X (mdifferentiableAt_zeroSection ..) (mdifferentiableAt_zeroSection ..) : f X (0+0) x = _) -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] in - -@[simp] -lemma zeroσ (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by - ext x - apply cov.isCovariantDerivativeOn.zeroσ - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -lemma _root_.IsCovariantDerivativeOn.sum_X (hf : IsCovariantDerivativeOn F V f s) +lemma sum_X (hf : IsCovariantDerivativeOn F f s) {ι : Type*} {u : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x} (hx : x ∈ s) : f (∑ i ∈ u, X i) σ x = ∑ i ∈ u, f (X i) σ x := by @@ -219,21 +281,19 @@ lemma _root_.IsCovariantDerivativeOn.sum_X (hf : IsCovariantDerivativeOn F V f s | insert a u ha h => simp [Finset.sum_insert ha, ← h, hf.addX] +end computational_properties -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] - [VectorBundle 𝕜 F V] in -lemma sum_X (cov : CovariantDerivative I F V) - {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : - cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by - ext x - simpa using cov.isCovariantDerivativeOn.sum_X +section operations + +variable {s : Set M} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} /-- A convex combination of covariant derivatives is a covariant derivative. -/ @[simps] -def _root_.IsCovariantDerivativeOn.convexCombination +def convexCombination {f' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (hf : IsCovariantDerivativeOn F V f s) (hf' : IsCovariantDerivativeOn F V f' s) (g : M → 𝕜) : - IsCovariantDerivativeOn F V (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where + (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : + IsCovariantDerivativeOn F (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where addX X X' σ _ hx := by simp [hf.addX, hf'.addX]; module smulX X σ φ _ hx := by simp [hf.smulX, hf'.smulX]; module addσ X σ σ' x hx hσ hσ' := by @@ -246,19 +306,24 @@ def _root_.IsCovariantDerivativeOn.convexCombination simp [hf.leibniz X hσ hφ, hf'.leibniz X hσ hφ] module -/-- A convex combination of covariant derivatives is a covariant derivative. -/ -@[simps] -def convexCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : - CovariantDerivative I F V where - toFun := fun X σ ↦ (g • (cov X σ)) + (1 - g) • (cov' X σ) - isCovariantDerivativeOn := - cov.isCovariantDerivativeOn.convexCombination cov'.isCovariantDerivativeOn _ +/-- A convex combination of two `C^k` connections is a `C^k` connection. -/ +lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination + [IsManifold I 1 M] [VectorBundle 𝕜 F V] + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) + (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) + (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : + ContMDiffCovariantDerivativeOn F n (fun X σ ↦ (f • (cov X σ)) + (1 - f) • (cov' X σ)) u where + regularity hX hσ := by + apply ContMDiffOn.add_section + · exact hf.smul_section <| Hcov.regularity hX hσ + · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.regularity hX hσ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def _root_.IsCovariantDerivativeOn.convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (h : ∀ i, IsCovariantDerivativeOn F V (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : - IsCovariantDerivativeOn F V (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where + (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : + IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where addX X X' σ x hx := by rw [← Finset.sum_add_distrib] congr @@ -306,6 +371,145 @@ def _root_.IsCovariantDerivativeOn.convexCombination' {ι : Type*} {s : Finset rw [this, one_smul] simp + +variable {s : Set M} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + +lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] + [∀ (x : M), ContinuousSMul 𝕜 (V x)] (hf : IsCovariantDerivativeOn F f s) + (A : Π x : M, TangentSpace I x →L[𝕜] V x →L[𝕜] V x) : + IsCovariantDerivativeOn F (fun X σ x ↦ f X σ x + A x (X x) (σ x)) s where + addX X X' σ x hx := by + simp [hf.addX] + module + smulX X σ g x hx := by + simp [hf.smulX] + addσ X σ σ' x hσ hσ' hx := by + simp [hf.addσ X hσ hσ'] + module + smul_const_σ X {σ a} x hx := by + simp [hf.smul_const_σ] + leibniz X σ g x hσ hg hx := by + simp [hf.leibniz X hσ hg] + module + +end operations + +section trivial_bundle + +variable (I M F) in +@[simps] +noncomputable def trivial : + IsCovariantDerivativeOn F (V := Trivial M F) + (fun X s x ↦ mfderiv I 𝓘(𝕜, F) s x (X x)) univ where + addX X X' σ x _ := by simp + smulX X σ c' x _ := by simp + addσ X σ σ' x hσ hσ' hx := by + rw [mdifferentiableAt_section] at hσ hσ' + -- TODO: specialize mdifferentiableAt_section to trivial bundles? + change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ + change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' + rw [mfderiv_add hσ hσ'] + rfl + smul_const_σ X σ a x hx := by + rw [mfderiv_const_smul] + leibniz X σ f x hσ hf hx := by + rw [mdifferentiableAt_section] at hσ + exact mfderiv_smul hσ hf (X x) + +lemma of_endomorphism (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : + IsCovariantDerivativeOn F + (fun (X : Π x : M, TangentSpace I x) (s : M → F) x ↦ + letI d : F := mfderiv I 𝓘(𝕜, F) s x (X x) + d + A x (X x) (s x)) univ := + trivial I M F |>.add_one_form A + +end trivial_bundle + +end IsCovariantDerivativeOn + +/-! Bundled global covariant derivatives -/ + +variable (I F V) in +@[ext] +structure CovariantDerivative where + toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) + isCovariantDerivativeOn : IsCovariantDerivativeOn F toFun Set.univ + +namespace CovariantDerivative + +attribute [coe] toFun + +/-- Coercion of a `CovariantDerivative` to function -/ +instance : CoeFun (CovariantDerivative I F V) + fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := + ⟨fun e ↦ e.toFun⟩ + +instance (cov : CovariantDerivative I F V) {s : Set M} : + IsCovariantDerivativeOn F cov s := by + apply cov.isCovariantDerivativeOn.mono (fun ⦃a⦄ a ↦ trivial) + +/-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant derivative on each set in an open cover, +it is a covariant derivative. -/ +def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) (hs : ⋃ i, s i = Set.univ) : + CovariantDerivative I F V := + ⟨f, hs ▸ IsCovariantDerivativeOn.iUnion hf⟩ + +@[simp] +lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set M} + {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) (hs : ⋃ i, s i = Set.univ) : + of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl + + +-- TODO: relative the definition below to ContMDiffCovariantDerivativeOn +/-- +A covariant derivative ∇ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where + regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, + CMDiff (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → + -- TODO: CMDiff does not work here! + ContMDiff% k (T% (cov X σ)) + +-- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection +-- is of class C^k (up to off-by-one errors) + +section computational_properties + +@[simp] +lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = 0 := by + ext x + apply cov.isCovariantDerivativeOn.zeroX + +@[simp] +lemma zeroσ [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) + (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by + ext x + apply cov.isCovariantDerivativeOn.zeroσ + +lemma sum_X (cov : CovariantDerivative I F V) + {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : + cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by + ext x + simpa using cov.isCovariantDerivativeOn.sum_X + +end computational_properties + +section operations + +/-- A convex combination of covariant derivatives is a covariant derivative. -/ +@[simps] +def convexCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : + CovariantDerivative I F V where + toFun := fun X σ ↦ (g • (cov X σ)) + (1 - g) • (cov' X σ) + isCovariantDerivativeOn := + cov.isCovariantDerivativeOn.convexCombination cov'.isCovariantDerivativeOn _ + /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : @@ -314,24 +518,8 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' (fun i ↦ (cov i).isCovariantDerivativeOn) hf -omit [IsManifold I 0 M] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -/-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivativeOn.convexCombination [IsManifold I 1 M] - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) - (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) - (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : - ContMDiffCovariantDerivativeOn F n (fun X σ ↦ (f • (cov X σ)) + (1 - f) • (cov' X σ)) u where - regularity hX hσ := by - apply ContMDiffOn.add_section - · exact hf.smul_section <| Hcov.regularity hX hσ - · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.regularity hX hσ - -omit [IsManifold I 0 M] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma _root_.IsCovariantDerivativeOn.convexCombination_isRegular [IsManifold I 1 M] +lemma IsCkConnection.convexCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : IsCkConnection cov n) (hcov' : IsCkConnection cov' n) : @@ -341,16 +529,15 @@ lemma _root_.IsCovariantDerivativeOn.convexCombination_isRegular [IsManifold I 1 · exact hf.smul_section <| hcov.regularity hX hσ · exact (contMDiff_const.sub hf).smul_section <| hcov'.regularity hX hσ -omit [IsManifold I 0 M] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in /-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset ι} [Nonempty s] +lemma IsCkConnection.convexCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] + {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, IsCkConnection (cov i) n) : IsCkConnection (convexCombination' cov hf) n where regularity {X σ} hX hσ := by - unfold convexCombination' + unfold CovariantDerivative.convexCombination' dsimp have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n (T% (f i • (cov i) X σ)) := by @@ -360,60 +547,10 @@ lemma convexCombination'_isRegular [IsManifold I 1 M] {ι : Type*} {s : Finset -- Future: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) -section add_one_form - -omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] in -lemma _root_.IsCovariantDerivativeOn.add_one_form (hf : IsCovariantDerivativeOn F V f s) - (A : Π x : M, TangentSpace I x →L[𝕜] V x →L[𝕜] V x) : - IsCovariantDerivativeOn F V (fun X σ x ↦ f X σ x + A x (X x) (σ x)) s where - addX X X' σ x hx := by - simp [hf.addX] - module - smulX X σ g x hx := by - simp [hf.smulX] - addσ X σ σ' x hσ hσ' hx := by - simp [hf.addσ X hσ hσ'] - module - smul_const_σ X {σ a} x hx := by - simp [hf.smul_const_σ] - leibniz X σ g x hσ hg hx := by - simp [hf.leibniz X hσ hg] - module - -end add_one_form +end operations section trivial_bundle -omit [IsManifold I 0 M] in -lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : - mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by - by_cases hs : MDifferentiableAt% s x - · have hs' := hs.const_smul a - suffices - (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = - a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) - (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] - change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ - rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] - rfl - · by_cases ha : a = 0 - · have : a • s = 0 := by ext; simp [ha] - rw [this, ha] - change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ - simp - have hs' : ¬ MDifferentiableAt I 𝓘(𝕜, F) (a • s) x := - fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) - rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] - simp - rfl - -lemma mfderiv_smul {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) - (hs : MDiffAt s x) (v : TangentSpace I x) : - letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v - letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v - mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by - sorry - variable (I M F) in @[simps] noncomputable def trivial : CovariantDerivative I F (Trivial M F) where @@ -437,25 +574,6 @@ end trivial_bundle variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] --- variable (E E') in --- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ --- @[simps] --- noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' --- (Bundle.Trivial E E') where --- toFun X s := fun x ↦ fderiv 𝕜 s x (X x) --- isCovariantDerivativeOn := --- { addX X X' σ x _ := by simp --- smulX X σ c' x _ := by simp --- addσ X σ σ' x hσ hσ' hx := by --- rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' --- rw [fderiv_add hσ hσ'] --- rfl --- smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] --- leibniz X σ f x hσ hf hx := by --- have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := --- fderiv_smul (by simp_all) (by simp_all) --- simp [this, bar] --- rfl } -- TODO: does it make sense to speak of analytic connections? if so, change the definition of -- regularity and use ∞ from `open scoped ContDiff` instead. @@ -484,87 +602,37 @@ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E -- or perhaps a contMDiffOn version of this lemma? sorry -lemma of_endomorophism_isCovariantDerivativeOn (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : - IsCovariantDerivativeOn F (Trivial M F) - (fun (X : Π x : M, TangentSpace I x) (s : M → F) x ↦ - letI d : F := mfderiv I 𝓘(𝕜, F) s x (X x) - d + A x (X x) (s x)) univ := - trivial I M F |>.isCovariantDerivativeOn.add_one_form A - noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) - isCovariantDerivativeOn := by - convert of_endomorophism_isCovariantDerivativeOn (I := 𝓘(𝕜, E)) A - ext f x v - rw [mfderiv_eq_fderiv] - -section real - -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} - -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] - -- `F` model fiber - (n : WithTop ℕ∞) - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul ℝ (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] - -- `V` vector bundle - -/- the following lemmas are subsubmed by tensoriality_criterion - XXX should they be extracted as separate lemmas (stated twice)? -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -/-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ -lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] - {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσσ' : ∀ x ∈ s, X x = X' x) : - cov X σ x = cov X' σ x := by - -- Choose a smooth bump function ψ with support around `x` contained in `s` - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs - -- Observe that `ψ • X = ψ • X'` as dependent functions. - have (x : M) : ((ψ : M → ℝ) • X) x = ((ψ : M → ℝ) • X') x := by - by_cases h : x ∈ s - · simp [hσσ' x h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - -- Then, it's a chain of (dependent) equalities. - calc cov X σ x - _ = cov ((ψ : M → ℝ) • X) σ x := by simp [cov.smulX] - _ = cov ((ψ : M → ℝ) • X') σ x := by rw [funext this] - _ = cov X' σ x := by simp [cov.smulX] + isCovariantDerivativeOn := by + convert IsCovariantDerivativeOn.of_endomorphism (I := 𝓘(𝕜, E)) A + ext f x v + rw [mfderiv_eq_fderiv] +end CovariantDerivative +end any_field -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} - (hX : X x = 0) : cov X σ x = 0 := by - -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. - -- To do so, choose a basis of TangentSpace I x = E. - let n : ℕ := Module.finrank ℝ E - let b : Basis (Fin n) ℝ E := Module.finBasis ℝ E - let e := trivializationAt E (TangentSpace I) x - let Xi (i : Fin n) := b.localFrame e i - -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. - let a := fun i ↦ b.localFrame_repr e i X - have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X - have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at hX i - calc cov X σ x - _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) - _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp - _ = ∑ i, a i x • cov (Xi i) σ x := by - congr; ext i; simp [cov.smulX (Xi i) σ (a i)] - _ = 0 := by simp [this] -/ +section real + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + -- `V` vector bundle + +namespace IsCovariantDerivativeOn -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- `cov X σ x` only depends on `X` via `X x` -/ -lemma congr_X_at {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - [T2Space M] [IsManifold I ∞ M] {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) +lemma congr_X_at [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] + {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hx : x ∈ u) (hXX' : X x = X' x) : cov X σ x = cov X' σ x := by apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' @@ -573,48 +641,6 @@ lemma congr_X_at {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π · intro X X' rw [hcov.addX] -/- TODO: are these lemmas still useful after the general tensoriality lemma? -are they worth extracting separately? -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} - (hσ : MDiffAt (T% σ) x) - (f : SmoothBumpFunction I x) : - cov X ((f : M → ℝ) • σ) x = cov X σ x := by - rw [cov.leibniz _ _ _ _ hσ] - swap; · apply f.contMDiff.mdifferentiable (by norm_num) - calc _ - _ = cov X σ x + 0 := ?_ - _ = cov X σ x := by rw [add_zero] - simp [f.eq_one, f.eventuallyEq_one.mfderiv_eq] - rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] - left - rfl - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_σ_of_eventuallyEq - (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσ : MDiffAt (T% σ) x) - (hσσ' : ∀ x ∈ s, σ x = σ' x) : - cov X σ x = cov X σ' x := by - -- Choose a smooth bump function ψ with support around `x` contained in `s` - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs - -- Observe that `ψ • σ = ψ • σ'` as dependent functions. - have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by - by_cases h : x ∈ s - · simp [hσσ' x h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - -- Then, it's a chain of (dependent) equalities. - calc cov X σ x - _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ hσ] - _ = cov X ((ψ : M → ℝ) • σ') x := sorry -- use simp [funext hσ] and (by simp [this]) - _ = cov X σ' x := by - simp [cov.congr_σ_smoothBumpFunction, mdifferentiableAt_dependent_congr hs hσ hσσ'] --/ - -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. @@ -623,21 +649,17 @@ def differenceAux (cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := fun X σ ↦ cov X σ - cov' X σ -omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] - [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] in +omit [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] in @[simp] lemma differenceAux_apply (cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) : differenceAux cov cov' X σ = cov X σ - cov' X σ := rfl -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] [FiniteDimensional ℝ E] in -lemma _root_.IsCovariantDerivativeOn.differenceAux_smul_eq +lemma differenceAux_smul_eq {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) - (hcov' : IsCovariantDerivativeOn F V cov' u) + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (hcov' : IsCovariantDerivativeOn F cov' u) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) (hσ : MDiffAt (T% σ) x) @@ -652,25 +674,22 @@ lemma _root_.IsCovariantDerivativeOn.differenceAux_smul_eq _ = f x • (cov X σ x - cov' X σ x) := by simp [smul_sub] _ = _ := rfl -omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] in -lemma _root_.IsCovariantDerivativeOn.differenceAux_smul_eq' +lemma differenceAux_smul_eq' {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) - (hcov' : IsCovariantDerivativeOn F V cov' u) + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (hcov' : IsCovariantDerivativeOn F cov' u) (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) : differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by simp [differenceAux, hcov.smulX, hcov'.smulX, smul_sub] -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ -lemma _root_.IsCovariantDerivativeOn.differenceAux_tensorial +lemma differenceAux_tensorial {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F V cov u) - (hcov' : IsCovariantDerivativeOn F V cov' u) - [T2Space M] [IsManifold I ∞ M] - [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (hcov' : IsCovariantDerivativeOn F cov' u) + [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} (hσ : MDiffAt (T% σ) x₀) (hσ' : MDiffAt (T% σ') x₀) @@ -683,7 +702,7 @@ lemma _root_.IsCovariantDerivativeOn.differenceAux_tensorial · intro f X apply hcov.differenceAux_smul_eq' hcov' · intro X X' - unfold φ CovariantDerivative.differenceAux + unfold φ differenceAux simp only [Pi.sub_apply, hcov.addX, hcov'.addX] abel · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ differenceAux cov cov' X' σ @@ -697,75 +716,11 @@ lemma _root_.IsCovariantDerivativeOn.differenceAux_tensorial rw [hcov.addσ, hcov'.addσ] <;> try assumption abel --- TODO: either change `localFrame` to make sure it is everywhere smooth --- or introduce a cut-off here. First option is probaly better. --- TODO: comment why we chose the second option in the end, and adapt the definition accordingly --- new definition: smooth a bump function, then smul with localExtensionOn -variable (I F) in -/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. -The details of the extension are mostly unspecified: for covariant derivatives, the value of -`s` at points other than `x` will not matter (except for shorter proofs). -Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. --/ -noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - (x' : M) → V x' := - letI b := Basis.ofVectorSpace ℝ F - letI t := trivializationAt F V x - -- Choose a smooth bump function ψ near `x`, supported within t.baseSet - -- and return ψ • V₀ instead. - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - ψ.toFun • localExtensionOn b t x v - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in --- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for --- *well-chosen* extensions (such as ours). --- so, one may argue this is mathematically wrong, but it encodes the "choice some extension --- with this and that property" nicely --- a different proof would be to argue only the value at a point matters for cov -@[simp] -lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : - extend I F (v + v') = extend I F v + extend I F v' := by - simp [extend, localExtensionOn_add] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -@[simp] -lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} (v : V x) : - extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - extend I F v x = v := by - simpa [extend] using - localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% extend I F σ₀) := by - letI t := trivializationAt F V x - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - let hψ := - Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - apply ψ.contMDiff.contMDiffOn.smul_section_of_tsupport t.open_baseSet hψ.1 - apply contMDiffOn_localExtensionOn _ hx - -variable (F I) in -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in -lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDiff (T% extend I F σ₀) := - contMDiff_extend σ₀ |>.mdifferentiable (by simp) - -omit [FiniteDimensional ℝ E] [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul ℝ (V x)] in lemma isBilinearMap_differenceAux [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] - [ContMDiffVectorBundle ∞ F V I] {s : Set M} {cov cov'} {x : M} - (hcov : IsCovariantDerivativeOn F V cov s) - (hcov' : IsCovariantDerivativeOn F V cov' s) (hx : x ∈ s := by trivial) : + [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] {s : Set M} {cov cov'} {x : M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) : IsBilinearMap ℝ (fun (X₀ : TangentSpace I x) (σ₀ : V x) ↦ differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x) where add_left u v w := by @@ -786,49 +741,39 @@ lemma isBilinearMap_differenceAux simp only [extend_smul, Pi.sub_apply, hcov.smul_const_σ, hcov'.smul_const_σ] module +variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + /-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] - [FiniteDimensional ℝ E] [ContMDiffVectorBundle ∞ F V I] + [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} {x : M} - (hcov : IsCovariantDerivativeOn F V cov s) - (hcov' : IsCovariantDerivativeOn F V cov' s) + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) : TangentSpace I x →L[ℝ] V x →L[ℝ] V x := haveI : FiniteDimensional ℝ (TangentSpace I x) := by assumption (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap --- -- Note: we conciously register this lemma in unapplied form, --- -- but differenceAux_apply: this means the applied form should simplify down all the way, --- -- but hopefully a mere term difference not. --- omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in --- @[simp] --- lemma difference_toFun [FiniteDimensional ℝ F] [FiniteDimensional ℝ E] [IsManifold I 1 M] --- (cov cov' : CovariantDerivative I F V) : --- cov.difference cov' = fun x X₀ σ₀ ↦ differenceAux cov cov' (extend E X₀) --- (extend F σ₀) x := rfl - --- show? the map differenceAux to difference is injective - lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] - [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - [ContMDiffVectorBundle ∞ F V I] + [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] + [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} {x : M} - (hcov : IsCovariantDerivativeOn F V cov s) - (hcov' : IsCovariantDerivativeOn F V cov' s) + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) (X₀ : TangentSpace I x) (σ₀ : V x) : difference hcov hcov' hx X₀ σ₀ = cov (extend I E X₀) (extend I F σ₀) x - cov' (extend I E X₀) (extend I F σ₀) x := rfl @[simp] lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] - [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - [ContMDiffVectorBundle ∞ F V I] + [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] + [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} {x : M} - (hcov : IsCovariantDerivativeOn F V cov s) - (hcov' : IsCovariantDerivativeOn F V cov' s) + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) (X : Π x, TangentSpace I x) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : difference hcov hcov' hx (X x) (σ x) = @@ -842,14 +787,6 @@ section classification variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] -theorem contDiff_extend {E : Type*} - [NormedAddCommGroup E] [NormedSpace ℝ E] {E' : Type*} [NormedAddCommGroup E'] - [NormedSpace ℝ E'] [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] (x : E) (y : E') : - ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by - rw [contDiff_iff_contDiffAt] - intro x' - rw [← contMDiffAt_iff_contDiffAt] - simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') y x' /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term @@ -871,24 +808,27 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] use fun x ↦ difference cov.isCovariantDerivativeOn (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn (mem_univ x) intro X σ x hσ - simp only [of_endomorphism] + simp only [CovariantDerivative.of_endomorphism] erw [difference_apply cov.isCovariantDerivativeOn - (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn _ X hσ, trivial] + (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn _ X hσ, + CovariantDerivative.trivial] simp only [mfderiv_eq_fderiv] module end classification +end IsCovariantDerivativeOn + section from_trivialization variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] noncomputable -def _root_.Trivialization.covDeriv (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) +def Trivialization.covDeriv (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (x : M) : V x := e.symm x (mfderiv I 𝓘(ℝ, F) (fun x' ↦ (e (σ x')).2) x (X x)) -lemma _root_.Trivialization.covDeriv_isCovariantDerivativeOn : - IsCovariantDerivativeOn (I := I) F V e.covDeriv e.baseSet where +lemma Trivialization.covDeriv_isCovariantDerivativeOn : + IsCovariantDerivativeOn (I := I) F e.covDeriv e.baseSet where addX X X' σ x hx := by sorry smulX X σ c' x hx := by sorry addσ X σ σ' x hσ hσ' hx := by sorry @@ -897,7 +837,9 @@ lemma _root_.Trivialization.covDeriv_isCovariantDerivativeOn : end from_trivialization + section horiz +namespace CovariantDerivative def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := by @@ -925,17 +867,17 @@ lemma proj_mderiv {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x (X x)) := by sorry +end CovariantDerivative end horiz section torsion +namespace CovariantDerivative variable [h : IsManifold I ∞ M] -- The torsion tensor of a covariant derivative on the tangent bundle `TM`. variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} -omit [FiniteDimensional ℝ E] - variable (cov) in noncomputable def torsion : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := @@ -1022,11 +964,10 @@ lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : ext x apply cov.torsion_smul_right_apply _ (hf x) (hY x) -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] in /-- The torsion of a covariant derivative is tensorial: the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ -def torsion_tensorial [T2Space M] [IsManifold I ∞ M] - [FiniteDimensional ℝ F] [ContMDiffVectorBundle 1 F V I] +def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {X X' Y Y' : Π x : M, TangentSpace I x} {x₀ : M} (hX : MDiffAt (T% X) x₀) (hX' : MDiffAt (T% X') x₀) (hY : MDiffAt (T% Y) x₀) (hY' : MDiffAt (T% Y') x₀) @@ -1078,10 +1019,115 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ -- compute: their Lie bracket is zero -- compute: the other two terms cancel, done +end CovariantDerivative end torsion end real -end CovariantDerivative -end +/- the following lemmas are subsubmed by tensoriality_criterion + XXX should they be extracted as separate lemmas (stated twice)? +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +/-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ +lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] + {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) + (hσσ' : ∀ x ∈ s, X x = X' x) : + cov X σ x = cov X' σ x := by + -- Choose a smooth bump function ψ with support around `x` contained in `s` + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs + -- Observe that `ψ • X = ψ • X'` as dependent functions. + have (x : M) : ((ψ : M → ℝ) • X) x = ((ψ : M → ℝ) • X') x := by + by_cases h : x ∈ s + · simp [hσσ' x h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] + -- Then, it's a chain of (dependent) equalities. + calc cov X σ x + _ = cov ((ψ : M → ℝ) • X) σ x := by simp [cov.smulX] + _ = cov ((ψ : M → ℝ) • X') σ x := by rw [funext this] + _ = cov X' σ x := by simp [cov.smulX] + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} + (hX : X x = 0) : cov X σ x = 0 := by + -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. + -- To do so, choose a basis of TangentSpace I x = E. + let n : ℕ := Module.finrank ℝ E + let b : Basis (Fin n) ℝ E := Module.finBasis ℝ E + let e := trivializationAt E (TangentSpace I) x + let Xi (i : Fin n) := b.localFrame e i + -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. + let a := fun i ↦ b.localFrame_repr e i X + have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X + have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at hX i + calc cov X σ x + _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) + _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp + _ = ∑ i, a i x • cov (Xi i) σ x := by + congr; ext i; simp [cov.smulX (Xi i) σ (a i)] + _ = 0 := by simp [this] -/ + +/- TODO: are these lemmas still useful after the general tensoriality lemma? +are they worth extracting separately? +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} + (hσ : MDiffAt (T% σ) x) + (f : SmoothBumpFunction I x) : + cov X ((f : M → ℝ) • σ) x = cov X σ x := by + rw [cov.leibniz _ _ _ _ hσ] + swap; · apply f.contMDiff.mdifferentiable (by norm_num) + calc _ + _ = cov X σ x + 0 := ?_ + _ = cov X σ x := by rw [add_zero] + simp [f.eq_one, f.eventuallyEq_one.mfderiv_eq] + rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] + left + rfl + +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] in +lemma congr_σ_of_eventuallyEq + (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] + (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) + (hσ : MDiffAt (T% σ) x) + (hσσ' : ∀ x ∈ s, σ x = σ' x) : + cov X σ x = cov X σ' x := by + -- Choose a smooth bump function ψ with support around `x` contained in `s` + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs + -- Observe that `ψ • σ = ψ • σ'` as dependent functions. + have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by + by_cases h : x ∈ s + · simp [hσσ' x h] + · simp [notMem_support.mp fun a ↦ h (hψ a)] + -- Then, it's a chain of (dependent) equalities. + calc cov X σ x + _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ hσ] + _ = cov X ((ψ : M → ℝ) • σ') x := sorry -- use simp [funext hσ] and (by simp [this]) + _ = cov X σ' x := by + simp [cov.congr_σ_smoothBumpFunction, mdifferentiableAt_dependent_congr hs hσ hσσ'] +-/ + +-- variable (E E') in +-- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ +-- @[simps] +-- noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' +-- (Bundle.Trivial E E') where +-- toFun X s := fun x ↦ fderiv 𝕜 s x (X x) +-- isCovariantDerivativeOn := +-- { addX X X' σ x _ := by simp +-- smulX X σ c' x _ := by simp +-- addσ X σ σ' x hσ hσ' hx := by +-- rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' +-- rw [fderiv_add hσ hσ'] +-- rfl +-- smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] +-- leibniz X σ f x hσ hf hx := by +-- have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := +-- fderiv_smul (by simp_all) (by simp_all) +-- simp [this, bar] +-- rfl } diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 781d0b18123573..a3863831b99f7a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -470,7 +470,7 @@ lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate_aux I (M := M) e) e.baseSet where + IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e) e.baseSet where addX X X' σ x := by -- these three sorries seem to be necessary! have hX : MDiff (T% X) := sorry @@ -528,7 +528,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn E (TangentSpace I) (lcCandidate I M) e.baseSet := by + IsCovariantDerivativeOn E (lcCandidate I M) e.baseSet := by sorry -- need some IsCovariantDerivativeOn_congr + lemma bar end From c7d8bc9093781d463dd58ad99da16eea083e57e4 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 14 Jul 2025 18:39:11 +0200 Subject: [PATCH 279/601] Refactor classification on trivial bundles --- .../VectorBundle/CovariantDerivative.lean | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ee660de22ec558..adf1ce31127d3d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -748,12 +748,14 @@ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Spac [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {s : Set M} {x : M} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) - (hx : x ∈ s := by trivial) : TangentSpace I x →L[ℝ] V x →L[ℝ] V x := + (x : M) : TangentSpace I x →L[ℝ] V x →L[ℝ] V x := haveI : FiniteDimensional ℝ (TangentSpace I x) := by assumption - (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap + open Classical in + if hx : x ∈ s then (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap + else 0 lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] @@ -763,8 +765,10 @@ lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) (X₀ : TangentSpace I x) (σ₀ : V x) : - difference hcov hcov' hx X₀ σ₀ = - cov (extend I E X₀) (extend I F σ₀) x - cov' (extend I E X₀) (extend I F σ₀) x := rfl + difference hcov hcov' x X₀ σ₀ = + cov (extend I E X₀) (extend I F σ₀) x - cov' (extend I E X₀) (extend I F σ₀) x := by + simp only [difference, hx, reduceDIte] + rfl @[simp] lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] @@ -776,44 +780,42 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) (X : Π x, TangentSpace I x) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : - difference hcov hcov' hx (X x) (σ x) = - cov X σ x - cov' X σ x := - hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hσ (extend_apply_self _) + difference hcov hcov' x (X x) (σ x) = + cov X σ x - cov' X σ x := by + simp only [difference, hx, reduceDIte] + exact hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hσ (extend_apply_self _) (extend_apply_self _) hx -- The classification of real connections over a trivial bundle section classification - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] - - /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term - -For technical reasons, this is only almost true: the left hand sides agree for all `X`, `σ` and `x` -such that `σ` is differentiable at `x`. (Since the literature mostly considers smooth connections, -this is not an issue for mathematical practice at all.) -The reason is because of the construction of a covariant derivative from a zero-order term `A`: -`of_endomorphism A X₀ σ₀` is defined by turning the tangent vectors `X₀` and `σ₀` at `x` -into vector fields near `x` --- which are smooth by construction. Thus, if `σ` is not differentiable -at `x`, `of_endomorphism A` at `x` uses a smooth extension of `σ x`, with different results. -/ -lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ E'] - (cov : CovariantDerivative 𝓘(ℝ, E) E' (Bundle.Trivial E E')) : - ∃ (A : E → E →L[ℝ] E' →L[ℝ] E'), - ∀ X : (x : E) → TangentSpace 𝓘(ℝ, E) x, ∀ σ : (x : E) → Trivial E E' x, ∀ x : E, +lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + (cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)) + {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) : + ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), + ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x ∈ s, MDiffAt (T% σ) x → - cov X σ x = (CovariantDerivative.of_endomorphism A) X σ x := by - use fun x ↦ difference cov.isCovariantDerivativeOn - (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn (mem_univ x) - intro X σ x hσ - simp only [CovariantDerivative.of_endomorphism] - erw [difference_apply cov.isCovariantDerivativeOn - (CovariantDerivative.trivial 𝓘(ℝ, E) E E').isCovariantDerivativeOn _ X hσ, - CovariantDerivative.trivial] - simp only [mfderiv_eq_fderiv] - module + letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) + cov X σ x = d + A x (X x) (σ x) := by + use fun x ↦ hcov.difference (trivial I M F |>.mono <| subset_univ s) x + intro X σ x hx hσ + rw [difference_apply] + · module + · assumption + +lemma _root_.CovariantDerivative.exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + (cov : CovariantDerivative I F (Bundle.Trivial M F)) : + ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), + ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x, + MDiffAt (T% σ) x → + letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) + cov X σ x = d + A x (X x) (σ x) := by + simpa using cov.isCovariantDerivativeOn.exists_endomorph end classification From 7595a39a0a887a7e39c37bc1caec08f58024f9d0 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 15 Jul 2025 15:33:17 +0200 Subject: [PATCH 280/601] Add pullback of LocalFrame stub --- .../Manifold/VectorBundle/LocalFrame.lean | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 6e3fe867169b0e..5d76aed37f8d0d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -273,6 +273,30 @@ end set_option linter.style.commandStart true +section pullback + +variable {E' : Type*} [NormedAddCommGroup E'] + [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] -- [IsManifold I 0 M] + -- [ContMDiffVectorBundle n F V I] + +-- Note: there is some mathematical content to the sorry. The `have` statement is +-- about maps to the total space of the original bundle and we want to look at +-- the same map seen as a map into the total space of the pullback bundle. +lemma pullback (hs : IsLocalFrameOn I F n s u) (f : ContMDiffMap I' I M' M n) : + letI (x : M') : AddCommGroup ((f *ᵖ V) x) := inferInstanceAs (AddCommGroup <| V (f x)) + letI (x : M') : Module 𝕜 ((f *ᵖ V) x) := inferInstanceAs (Module 𝕜 <| V (f x)) + IsLocalFrameOn I' F n (V := f *ᵖ V) (fun i x' ↦ s i (f x')) (f ⁻¹' u) := + letI (x : M') : AddCommGroup ((f *ᵖ V) x) := inferInstanceAs (AddCommGroup <| V (f x)) + letI (x : M') : Module 𝕜 ((f *ᵖ V) x) := inferInstanceAs (Module 𝕜 <| V (f x)) + { linearIndependent hx := hs.linearIndependent hx, + generating hx := hs.generating hx, + contMDiffOn (i : ι) := by + have := (hs.contMDiffOn i).comp (s := f ⁻¹' u) f.contMDiff.contMDiffOn subset_rfl + sorry + } +end pullback + end IsLocalFrameOn end IsLocalFrame From c4238c1b6c0dfea766833aa8f78ff5c8d0a8867d Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 15 Jul 2025 16:35:32 +0200 Subject: [PATCH 281/601] More fun with automatic continuity of linear maps --- .../Geometry/Manifold/VectorBundle/Misc.lean | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean index 4dbbdf00b05397..fe8ab05983a3ed 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -30,6 +30,11 @@ def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] E →ₗ[R] F →ₗ[R] G := LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right +lemma isBilinearMap_eval (R : Type*) (E F : Type*) [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [Module R E] [Module R F] : + IsBilinearMap R (fun (e : E) (φ : E →ₗ[R] F) ↦ φ e) := by + constructor <;> simp + def IsBilinearMap.toContinuousLinearMap {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] @@ -44,6 +49,26 @@ def IsBilinearMap.toContinuousLinearMap IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) (by constructor <;> (intros;simp)) |>.toContinuousLinearMap +def isBilinearMap_evalL + (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] : + IsBilinearMap 𝕜 (fun (e : E) (φ : E →L[𝕜] F) ↦ φ e) := by + constructor <;> simp + +def evalL + (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] : E →L[𝕜] (E →L[𝕜] F) →L[𝕜] F := + (isBilinearMap_evalL 𝕜 E F).toContinuousLinearMap end section prerequisites From c54f9254d57b2a3de9b5c1fe84d224d8599a48e7 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 15 Jul 2025 16:35:54 +0200 Subject: [PATCH 282/601] Projection operator in the trivial bundle case --- .../VectorBundle/CovariantDerivative.lean | 63 +++++++++++++++---- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index adf1ce31127d3d..3da7b8ed79c5d0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -381,12 +381,12 @@ lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] IsCovariantDerivativeOn F (fun X σ x ↦ f X σ x + A x (X x) (σ x)) s where addX X X' σ x hx := by simp [hf.addX] - module + abel smulX X σ g x hx := by simp [hf.smulX] addσ X σ σ' x hσ hσ' hx := by simp [hf.addσ X hσ hσ'] - module + abel smul_const_σ X {σ a} x hx := by simp [hf.smul_const_σ] leibniz X σ g x hσ hg hx := by @@ -555,7 +555,7 @@ variable (I M F) in @[simps] noncomputable def trivial : CovariantDerivative I F (Trivial M F) where toFun X s x := mfderiv I 𝓘(𝕜, F) s x (X x) - isCovariantDerivativeOn := + isCovariantDerivativeOn := -- TODO use previous work { addX X X' σ x _ := by simp smulX X σ c' x _ := by simp addσ X σ σ' x hσ hσ' hx := by @@ -788,14 +788,14 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x -- The classification of real connections over a trivial bundle section classification + +variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] + /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term -/ -lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] - (cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)) - {s : Set M} - (hcov : IsCovariantDerivativeOn F cov s) : +lemma exists_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x ∈ s, MDiffAt (T% σ) x → @@ -807,18 +807,59 @@ lemma exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] · module · assumption -lemma _root_.CovariantDerivative.exists_endomorph [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] +noncomputable def one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + Π x : M, TangentSpace I x →L[ℝ] F →L[ℝ] F := + hcov.exists_one_form.choose + +lemma eq_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + {X : (x : M) → TangentSpace I x} {σ : M → F} + {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) + cov X σ x = d + hcov.one_form x (X x) (σ x) := + hcov.exists_one_form.choose_spec X σ x hx hσ + +lemma _root_.CovariantDerivative.exists_one_form (cov : CovariantDerivative I F (Bundle.Trivial M F)) : ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x, MDiffAt (T% σ) x → letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) cov X σ x = d + A x (X x) (σ x) := by - simpa using cov.isCovariantDerivativeOn.exists_endomorph + simpa using cov.isCovariantDerivativeOn.exists_one_form end classification +section projection_trivial_bundle + +variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + +local notation "TM" => TangentSpace I + +-- instance (f : F) : CoeOut (TangentSpace 𝓘(ℝ, F) f) F := +-- ⟨fun x ↦ x⟩ + +noncomputable +def projection {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + (TM x) × F →L[ℝ] F := + .snd ℝ (TM x) F + (evalL ℝ F F f ∘L hcov.one_form x ∘L .fst ℝ (TM x) F) + +@[simp] +lemma projection_apply {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : + hcov.projection x f (v, w) = w + hcov.one_form x v f := rfl + +lemma cov_eq_proj {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) (X : Π x : M, TM x) (σ : M → F) + {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + cov X σ x = hcov.projection x (σ x) (X x, mfderiv I 𝓘(ℝ, F) σ x (X x)) := by + simpa using hcov.eq_one_form hσ + +end projection_trivial_bundle + end IsCovariantDerivativeOn section from_trivialization From 9816e63e5224cf54a7e44cec5da97cf7ded5b726 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 15 Jul 2025 17:35:50 +0200 Subject: [PATCH 283/601] Clean up notation of C^k connections --- .../VectorBundle/CovariantDerivative.lean | 67 ++++++++++--------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 3da7b8ed79c5d0..c7886bc1b1f083 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -202,7 +202,7 @@ This is a class so typeclass inference can deduce this automatically. class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (u : Set M) where - regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, + contMDiff : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, CMDiff[u] (k + 1) (T% σ) → CMDiff[u] k (T% X) → CMDiff[u] k (T% (cov X σ)) @@ -314,10 +314,10 @@ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : ContMDiffCovariantDerivativeOn F n (fun X σ ↦ (f • (cov X σ)) + (1 - f) • (cov' X σ)) u where - regularity hX hσ := by + contMDiff hX hσ := by apply ContMDiffOn.add_section - · exact hf.smul_section <| Hcov.regularity hX hσ - · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.regularity hX hσ + · exact hf.smul_section <| Hcov.contMDiff hX hσ + · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hσ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] @@ -371,6 +371,15 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] rw [this, one_smul] simp +/-- A convex combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ +lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination' {n : ℕ∞} + [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} + {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) + {f : ι → M → 𝕜} (hf : ∀ i ∈ s, CMDiff[u] n (f i)) : + ContMDiffCovariantDerivativeOn F n (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where + contMDiff hσ hX := + ContMDiffOn.sum_section (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ hX) variable {s : Set M} {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} @@ -464,17 +473,20 @@ lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl --- TODO: relative the definition below to ContMDiffCovariantDerivativeOn /-- A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ -class IsCkConnection (cov : CovariantDerivative I F V) (k : ℕ∞) [IsManifold I 1 M] where - regularity : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - CMDiff (k + 1) (T% σ) → ContMDiff I (I.prod 𝓘(𝕜, E)) k (T% X) → - -- TODO: CMDiff does not work here! - ContMDiff% k (T% (cov X σ)) +class ContMDiffCovariantDerivative [IsManifold I 1 M] + (cov : CovariantDerivative I F V) (k : ℕ∞) where + contMDiff : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ + +@[simp] +lemma contMDiffCovariantDerivativeOn_univ_iff [IsManifold I 1 M] + {cov : CovariantDerivative I F V} {k : ℕ∞} : + ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ ↔ ContMDiffCovariantDerivative cov k := + ⟨fun h ↦ ⟨h⟩, fun h ↦ h.contMDiff⟩ -- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection -- is of class C^k (up to off-by-one errors) @@ -519,30 +531,24 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma IsCkConnection.convexCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.convexCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) - (hcov : IsCkConnection cov n) (hcov' : IsCkConnection cov' n) : - IsCkConnection (convexCombination cov cov' f) n where - regularity {X σ} hX hσ := by - apply ContMDiff.add_section - · exact hf.smul_section <| hcov.regularity hX hσ - · exact (contMDiff_const.sub hf).smul_section <| hcov'.regularity hX hσ + (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : + ContMDiffCovariantDerivative (convexCombination cov cov' f) n where + contMDiff := + ContMDiffCovariantDerivativeOn.convexCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff /-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma IsCkConnection.convexCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.convexCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) - (hcov : ∀ i ∈ s, IsCkConnection (cov i) n) : - IsCkConnection (convexCombination' cov hf) n where - regularity {X σ} hX hσ := by - unfold CovariantDerivative.convexCombination' - dsimp - have ms (i) (hi : i ∈ s) : ContMDiff I (I.prod 𝓘(𝕜, F)) n - (T% (f i • (cov i) X σ)) := by - apply (hf' i hi).smul_section <| IsCkConnection.regularity hX hσ (self := hcov i hi) - exact .sum_section (t := fun i ↦ f i • (cov i) X σ) ms + (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : + ContMDiffCovariantDerivative (convexCombination' cov hf) n where + contMDiff := + ContMDiffCovariantDerivativeOn.convexCombination' + (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) -- Future: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) @@ -579,8 +585,9 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] -- regularity and use ∞ from `open scoped ContDiff` instead. /-- The trivial connection on the trivial bundle is smooth -/ -lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where - regularity {X σ} hX hσ := by +lemma trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where + contMDiff := by -- {X σ} hX hσ + sorry /- -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well simp only [trivial] -- use a local trivialisation @@ -600,7 +607,7 @@ lemma trivial_isSmooth : IsCkConnection (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E simp at h₂ -- now use ContMDiffOn.congr and contDiff_infty_iff_fderiv, -- or perhaps a contMDiffOn version of this lemma? - sorry + sorry -/ noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where From 0b97c4978c5ebd3fb06cf538e74286e6f9e91416 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 15 Jul 2025 18:15:41 +0200 Subject: [PATCH 284/601] More local study of connections --- .../VectorBundle/CovariantDerivative.lean | 65 ++++++++++++++++--- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index c7886bc1b1f083..555b3e1b6daa77 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -32,6 +32,20 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] +section +variable {E' : Type*} [NormedAddCommGroup E'] + [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +axiom map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : M → M' + +lemma map_of_one_jet_spec {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : + map_of_one_jet u u' x = x' ∧ + MDiffAt (map_of_one_jet u u') x ∧ + mfderiv I I' (map_of_one_jet u u') x u = u' := by + sorry +end + variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] @@ -845,26 +859,59 @@ variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] local notation "TM" => TangentSpace I --- instance (f : F) : CoeOut (TangentSpace 𝓘(ℝ, F) f) F := --- ⟨fun x ↦ x⟩ +instance (f : F) : CoeOut (TangentSpace 𝓘(ℝ, F) f) F := + ⟨fun x ↦ x⟩ + +variable {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} noncomputable -def projection {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} - (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : - (TM x) × F →L[ℝ] F := +def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) × F →L[ℝ] F := .snd ℝ (TM x) F + (evalL ℝ F F f ∘L hcov.one_form x ∘L .fst ℝ (TM x) F) @[simp] -lemma projection_apply {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} - (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : +lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : hcov.projection x f (v, w) = w + hcov.one_form x v f := rfl -lemma cov_eq_proj {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} - (hcov : IsCovariantDerivativeOn F cov s) (X : Π x : M, TM x) (σ : M → F) +lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (X : Π x : M, TM x) (σ : M → F) {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : cov X σ x = hcov.projection x (σ x) (X x, mfderiv I 𝓘(ℝ, F) σ x (X x)) := by simpa using hcov.eq_one_form hσ +noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + Submodule ℝ (TM x × F) := + LinearMap.ker (hcov.projection x f) + +lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + IsCompl (hcov.horiz x f) (.prod ⊥ ⊤) := by + refine IsCompl.of_eq ?_ ?_ + · refine (Submodule.eq_bot_iff _).mpr ?_ + rintro ⟨u, w⟩ ⟨huw, hu, hw⟩ + simp_all [horiz] + · apply Submodule.sup_eq_top_iff _ _ |>.2 + intro u + use u - (0, hcov.projection x f u), ?_, (0, hcov.projection x f u), ?_, ?_ + all_goals simp [horiz] + +lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : F} + {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ + ∃ σ : M → F, MDiffAt (T% σ) x ∧ + σ x = f ∧ + mfderiv I 𝓘(ℝ, F) σ x u = v ∧ + cov (extend I E u) σ x = 0 := by + constructor + · intro huv + simp [horiz] at huv + let w : TangentSpace 𝓘(ℝ, F) f := v -- - hcov.projection x f (u, v) + rcases map_of_one_jet_spec u w with ⟨h, h', h''⟩ + use map_of_one_jet u w, ?_, h, h'' + · rw [hcov.eq_one_form] + · simp [w, h'', h, huv] + · rwa [mdifferentiableAt_section] + · rwa [mdifferentiableAt_section] + · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ + simp [horiz, ← covσ] + rw [hcov.eq_one_form σ_diff, extend_apply_self] + end projection_trivial_bundle end IsCovariantDerivativeOn From a269252bbff4a5021ff3593edd9d3b0349e20781 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 17 Jul 2025 12:33:18 +0200 Subject: [PATCH 285/601] Start map_of_one_jet --- .../VectorBundle/CovariantDerivative.lean | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 555b3e1b6daa77..1aeaf3bb909160 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -37,13 +37,70 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] -axiom map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : M → M' +def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := sorry + +lemma map_of_loc_one_jet_spec (e u : E) (e' u' : E') : + map_of_loc_one_jet e u e' u' e = e' ∧ + DifferentiableAt 𝕜 (map_of_loc_one_jet e u e' u') e ∧ + fderiv 𝕜 (map_of_loc_one_jet e u e' u') e u = u' := by + sorry + +def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : + M → M' := + letI ψ := extChartAt I' x' + letI φ := extChartAt I x + ψ.symm ∘ + (map_of_loc_one_jet (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ + φ + +/- + +/-- Conjugating a function to write it in the preferred charts around `x`. +The manifold derivative of `f` will just be the derivative of this conjugated function. -/ +@[simp, mfld_simps] +def writtenInExtChartAt (x : M) (f : M → M') : E → E' := + extChartAt I' (f x) ∘ f ∘ (extChartAt I x).symm +-/ lemma map_of_one_jet_spec {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : map_of_one_jet u u' x = x' ∧ MDiffAt (map_of_one_jet u u') x ∧ mfderiv I I' (map_of_one_jet u u') x u = u' := by - sorry + let ψ := extChartAt I' x' + let φ := extChartAt I x + rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) + (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') with ⟨h, h', h''⟩ + refine ⟨?_, ?_, ?_⟩ + · simp [map_of_one_jet] + erw [h] + simp [ψ] + · rw [mdifferentiableAt_iff] + constructor + · unfold map_of_one_jet + refold_let φ ψ + apply ContinuousAt.comp + · rw [Function.comp_apply, h] + apply continuousAt_extChartAt_symm + · apply ContinuousAt.comp + · apply h'.continuousAt + · apply continuousAt_extChartAt + · apply h'.differentiableWithinAt.congr_of_eventuallyEq + · have : (extChartAt I x).target ∈ 𝓝[range I] (φ x) := by + apply extChartAt_target_mem_nhdsWithin + filter_upwards [this] with e he + unfold map_of_one_jet writtenInExtChartAt + refold_let φ ψ + have : (ψ.symm ∘ map_of_loc_one_jet (φ x) ((mfderiv I 𝓘(𝕜, E) (φ) x) u) (ψ x') + ((mfderiv I' 𝓘(𝕜, E') (ψ) x') u') ∘ φ) x = x' := by + rw [Function.comp_apply, Function.comp_apply, h, extChartAt_to_inv x'] + rw [this] + refold_let φ ψ + simp only [Function.comp_apply, ] + rw [PartialEquiv.right_inv _ he, PartialEquiv.right_inv] + sorry + · rw [h] + sorry + · sorry end variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @@ -901,7 +958,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : constructor · intro huv simp [horiz] at huv - let w : TangentSpace 𝓘(ℝ, F) f := v -- - hcov.projection x f (u, v) + let w : TangentSpace 𝓘(ℝ, F) f := v rcases map_of_one_jet_spec u w with ⟨h, h', h''⟩ use map_of_one_jet u w, ?_, h, h'' · rw [hcov.eq_one_form] From ab97b3f211ba2ecdb0ba6d26e536e6e6e5798010 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 15:40:14 +0200 Subject: [PATCH 286/601] chore(Elaborators): fix a few typos in doc-strings --- Mathlib/Geometry/Manifold/Elaborators.lean | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index c49814b40dc9b7..cef3915b5c1fc1 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -308,8 +308,9 @@ elab:max "MDiff" t:term:arg : term => do | _ => throwError m!"Term {e} is not a function." -- TODO: say something about the expected type of `n` being in ℕ or WithTop ℕ∞! -/-- `CMDiffAt[s] n f` elaborates to `ContMDiffWithinAt I J n f s`, -trying to determine `I` and `J` from the local context. -/ +/-- `CMDiffAt[s] n f x` elaborates to `ContMDiffWithinAt I J n f s x`, +trying to determine `I` and `J` from the local context. +The argument `x` can be omitted. -/ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none @@ -325,8 +326,9 @@ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do return ← mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] | _ => throwError m!"Term {ef} is not a function." -/-- `CMDiffAt n f` elaborates to `ContMDiffAt I J n f s` -trying to determine `I` and `J` from the local context. -/ +/-- `CMDiffAt n f x` elaborates to `ContMDiffAt I J n f x` +trying to determine `I` and `J` from the local context. +The argument `x` can be omitted. -/ elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none @@ -358,8 +360,8 @@ elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do /-- `CMDiff n f` elaborates to `ContMDiff I J n f`, trying to determine `I` and `J` from the local context. -/ -elab:max "CMDiff" nt:term:arg t:term:arg : term => do - let e ← Term.elabTerm t none +elab:max "CMDiff" nt:term:arg f:term:arg : term => do + let e ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none let ne ← Term.elabTerm nt wtn let etype ← inferType e >>= instantiateMVars @@ -371,8 +373,8 @@ elab:max "CMDiff" nt:term:arg t:term:arg : term => do | _ => throwError m!"Term {e} is not a function." -- TODO: remove in favour of CMDiff (after aligning their behaviour and adding a test for it!) -elab:max "ContMDiff%" nt:term:arg t:term:arg : term => do - let e ← Term.elabTerm t none +elab:max "ContMDiff%" nt:term:arg f:term:arg : term => do + let e ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none let ne ← Term.elabTermEnsuringType nt wtn let etype ← inferType e >>= instantiateMVars From c24b2fe63b20d6d418e65174f9f9929d95d7ac03 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 15:40:26 +0200 Subject: [PATCH 287/601] feat: custom elaborator for mderiv(Within) --- Mathlib/Geometry/Manifold/Elaborators.lean | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index cef3915b5c1fc1..d318b09a86f5ae 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -22,7 +22,9 @@ They allow writing - `CMDiff n f` for `ContMDiff I J n f` - `CMDiffAt n f x` for `ContMDiffAt I J n f x` - `CMDiff[u] n f` for `ContMDiffOn I J n f u` -- `CMDiffAt[u] n f` for `ContMDiffWithinAt I J n f u x`. +- `CMDiffAt[u] n f` for `ContMDiffWithinAt I J n f u x`, +- `mfderiv[u] f x` for `mfderivWithin I J f s x`, +- `mfderiv% f x` for `mfderiv I J f x`. In each of these cases, the models with corners are inferred from the domain and codomain of `f`. The search for models with corners uses the local context and is (almost) only syntactic, hence @@ -385,4 +387,31 @@ elab:max "ContMDiff%" nt:term:arg f:term:arg : term => do return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] | _ => throwError m!"Term {e} is not a function." +/-- `mfderiv[u] f x` elaborates to `mfderivWithin I J f x`, +trying to determine `I` and `J` from the local context. -/ +elab:max "mfderiv[" s:term:arg "]" t:term:arg : term => do + let es ← Term.elabTerm s none + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + let _estype ← inferType es >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + -- TODO: check `estype` and src are compatible + return ← mkAppM ``mfderivWithin #[srcI, tgtI, e, es] + | _ => throwError m!"Term {e} is not a function." + +/-- `mfderiv f x` elaborates to `mfderiv I J f x`, +trying to determine `I` and `J` from the local context. -/ +elab:max "mfderiv%" t:term:arg : term => do + let e ← Term.elabTerm t none + let etype ← inferType e >>= instantiateMVars + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM `mfderiv #[srcI, tgtI, e] + | _ => throwError m!"Term {e} is not a function." + end From 05048fa47eab3b99ed61e720e946dcf8d2425a61 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 15:45:43 +0200 Subject: [PATCH 288/601] And add some tests, including some for (already fine) error messages --- .../DifferentialGeometry/Elaborators.lean | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/MathlibTest/DifferentialGeometry/Elaborators.lean b/MathlibTest/DifferentialGeometry/Elaborators.lean index 66bf1c5a8806a0..1e3244a773bf48 100644 --- a/MathlibTest/DifferentialGeometry/Elaborators.lean +++ b/MathlibTest/DifferentialGeometry/Elaborators.lean @@ -338,3 +338,104 @@ info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a #check MDifferentiableAt% (T% s) end differentiability + +section mfderiv + +variable {EM' : Type*} [NormedAddCommGroup EM'] + [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +variable {f : M → M'} {s : Set M} {m : M} + +/-- info: mfderiv I I' f : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ +#guard_msgs in +#check mfderiv% f + +/-- info: mfderiv I I' f m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ +#guard_msgs in +#check mfderiv% f m + +/-- info: mfderivWithin I I' f s : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ +#guard_msgs in +#check mfderiv[s] f + +/-- info: mfderivWithin I I' f s m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ +#guard_msgs in +#check mfderiv[s] f m + +variable {f : E → EM'} {s : Set E} {m : E} + +/-- +info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) +-/ +#guard_msgs in +#check mfderiv% f + +/-- +info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) +-/ +#guard_msgs in +#check mfderiv% f m + +/-- +info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) +-/ +#guard_msgs in +#check mfderiv[s] f + +/-- +info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) +-/ +#guard_msgs in +#check mfderiv[s] f m + +section errors + +-- Test an error message, about mismatched types. +variable {s' : Set M} {m' : M} + +/-- +error: Application type mismatch: In the application + mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m' +the argument + m' +has type + M : Type u_4 +but is expected to have type + E : Type u_2 +--- +info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f sorry : TangentSpace 𝓘(𝕜, E) sorry →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f sorry) +-/ +#guard_msgs in +#check mfderiv% f m' + +-- Error messages: argument s has mismatched type. +/-- +error: Application type mismatch: In the application + mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s' +the argument + s' +has type + Set.{u_4} M : Type u_4 +but is expected to have type + Set.{u_2} E : Type u_2 +-/ +#guard_msgs in +#check mfderiv[s'] f + +/-- +error: Application type mismatch: In the application + mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s' +the argument + s' +has type + Set.{u_4} M : Type u_4 +but is expected to have type + Set.{u_2} E : Type u_2 +-/ +#guard_msgs in +#check mfderiv[s'] f m + +end errors + +end mfderiv From a3302d11e7a0d0aa9d6b94ba96abb7ebf8ae0e7f Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 17 Jul 2025 17:28:37 +0200 Subject: [PATCH 289/601] Reduce map_of_one_jet_spec to the local case --- .../VectorBundle/CovariantDerivative.lean | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1aeaf3bb909160..22d345572f8052 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -11,6 +11,7 @@ import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.VectorBundle.Misc import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket +import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary import Mathlib.Geometry.Manifold.Elaborators /-! @@ -54,53 +55,50 @@ def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I (map_of_loc_one_jet (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ φ -/- +-- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. -/-- Conjugating a function to write it in the preferred charts around `x`. -The manifold derivative of `f` will just be the derivative of this conjugated function. -/ -@[simp, mfld_simps] -def writtenInExtChartAt (x : M) (f : M → M') : E → E' := - extChartAt I' (f x) ∘ f ∘ (extChartAt I x).symm +/-- For any `(x, u) ∈ TM` and `(x', u') ∈ TM'`, `map_of_one_jet u u'` sends `x` to `x'` and +its derivative sends `u` to `u'`. We need to assume the target manifold `M'` has no boundary +since we cannot hope the result is `x` and `x'` are boundary points and `u` is inward +while `u'` is outward. -/ -lemma map_of_one_jet_spec {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : +lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] + [BoundarylessManifold I' M'] {x : M} (u : TangentSpace I x) {x' : M'} + (u' : TangentSpace I' x') : map_of_one_jet u u' x = x' ∧ MDiffAt (map_of_one_jet u u') x ∧ mfderiv I I' (map_of_one_jet u u') x u = u' := by let ψ := extChartAt I' x' let φ := extChartAt I x + let g := map_of_loc_one_jet (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') + let Ψ : M' → E' := ψ -- FIXME: this is working around a limitation of MDiffAt elaborator + have hψ : MDiffAt Ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') + let Φ : M → E := φ -- FIXME: this is working around a limitation of MDiffAt elaborator + have hφ : MDiffAt Φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) - (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') with ⟨h, h', h''⟩ - refine ⟨?_, ?_, ?_⟩ - · simp [map_of_one_jet] - erw [h] - simp [ψ] - · rw [mdifferentiableAt_iff] - constructor - · unfold map_of_one_jet - refold_let φ ψ - apply ContinuousAt.comp - · rw [Function.comp_apply, h] - apply continuousAt_extChartAt_symm - · apply ContinuousAt.comp - · apply h'.continuousAt - · apply continuousAt_extChartAt - · apply h'.differentiableWithinAt.congr_of_eventuallyEq - · have : (extChartAt I x).target ∈ 𝓝[range I] (φ x) := by - apply extChartAt_target_mem_nhdsWithin - filter_upwards [this] with e he - unfold map_of_one_jet writtenInExtChartAt - refold_let φ ψ - have : (ψ.symm ∘ map_of_loc_one_jet (φ x) ((mfderiv I 𝓘(𝕜, E) (φ) x) u) (ψ x') - ((mfderiv I' 𝓘(𝕜, E') (ψ) x') u') ∘ φ) x = x' := by - rw [Function.comp_apply, Function.comp_apply, h, extChartAt_to_inv x'] - rw [this] - refold_let φ ψ - simp only [Function.comp_apply, ] - rw [PartialEquiv.right_inv _ he, PartialEquiv.right_inv] - sorry - · rw [h] - sorry - · sorry + (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') with + ⟨h : g (φ x) = ψ x', h', h''⟩ + have hg : MDiffAt g (φ x) := mdifferentiableAt_iff_differentiableAt.mpr h' + have hgφ : MDiffAt (g ∘ φ) x := h'.comp_mdifferentiableAt hφ + let Ψi : E' → M' := ψ.symm -- FIXME: this is working around a limitation of MDiffAt elaborator + have hψi : MDiffAt Ψi (g (φ x)) := by + rw [h] + have := mdifferentiableWithinAt_extChartAt_symm (I := I') (mem_extChartAt_target x') + exact this.mdifferentiableAt (range_mem_nhds_isInteriorPoint <| + BoundarylessManifold.isInteriorPoint' x') + unfold map_of_one_jet + refold_let g φ ψ at * + refine ⟨by simp [h, ψ], hψi.comp x hgφ, ?_⟩ + rw [mfderiv_comp x hψi hgφ, mfderiv_comp x hg hφ, mfderiv_eq_fderiv] + change (mfderiv 𝓘(𝕜, E') I' Ψi (g (φ x))) (fderiv 𝕜 g (φ x) <| mfderiv I 𝓘(𝕜, E) φ x u) = u' + rw [h] at hψi + rw [h'', h, ← mfderiv_comp_apply x' hψi hψ] + have : Ψi ∘ ψ =ᶠ[𝓝 x'] id := by + have : ∀ᶠ z in 𝓝 x', z ∈ ψ.source := extChartAt_source_mem_nhds x' + filter_upwards [this] with z hz + exact ψ.left_inv hz + simp [this.mfderiv_eq] + rfl end variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] From 9a22a01b2b9ba8a6eeff90a610bc0395534c7fb4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 15:52:50 +0200 Subject: [PATCH 290/601] chore(Misc): minor tweaks --- Mathlib/Geometry/Manifold/VectorBundle/Misc.lean | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean index fe8ab05983a3ed..5510769c0c0389 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -106,8 +106,7 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @[simp] theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : - MDiffAt (T% σ) e ↔ - DifferentiableAt 𝕜 σ e := by + MDiffAt (T% σ) e ↔ DifferentiableAt 𝕜 σ e := by simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] attribute [simp] mdifferentiableAt_iff_differentiableAt @@ -139,10 +138,9 @@ omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → variable {I F V x} in /-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, one is differentiable at `x` iff the other is. -/ -lemma mfderiv_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) +lemma mdifferentiable_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) (hσ : ∀ x ∈ s, σ x = σ' x) : - MDiffAt (T% σ) x ↔ - MDiffAt (T% σ') x := + MDiffAt (T% σ) x ↔ MDiffAt (T% σ') x := ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ From 517938aa37a82dd527d78afb9e9cb5f8c270befa Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 16:12:57 +0200 Subject: [PATCH 291/601] Use mfderiv elaborator a bit --- .../Geometry/Manifold/VectorBundle/LeviCivita.lean | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index a3863831b99f7a..5c6315bc1b82d0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -129,7 +129,7 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) def IsCompatible : Prop := ∀ X Y Z : Π x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! ∀ x : M, - mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x) = ⟪cov X Y, Z⟫ x + ⟪Y, cov X Z⟫ x + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪cov X Y, Z⟫ x + ⟪Y, cov X Z⟫ x -- TODO: make g part of the notation! /-- A covariant derivative on `TM` is called the **Levi-Civita connection** for a Riemannian metric @@ -138,7 +138,7 @@ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree -- This is mild defeq abuse, right? variable (X Y Z) in -noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv I 𝓘(ℝ) ⟪Y, Z⟫ x (X x)) +noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv% ⟪Y, Z⟫ x (X x)) section rhs_aux @@ -180,7 +180,7 @@ lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI A (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) + letI A (x) : ℝ := (mfderiv% f x) (X x) rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by ext x rw [rhs_aux, product_smul_left, mfderiv_smul (foo hY hZ x) (hf x)] @@ -188,7 +188,7 @@ lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDi variable (X) in lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI A (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) + letI A (x) : ℝ := (mfderiv% f x) (X x) rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] @@ -299,12 +299,12 @@ lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ ext x simp only [Pi.mul_apply, Pi.add_apply] have h1 : VectorField.mlieBracket I X (f • Z) = - f • VectorField.mlieBracket I X Z + (fun x ↦ mfderiv I 𝓘(ℝ, ℝ) f x (X x)) • Z := by + f • VectorField.mlieBracket I X Z + (fun x ↦ mfderiv% f x (X x)) • Z := by ext x rw [VectorField.mlieBracket_smul_right (hf x) (hZ x), add_comm] simp have h2 : VectorField.mlieBracket I (f • Z) Y = - -(fun x ↦ mfderiv I 𝓘(ℝ, ℝ) f x (Y x)) • Z + f • VectorField.mlieBracket I Z Y := by + -(fun x ↦ mfderiv% f x (Y x)) • Z + f • VectorField.mlieBracket I Z Y := by ext x rw [VectorField.mlieBracket_smul_left (hf x) (hZ x)] simp @@ -312,7 +312,7 @@ lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ set A := rhs_aux I X Y Z x set B := rhs_aux I Y Z X x set C := rhs_aux I Z X Y x - set D := (fun x ↦ (mfderiv I 𝓘(ℝ, ℝ) f x) (X x)) • Z + set D := (fun x ↦ (mfderiv% f x) (X x)) • Z rw [product_add_right, product_add_right] -- These are all science fiction, and not fully true! From 8f2168af94f3d2d1189dd2e9e817b6df09907ccf Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 16:41:29 +0200 Subject: [PATCH 292/601] feat: mostly prove that a convex combination of covariant derivatives is one - prove this by induction from the two-argument case instead (The other induction arguments were repeating itself.) - use a better induction principle: over non-empty finset To facilicate this, phrase the non-emptiness hypothesis using finsets. TODO: congruence lemma for IsCovariantDerivativeOn (missing anyway, not so hard) Bigger TODO: fully refactor this proof to make it go through. The induction has an annoying gotcha, that it doesn't handle one scalar being zero at a point... (Generalising this to locally finite sums will make it go away, though.) --- .../VectorBundle/CovariantDerivative.lean | 100 +++++++++--------- 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 22d345572f8052..156b2d30584e2c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -389,60 +389,56 @@ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hσ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +def convexCombination' {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : - IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where - addX X X' σ x hx := by - rw [← Finset.sum_add_distrib] - congr - ext i - simp [(h i).addX] - smulX X σ g x hx := by - rw [Finset.smul_sum] - congr - ext i - simp [(h i).smulX] - module - addσ X σ σ' x hσ hσ' hx := by - -- XXX: is this nicer using induction? - classical - induction s using Finset.induction with - | empty => simp - | insert a s has h => - simp [Finset.sum_insert has] - sorry - smul_const_σ X {σ a} x hx := by - rw [Finset.smul_sum] - congr - ext i - simp [(h i).smul_const_σ] - module - leibniz X σ g x hσ hg hx := by - calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x - _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x - + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x) := by + IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u := by + classical + induction hs using Finset.Nonempty.cons_induction generalizing f with + | singleton a => simp_all + | cons i₀ s hi₀ hs h' => + simp only [Finset.cons_eq_insert] + let g : ι → M → 𝕜 := fun i x ↦ f i x / (1 - f i₀ x) + have hg : ∑ i ∈ s, g i = 1 := by + ext x + simp [g] + calc ∑ i ∈ s, f i x / (1 - f i₀ x) + _ = ∑ i ∈ s, (1 - f i₀ x)⁻¹ • f i x := by simp_rw [smul_eq_mul, inv_mul_eq_div] + _ = (1 - f i₀ x)⁻¹ • ∑ i ∈ s, f i x := by rw [Finset.smul_sum] + _ = (1 - f i₀ x)⁻¹ • (∑ i ∈ Finset.cons i₀ s hi₀, f i x - f i₀ x):= by + congr + rw [eq_sub_iff_add_eq, Finset.sum_cons, add_comm] + _ = (1 - f i₀ x)⁻¹ • (1 - f i₀ x):= by + congr + sorry -- exact hf except applied + _ = 1 := sorry + + -- TODO: rejigger my set-up to provide this + -- at x, some function is non-zero, and then the same holds in a neighbourhood + -- (by continuity, which I'll also assume) + -- so, need to shrink the open set and patch together, awful, but can be done + have bettersetup : ∀ x, f i₀ x ≠ 1 := sorry + have side_computation := calc fun X σ x ↦ ∑ i ∈ insert i₀ s, f i x • cov i X σ x + _ = fun X σ x ↦ f i₀ x • cov i₀ X σ x + ∑ i ∈ s, f i x • cov i X σ x := by + simp [Finset.sum_insert hi₀] + _ = fun X σ x ↦ f i₀ x • cov i₀ X σ x + (1 - f i₀ x) • ∑ i ∈ s, g i x • cov i X σ x := by + ext X σ x congr - ext i - rw [(h i).leibniz _ hσ hg] - simp_rw [Pi.smul_apply', smul_add, add_left_inj] - rw [smul_comm] - _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x) - + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by - rw [Finset.sum_add_distrib] - _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by - -- There has to be a shorter proof! - simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, add_right_inj] - set B := (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x - trans (∑ i ∈ s, f i x) • B - · rw [Finset.sum_smul] - have : ∑ i ∈ s, f i x = 1 := by convert congr_fun hf x; simp - rw [this, one_smul] - simp + rw [Finset.smul_sum] + congr; ext i + simp only [g] + -- this should be obvious now! + rw [← smul_assoc, smul_eq_mul, mul_div_cancel₀ (a := f i x) (b := 1 - f i₀ x)] + rw [sub_ne_zero]; exact (bettersetup x).symm + have : IsCovariantDerivativeOn F (fun X σ x ↦ + f i₀ x • cov i₀ X σ x + (1 - f i₀ x) • ∑ i ∈ s, g i x • cov i X σ x) u := + (h i₀).convexCombination (h' hg) _ + -- apply a suitable congruence lemma: TODO write! + sorry /-- A convex combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination' {n : ℕ∞} - [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} + [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) {f : ι → M → 𝕜} (hf : ∀ i ∈ s, CMDiff[u] n (f i)) : @@ -592,11 +588,11 @@ def convexCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : cov.isCovariantDerivativeOn.convexCombination cov'.isCovariantDerivativeOn _ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +def convexCombination' {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where toFun X t x := ∑ i ∈ s, (f i x) • (cov i) X t x - isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' + isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' hs (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ @@ -610,11 +606,11 @@ lemma ContMDiffCovariantDerivative.convexCombination [IsManifold I 1 M] [VectorB /-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ lemma ContMDiffCovariantDerivative.convexCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] - {ι : Type*} {s : Finset ι} [Nonempty s] + {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : - ContMDiffCovariantDerivative (convexCombination' cov hf) n where + ContMDiffCovariantDerivative (convexCombination' hs cov hf) n where contMDiff := ContMDiffCovariantDerivativeOn.convexCombination' (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) From edc42c15edd64d60297903c8480ad6f970d672d2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 17 Jul 2025 17:52:36 +0200 Subject: [PATCH 293/601] feat: add and use a congruence lemma for IsCovariantDerivativeOn --- .../VectorBundle/CovariantDerivative.lean | 23 ++++++++++++++++++- .../Manifold/VectorBundle/LeviCivita.lean | 4 +++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 156b2d30584e2c..1c3fa365a6f680 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -315,6 +315,18 @@ lemma iUnion {ι : Type*} end changing_set +/- Congruence properties -/ +section + +lemma congr {f g : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} + (hf : IsCovariantDerivativeOn F f s) + -- Is this too strong? Will see! + (hfg : ∀ {X : Π x : M, TangentSpace I x}, + ∀ {σ : Π x : M, V x}, ∀ {x}, x ∈ s → f X σ x = g X σ x) : + IsCovariantDerivativeOn F g s := sorry + +end + section computational_properties lemma smul_const_X @@ -388,6 +400,14 @@ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination · exact hf.smul_section <| Hcov.contMDiff hX hσ · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hσ +/-- A finite convex combination of covariant derivatives is a covariant derivative. -/ +def convexCombination'_aux {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) + {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) + (hf' : ∀ i ∈ s, ∀ x ∈ u, f i x ≠ 0) : + IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u := by + sorry + /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ def convexCombination' {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} @@ -433,7 +453,8 @@ def convexCombination' {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) have : IsCovariantDerivativeOn F (fun X σ x ↦ f i₀ x • cov i₀ X σ x + (1 - f i₀ x) • ∑ i ∈ s, g i x • cov i X σ x) u := (h i₀).convexCombination (h' hg) _ - -- apply a suitable congruence lemma: TODO write! + apply this.congr + intro X σ x hx sorry /-- A convex combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 5c6315bc1b82d0..3dc61265ebf1d4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -529,7 +529,9 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (lcCandidate I M) e.baseSet := by - sorry -- need some IsCovariantDerivativeOn_congr + lemma bar + apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidate_aux I e) + intro X σ x hx + exact (bar I X σ e hx).symm end From ba1c2d58c81a6cd15921bc8c6488abe1ed60bea6 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 17 Jul 2025 18:39:13 +0200 Subject: [PATCH 294/601] Some linear algebra --- .../VectorBundle/CovariantDerivative.lean | 44 +++++++++++++++++-- .../Manifold/VectorBundle/LocalFrame.lean | 6 +++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1c3fa365a6f680..ffa110e36ea503 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -29,6 +29,30 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section general_lemmas -- those lemmas should move +section linear_algebra +variable (𝕜 : Type*) [Field 𝕜] + {E : Type*} [AddCommGroup E] [Module 𝕜 E] + {E' : Type*} [AddCommGroup E'] [Module 𝕜 E'] + +lemma exists_map_of (u : E) (u' : E') : + ∃ φ : E →ₗ[𝕜] E', (u = 0 → u' = 0) → φ u = u' := by + by_cases h : u = 0 + · simp [h] + tauto + · have indep : LinearIndepOn 𝕜 id {u} := LinearIndepOn.id_singleton 𝕜 h + let s := indep.extend (subset_univ _) + have hus : u ∈ s := singleton_subset_iff.mp <| indep.subset_extend (subset_univ _) + use (Basis.extend indep).constr (M' := E') (S := 𝕜) fun _ ↦ u' + simpa [h, Basis.extend_apply_self] using (Basis.extend indep).constr_basis _ _ ⟨u, hus⟩ + +open Classical in +noncomputable def map_of (u : E) (u' : E') : E →ₗ[𝕜] E' := (exists_map_of 𝕜 u u').choose + +variable {𝕜} +lemma map_of_spec (u : E) (u' : E') (h : u = 0 → u' = 0) : map_of 𝕜 u u' u = u' := + (exists_map_of 𝕜 u u').choose_spec h +end linear_algebra + variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] @@ -41,7 +65,7 @@ variable {E' : Type*} [NormedAddCommGroup E'] def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := sorry -lemma map_of_loc_one_jet_spec (e u : E) (e' u' : E') : +lemma map_of_loc_one_jet_spec (e u : E) (e' u' : E') (hu : u = 0 → u' = 0) : map_of_loc_one_jet e u e' u' e = e' ∧ DifferentiableAt 𝕜 (map_of_loc_one_jet e u e' u') e ∧ fderiv 𝕜 (map_of_loc_one_jet e u e' u') e u = u' := by @@ -64,7 +88,7 @@ while `u'` is outward. -/ lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] [BoundarylessManifold I' M'] {x : M} (u : TangentSpace I x) {x' : M'} - (u' : TangentSpace I' x') : + (u' : TangentSpace I' x') (hu : u = 0 → u' = 0) : map_of_one_jet u u' x = x' ∧ MDiffAt (map_of_one_jet u u') x ∧ mfderiv I I' (map_of_one_jet u u') x u = u' := by @@ -75,8 +99,10 @@ lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] have hψ : MDiffAt Ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') let Φ : M → E := φ -- FIXME: this is working around a limitation of MDiffAt elaborator have hφ : MDiffAt Φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) + replace hu : mfderiv I 𝓘(𝕜, E) φ x u = 0 → mfderiv I' 𝓘(𝕜, E') ψ x' u' = 0 := by + sorry rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) - (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') with + (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') hu with ⟨h : g (φ x) = ψ x', h', h''⟩ have hg : MDiffAt g (φ x) := mdifferentiableAt_iff_differentiableAt.mpr h' have hgφ : MDiffAt (g ∘ φ) x := h'.comp_mdifferentiableAt hφ @@ -193,6 +219,10 @@ lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module +@[simp] +lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : + extend I F (0 : V x) = 0 := by simp [extend, localExtensionOn_zero]; module + @[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : extend I F v x = v := by simpa [extend] using @@ -974,7 +1004,13 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : · intro huv simp [horiz] at huv let w : TangentSpace 𝓘(ℝ, F) f := v - rcases map_of_one_jet_spec u w with ⟨h, h', h''⟩ + by_cases hu : u = 0 + · subst hu + replace huv : v = 0 := by simpa using huv + subst huv + use fun x ↦ f + simpa [hcov.zeroX, mdifferentiableAt_section] using mdifferentiableAt_const + rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ use map_of_one_jet u w, ?_, h, h'' · rw [hcov.eq_one_form] · simp [w, h'', h, huv] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 5d76aed37f8d0d..b07cae2453a901 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -725,6 +725,12 @@ lemma localExtensionOn_add (v v' : V x) : · simp [hx, localExtensionOn] · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] +variable (b e) in +lemma localExtensionOn_zero : + localExtensionOn b e x 0 = 0 := by + ext x' + by_cases hx: x ∈ e.baseSet <;> simp [hx, localExtensionOn] + variable (b e) in lemma localExtensionOn_smul (a : 𝕜) (v : V x) : localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by From cda18801191b34317b8d7dc0abcfa6a4ae8d8e28 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 17 Jul 2025 23:01:08 +0200 Subject: [PATCH 295/601] Local frame fixes --- .../Geometry/Manifold/VectorBundle/LocalFrame.lean | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index b07cae2453a901..1867dda9c83dbc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -414,14 +414,14 @@ lemma localFrame_repr_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x : simpa [localFrame_repr] using (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_apply_of_notMem hx s i --- XXX: do I want this lemma, or just the IsLocalFrameOn version? +omit [IsManifold I 0 M] in variable (e b) in @[simp] lemma localFrame_repr_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : b.localFrame_repr I e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by - simp [localFrame_repr, hx, localFrame_toBasis_at, IsLocalFrameOn.toBasisAt] - congr - sorry + have ilf := b.localFrame_isLocalFrameOn_baseSet I 1 e + rw [show localFrame_toBasis_at e b hx = ilf.toBasisAt hx by ext j; simp [localFrame, hx]] + exact ilf.repr_apply_of_mem hx s i -- TODO: better name? omit [IsManifold I 0 M] in @@ -457,6 +457,7 @@ lemma localFrame_repr_apply_zero_at variable {n} +omit [IsManifold I 0 M] in /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ @@ -648,7 +649,8 @@ lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 refine ⟨fun h i ↦ mdifferentiableOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ apply ((b.localFrame_isLocalFrameOn_baseSet I 1 e).mono ht').mdifferentiableOn_of_repr (t := s) convert hi - sorry -- should be easy/already done above + sorry -- should be easy/already done above. + -- This doesn’t seem to be used except in the next lemma that is not used anywhere. omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its @@ -706,6 +708,7 @@ lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : simp [localExtensionOn, hx] nth_rw 2 [← (b.localFrame_toBasis_at e hx).sum_repr v] +omit [IsManifold I 0 M] in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) [ContMDiffVectorBundle 1 F V I] {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} From f7278925123a7687256a679cf9d6f486529e265d Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 17 Jul 2025 23:01:35 +0200 Subject: [PATCH 296/601] Finish map_of_one_jet_spec --- .../VectorBundle/CovariantDerivative.lean | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index ffa110e36ea503..d57536b7fa248d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -53,32 +53,56 @@ lemma map_of_spec (u : E) (u' : E') (h : u = 0 → u' = 0) : map_of 𝕜 u u' u (exists_map_of 𝕜 u u').choose_spec h end linear_algebra -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] section -variable {E' : Type*} [NormedAddCommGroup E'] - [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] -def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := sorry - -lemma map_of_loc_one_jet_spec (e u : E) (e' u' : E') (hu : u = 0 → u' = 0) : - map_of_loc_one_jet e u e' u' e = e' ∧ - DifferentiableAt 𝕜 (map_of_loc_one_jet e u e' u') e ∧ - fderiv 𝕜 (map_of_loc_one_jet e u e' u') e u = u' := by - sorry +variable (𝕜) in +noncomputable def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := + fun x ↦ e' + map_of 𝕜 u u' (x - e) + +lemma map_of_loc_one_jet_spec [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] + (e u : E) (e' u' : E') (hu : u = 0 → u' = 0) : + map_of_loc_one_jet 𝕜 e u e' u' e = e' ∧ + DifferentiableAt 𝕜 (map_of_loc_one_jet 𝕜 e u e' u') e ∧ + fderiv 𝕜 (map_of_loc_one_jet 𝕜 e u e' u') e u = u' := by + unfold map_of_loc_one_jet + let φ := (map_of 𝕜 u u').toContinuousLinearMap + have diff : Differentiable 𝕜 (map_of 𝕜 u u') := + (map_of 𝕜 u u').toContinuousLinearMap.differentiable + refine ⟨by simp, ?_, ?_⟩ + · apply (differentiableAt_const e').add + apply diff.differentiableAt.comp + fun_prop + · simp + rw [fderiv_sub_const] + change (fderiv 𝕜 φ e) u = _ + rw [φ.hasFDerivAt.fderiv] + exact map_of_spec u u' hu +noncomputable def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : M → M' := letI ψ := extChartAt I' x' letI φ := extChartAt I x ψ.symm ∘ - (map_of_loc_one_jet (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ + (map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ φ +lemma ContinuousLinearMap.IsInvertible.injective {R M M₂ : Type*} [TopologicalSpace M] + [TopologicalSpace M₂] [Semiring R] [AddCommMonoid M] [Module R M] + [AddCommMonoid M₂] [Module R M₂] {f : M →L[R] M₂} (h : f.IsInvertible) : + Function.Injective f := by + rcases h with ⟨ψ, hψ⟩ + refine Function.HasLeftInverse.injective ⟨ψ.symm, fun x ↦ ψ.symm_apply_eq.mpr (by simp [← hψ])⟩ + -- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. /-- For any `(x, u) ∈ TM` and `(x', u') ∈ TM'`, `map_of_one_jet u u'` sends `x` to `x'` and @@ -87,20 +111,26 @@ since we cannot hope the result is `x` and `x'` are boundary points and `u` is i while `u'` is outward. -/ lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] - [BoundarylessManifold I' M'] {x : M} (u : TangentSpace I x) {x' : M'} + [BoundarylessManifold I' M'] + [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] + {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') (hu : u = 0 → u' = 0) : map_of_one_jet u u' x = x' ∧ MDiffAt (map_of_one_jet u u') x ∧ mfderiv I I' (map_of_one_jet u u') x u = u' := by let ψ := extChartAt I' x' let φ := extChartAt I x - let g := map_of_loc_one_jet (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') + let g := map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') let Ψ : M' → E' := ψ -- FIXME: this is working around a limitation of MDiffAt elaborator have hψ : MDiffAt Ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') let Φ : M → E := φ -- FIXME: this is working around a limitation of MDiffAt elaborator have hφ : MDiffAt Φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) replace hu : mfderiv I 𝓘(𝕜, E) φ x u = 0 → mfderiv I' 𝓘(𝕜, E') ψ x' u' = 0 := by - sorry + have : Function.Injective (mfderiv I 𝓘(𝕜, E) φ x) := + (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x)).injective + rw [injective_iff_map_eq_zero] at this + have := map_zero (mfderiv I' 𝓘(𝕜, E') ψ x') + grind rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') hu with ⟨h : g (φ x) = ψ x', h', h''⟩ @@ -221,7 +251,7 @@ lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V @[simp] lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : - extend I F (0 : V x) = 0 := by simp [extend, localExtensionOn_zero]; module + extend I F (0 : V x) = 0 := by simp [extend, localExtensionOn_zero] @[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : extend I F v x = v := by From 72f03c2ab337b7db0744ad303011129e83ae35ce Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 18 Jul 2025 00:01:06 +0200 Subject: [PATCH 297/601] mfderiv_smul --- .../VectorBundle/CovariantDerivative.lean | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index d57536b7fa248d..cf77a4b5c9e382 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -191,12 +191,32 @@ lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) simp rfl -lemma mfderiv_smul {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) +lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) (hs : MDiffAt s x) (v : TangentSpace I x) : letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by - sorry + set φ := chartAt H x + -- TODO: the next two have should be special cases of the same lemma + have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [← this] at hs + have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [← this] at hf + have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hsf : MDiffAt (s • f) x := hs.smul hf + simp [mfderiv, hsf, hs, hf] + have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := + ModelWithCorners.uniqueDiffWithinAt_image I + erw [fderivWithin_smul uniq hs' hf'] + simp [PartialHomeomorph.left_inv φ (ChartedSpace.mem_chart_source x)] + rfl end general_lemmas @@ -554,7 +574,7 @@ section trivial_bundle variable (I M F) in @[simps] -noncomputable def trivial : +noncomputable def trivial [IsManifold I 1 M] : IsCovariantDerivativeOn F (V := Trivial M F) (fun X s x ↦ mfderiv I 𝓘(𝕜, F) s x (X x)) univ where addX X X' σ x _ := by simp @@ -572,7 +592,7 @@ noncomputable def trivial : rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) -lemma of_endomorphism (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : +lemma of_endomorphism [IsManifold I 1 M] (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : IsCovariantDerivativeOn F (fun (X : Π x : M, TangentSpace I x) (s : M → F) x ↦ letI d : F := mfderiv I 𝓘(𝕜, F) s x (X x) @@ -705,7 +725,7 @@ section trivial_bundle variable (I M F) in @[simps] -noncomputable def trivial : CovariantDerivative I F (Trivial M F) where +noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where toFun X s x := mfderiv I 𝓘(𝕜, F) s x (X x) isCovariantDerivativeOn := -- TODO use previous work { addX X X' σ x _ := by simp From 86980972923d52ed09438d71674db9c39633a74a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 22 Jul 2025 18:09:44 +0200 Subject: [PATCH 298/601] feat: complete proof that a convex combination of covariant derivatives is one --- .../VectorBundle/CovariantDerivative.lean | 104 ++++++++---------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index cf77a4b5c9e382..9172e68838e833 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -481,61 +481,53 @@ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hσ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination'_aux {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) - {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) - (hf' : ∀ i ∈ s, ∀ x ∈ u, f i x ≠ 0) : - IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u := by - sorry - -/-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) +def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : - IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u := by - classical - induction hs using Finset.Nonempty.cons_induction generalizing f with - | singleton a => simp_all - | cons i₀ s hi₀ hs h' => - simp only [Finset.cons_eq_insert] - let g : ι → M → 𝕜 := fun i x ↦ f i x / (1 - f i₀ x) - have hg : ∑ i ∈ s, g i = 1 := by - ext x - simp [g] - calc ∑ i ∈ s, f i x / (1 - f i₀ x) - _ = ∑ i ∈ s, (1 - f i₀ x)⁻¹ • f i x := by simp_rw [smul_eq_mul, inv_mul_eq_div] - _ = (1 - f i₀ x)⁻¹ • ∑ i ∈ s, f i x := by rw [Finset.smul_sum] - _ = (1 - f i₀ x)⁻¹ • (∑ i ∈ Finset.cons i₀ s hi₀, f i x - f i₀ x):= by - congr - rw [eq_sub_iff_add_eq, Finset.sum_cons, add_comm] - _ = (1 - f i₀ x)⁻¹ • (1 - f i₀ x):= by - congr - sorry -- exact hf except applied - _ = 1 := sorry - - -- TODO: rejigger my set-up to provide this - -- at x, some function is non-zero, and then the same holds in a neighbourhood - -- (by continuity, which I'll also assume) - -- so, need to shrink the open set and patch together, awful, but can be done - have bettersetup : ∀ x, f i₀ x ≠ 1 := sorry - have side_computation := calc fun X σ x ↦ ∑ i ∈ insert i₀ s, f i x • cov i X σ x - _ = fun X σ x ↦ f i₀ x • cov i₀ X σ x + ∑ i ∈ s, f i x • cov i X σ x := by - simp [Finset.sum_insert hi₀] - _ = fun X σ x ↦ f i₀ x • cov i₀ X σ x + (1 - f i₀ x) • ∑ i ∈ s, g i x • cov i X σ x := by - ext X σ x + IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where + addX X X' σ x hx := by + rw [← Finset.sum_add_distrib] + congr + ext i + simp [(h i).addX] + smulX X σ g x hx := by + rw [Finset.smul_sum] + congr + ext i + simp [(h i).smulX] + module + addσ X σ σ' x hσ hσ' hx := by + rw [← Finset.sum_add_distrib] + congr + ext i + rw [← smul_add, (h i).addσ X hσ hσ' hx] + smul_const_σ X {σ a} x hx := by + rw [Finset.smul_sum] + congr + ext i + simp [(h i).smul_const_σ] + module + leibniz X σ g x hσ hg hx := by + calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x + _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x) := by congr - rw [Finset.smul_sum] - congr; ext i - simp only [g] - -- this should be obvious now! - rw [← smul_assoc, smul_eq_mul, mul_div_cancel₀ (a := f i x) (b := 1 - f i₀ x)] - rw [sub_ne_zero]; exact (bettersetup x).symm - have : IsCovariantDerivativeOn F (fun X σ x ↦ - f i₀ x • cov i₀ X σ x + (1 - f i₀ x) • ∑ i ∈ s, g i x • cov i X σ x) u := - (h i₀).convexCombination (h' hg) _ - apply this.congr - intro X σ x hx - sorry + ext i + rw [(h i).leibniz _ hσ hg] + simp_rw [Pi.smul_apply', smul_add, add_left_inj] + rw [smul_comm] + _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x) + + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by + rw [Finset.sum_add_distrib] + _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by + -- There has to be a shorter proof! + simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, add_right_inj] + set B := (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x + trans (∑ i ∈ s, f i x) • B + · rw [Finset.sum_smul] + have : ∑ i ∈ s, f i x = 1 := by convert congr_fun hf x; simp + rw [this, one_smul] + simp /-- A convex combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination' {n : ℕ∞} @@ -689,11 +681,11 @@ def convexCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : cov.isCovariantDerivativeOn.convexCombination cov'.isCovariantDerivativeOn _ /-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) +def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where toFun X t x := ∑ i ∈ s, (f i x) • (cov i) X t x - isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' hs + isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ @@ -707,11 +699,11 @@ lemma ContMDiffCovariantDerivative.convexCombination [IsManifold I 1 M] [VectorB /-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ lemma ContMDiffCovariantDerivative.convexCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] - {ι : Type*} {s : Finset ι} (hs : Finset.Nonempty s) + {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : - ContMDiffCovariantDerivative (convexCombination' hs cov hf) n where + ContMDiffCovariantDerivative (convexCombination' cov hf) n where contMDiff := ContMDiffCovariantDerivativeOn.convexCombination' (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) From f95e291b8b69b4a9f6987c05666b3f20f7feb0a9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 22 Jul 2025 18:15:44 +0200 Subject: [PATCH 299/601] Some comment tweaks --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 3dc61265ebf1d4..e14129f1d6850b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -438,7 +438,7 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := fun X Y x ↦ - -- Choose a trivialisation of TM near x. + -- Choose a trivialisation of `TM` near `x`. letI b := Basis.ofVectorSpace ℝ E -- Case distinction: if E is trivial, there is only one choice anyway; -- otherwise, b must be non-trivial. @@ -446,8 +446,8 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e - -- The coefficient of the desired tangent vector ∇ X Y x w.r.t. s i - -- is given by leviCivita_rhs X Y s i. + -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` + -- is given by `leviCivita_rhs X Y s i`. ∑ i, ((leviCivita_rhs I X Y (frame i)) x) • (frame i x) variable (M) in @@ -456,8 +456,7 @@ variable (M) in the candidate definition for the Levi-Civita connection on `TM`. -/ noncomputable def lcCandidate [FiniteDimensional ℝ E] : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - -- Use the preferred trivialisation at x to write down a candidate for the existence. - -- to write down a candidate for the existence. + -- Use the preferred trivialisation at `x` to write down a candidate for the existence. fun X Y x ↦ lcCandidate_aux I (trivializationAt E (TangentSpace I : M → Type _) x) X Y x variable (X Y) in From eb5eb6193e7992fb2609f2cc3b0cec27b6365600 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 27 Jul 2025 11:12:16 +0200 Subject: [PATCH 300/601] Fix merge --- .../VectorBundle/MDifferentiable.lean | 93 +------------------ 1 file changed, 1 insertion(+), 92 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 3ca63675926ff3..2a9cac0c943c18 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -207,97 +207,6 @@ protected theorem MDifferentiable.coordChange end coordChange -section coordChange - -variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] -variable (e e' : Trivialization F (π F E)) [MemTrivializationAtlas e] [MemTrivializationAtlas e'] - [VectorBundle 𝕜 F E] [ContMDiffVectorBundle n F E IB] (hn : 1 ≤ n) -variable {IB} - -include hn in -theorem mdifferentiableOn_coordChangeL : - MDifferentiableOn IB 𝓘(𝕜, F →L[𝕜] F) (fun b : B => (e.coordChangeL 𝕜 e' b : F →L[𝕜] F)) - (e.baseSet ∩ e'.baseSet) := - (contMDiffOn_coordChangeL e e').mdifferentiableOn (n := n) (hn := by simp [hn]) - -include hn in -theorem mdifferentiableOn_symm_coordChangeL : - MDifferentiableOn IB 𝓘(𝕜, F →L[𝕜] F) (fun b : B => ((e.coordChangeL 𝕜 e' b).symm : F →L[𝕜] F)) - (e.baseSet ∩ e'.baseSet) := by - rw [inter_comm] - refine (mdifferentiableOn_coordChangeL e' e hn).congr fun b hb ↦ ?_ - rw [e.symm_coordChangeL e' hb] - -variable {e e'} - -theorem mdifferentiableAt_coordChangeL {x : B} - (h : x ∈ e.baseSet) (h' : x ∈ e'.baseSet) (hn : 1 ≤ n) : - MDifferentiableAt IB 𝓘(𝕜, F →L[𝕜] F) (fun b : B => (e.coordChangeL 𝕜 e' b : F →L[𝕜] F)) x := - (mdifferentiableOn_coordChangeL e e' hn).mdifferentiableAt <| - (e.open_baseSet.inter e'.open_baseSet).mem_nhds ⟨h, h'⟩ - -variable {s : Set M} {f : M → B} {g : M → F} {x : M} - -protected theorem MDifferentiableWithinAt.coordChangeL (hf : MDifferentiableWithinAt IM IB f s x) - (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) (hn : 1 ≤ n) : - MDifferentiableWithinAt IM 𝓘(𝕜, F →L[𝕜] F) - (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) s x := - (mdifferentiableAt_coordChangeL he he' hn).comp_mdifferentiableWithinAt _ hf - -include hn in -protected nonrec theorem MDifferentiableAt.coordChangeL - (hf : MDifferentiableAt IM IB f x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : - MDifferentiableAt IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) x := - MDifferentiableWithinAt.coordChangeL hf he he' hn - -- TODO: why no dot notation? - -include hn in -protected theorem MDifferentiableOn.coordChangeL - (hf : MDifferentiableOn IM IB f s) (he : MapsTo f s e.baseSet) (he' : MapsTo f s e'.baseSet) : - MDifferentiableOn IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) s := - fun x hx ↦ (hf x hx).coordChangeL (he hx) (he' hx) hn - -include hn in -protected theorem MDifferentiable.coordChangeL - (hf : MDifferentiable IM IB f) (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : - MDifferentiable IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) := fun x ↦ - (hf x).coordChangeL hn (he x) (he' x) - -include hn in -protected theorem MDifferentiableWithinAt.coordChange - (hf : MDifferentiableWithinAt IM IB f s x) (hg : MDifferentiableWithinAt IM 𝓘(𝕜, F) g s x) - (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : - MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) s x := by - refine ((hf.coordChangeL he he' hn).clm_apply hg).congr_of_eventuallyEq ?_ ?_ - · have : e.baseSet ∩ e'.baseSet ∈ 𝓝 (f x) := - (e.open_baseSet.inter e'.open_baseSet).mem_nhds ⟨he, he'⟩ - filter_upwards [hf.continuousWithinAt this] with y hy - exact (Trivialization.coordChangeL_apply' e e' hy (g y)).symm - · exact (Trivialization.coordChangeL_apply' e e' ⟨he, he'⟩ (g x)).symm - -include hn in -protected nonrec theorem MDifferentiableAt.coordChange - (hf : MDifferentiableAt IM IB f x) (hg : MDifferentiableAt IM 𝓘(𝕜, F) g x) - (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : - MDifferentiableAt IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) x := - MDifferentiableWithinAt.coordChange hn hf hg he he' -- TODO: why no dot notation? - -include hn in -protected theorem MDifferentiableOn.coordChange - (hf : MDifferentiableOn IM IB f s) (hg : MDifferentiableOn IM 𝓘(𝕜, F) g s) - (he : MapsTo f s e.baseSet) (he' : MapsTo f s e'.baseSet) : - MDifferentiableOn IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) s := fun x hx ↦ - (hf x hx).coordChange hn (hg x hx) (he hx) (he' hx) - -include hn in -protected theorem MDifferentiable.coordChange - (hf : MDifferentiable IM IB f) (hg : MDifferentiable IM 𝓘(𝕜, F) g) - (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : - MDifferentiable IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) := fun x ↦ - (hf x).coordChange hn (hg x) (he x) (he' x) - -end coordChange - variable [(x : B) → AddCommMonoid (E x)] [(x : B) → Module 𝕜 (E x)] [VectorBundle 𝕜 F E] [ContMDiffVectorBundle 1 F E IB] @@ -312,7 +221,7 @@ lemma MDifferentiableWithinAt.change_section_trivialization (he : f x₀ ∈ e.source) (he' : f x₀ ∈ e'.source) : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := by rw [Trivialization.mem_source] at he he' - refine (hf.coordChange le_rfl he'f he he').congr_of_eventuallyEq ?_ ?_ + refine (hf.coordChange he'f he he').congr_of_eventuallyEq ?_ ?_ · filter_upwards [hf.continuousWithinAt (e.open_baseSet.mem_nhds he)] with y hy rw [Function.comp_apply, e.coordChange_apply_snd e' hy] · rw [Function.comp_apply, e.coordChange_apply_snd _ he] From c3a18538b6d87a75b4932b2c2002916485f93ad5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 29 Jul 2025 15:41:59 +0200 Subject: [PATCH 301/601] Fix for mathlib bump (except for one broken lemma, which is harder). - Basis was renamed to Module.Basis - GramSchmidtOrtho was changed; make our API match --- .../VectorBundle/CovariantDerivative.lean | 2 +- .../VectorBundle/GramSchmidtOrtho.lean | 52 +++++++------------ .../Manifold/VectorBundle/LeviCivita.lean | 4 +- .../Manifold/VectorBundle/LocalFrame.lean | 6 +-- .../VectorBundle/OrthonormalFrame.lean | 4 +- .../Manifold/VectorBundle/Tensoriality.lean | 2 +- 6 files changed, 27 insertions(+), 43 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 9172e68838e833..29f872072c7007 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -21,7 +21,7 @@ TODO: add a more complete doc-string -/ -open Bundle Filter Topology Set +open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 43263f7d332643..5fa6375e7551fe 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -70,23 +70,20 @@ omit [TopologicalSpace B] variable (s) in /-- This lemma uses `∑ i in` instead of `∑ i :`. -/ theorem gramSchmidt_def (n : ι) (x) : - gramSchmidt s n x = - s n x - ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).orthogonalProjection (s n x) := by - simp only [gramSchmidt, InnerProductSpace.gramSchmidt_def] + gramSchmidt s n x = s n x - ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).starProjection (s n x) := by + rw [gramSchmidt, InnerProductSpace.gramSchmidt_def] + congr variable (s) in theorem gramSchmidt_def' (n : ι) (x) : - s n x = gramSchmidt s n x + - ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).orthogonalProjection (s n x) := by + s n x = gramSchmidt s n x + ∑ i ∈ Iio n, (ℝ ∙ gramSchmidt s i x).starProjection (s n x) := by rw [gramSchmidt_def, sub_add_cancel] variable (s) in theorem gramSchmidt_def'' (n : ι) (x) : s n x = gramSchmidt s n x + ∑ i ∈ Iio n, - (⟪gramSchmidt s i x, s n x⟫ / (‖gramSchmidt s i x‖) ^ 2) • gramSchmidt s i x := by - convert gramSchmidt_def' s n x - rw [orthogonalProjection_singleton, RCLike.ofReal_pow] - rfl + (⟪gramSchmidt s i x, s n x⟫ / (‖gramSchmidt s i x‖) ^ 2) • gramSchmidt s i x := + InnerProductSpace.gramSchmidt_def'' ℝ (s · x) n variable (s) in @[simp] @@ -154,22 +151,8 @@ theorem span_gramSchmidt (x : B) : /-- If the section values `s i x` are orthogonal, `gramSchmidt` yields the same values at `x`. -/ theorem gramSchmidt_of_orthogonal {x} (hs : Pairwise fun i j ↦ ⟪s i x, s j x⟫ = 0) : ∀ i₀, gramSchmidt s i₀ x = s i₀ x:= by - intro i - rw [gramSchmidt_def] - trans s i x - 0 - · congr - apply Finset.sum_eq_zero - intro j hj - rw [Submodule.coe_eq_zero] - suffices span ℝ ((s · x) '' Set.Iic j) ⟂ ℝ ∙ s i x by - apply orthogonalProjection_mem_subspace_orthogonalComplement_eq_zero - rw [mem_orthogonal_singleton_iff_inner_left, ← mem_orthogonal_singleton_iff_inner_right] - exact this <| gramSchmidt_mem_span _ _ le_rfl - rw [isOrtho_span] - rintro u ⟨k, hk, rfl⟩ v (rfl : v = s i x) - apply hs - exact (lt_of_le_of_lt hk (Finset.mem_Iio.mp hj)).ne - · simp + simp_rw [gramSchmidt] + exact fun i ↦ congrFun (InnerProductSpace.gramSchmidt_of_orthogonal ℝ hs) i theorem gramSchmidt_ne_zero_coe (n : ι) (x) (h₀ : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic n → ι))) : gramSchmidt s n x ≠ 0 := @@ -195,14 +178,14 @@ theorem gramSchmidt_linearIndependent {x} (h₀ : LinearIndependent ℝ (s · x) /-- When the sections `s` form a basis at `x`, so do the sections `gramSchmidt s`. -/ noncomputable def gramSchmidtBasis {x} (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : - Basis ι ℝ (E x) := - Basis.mk (gramSchmidt_linearIndependent hs) + Module.Basis ι ℝ (E x) := + Module.Basis.mk (gramSchmidt_linearIndependent hs) ((span_gramSchmidt s x).trans (eq_top_iff'.mpr fun _ ↦ hs' trivial)).ge theorem coe_gramSchmidtBasis {x} (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : (gramSchmidtBasis hs hs') = (gramSchmidt s · x) := - Basis.coe_mk _ _ + Module.Basis.coe_mk _ _ noncomputable def gramSchmidtNormed [WellFoundedLT ι] (s : ι → (x : B) → E x) (n : ι) : (x : B) → E x := fun x ↦ @@ -275,8 +258,8 @@ lemma gramSchmidtNormed_apply_of_orthonormal {x} (hs : Orthonormal ℝ (s · x)) Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ noncomputable def gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : - Basis ι ℝ (E x) := - Basis.mk (v := fun i ↦ gramSchmidtNormed s i x) (gramSchmidtNormed_linearIndependent hs) + Module.Basis ι ℝ (E x) := + Module.Basis.mk (v := fun i ↦ gramSchmidtNormed s i x) (gramSchmidtNormed_linearIndependent hs) (by rw [span_gramSchmidtNormed_range s x, span_gramSchmidt s x]; exact hs') /-- Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ @@ -284,7 +267,7 @@ noncomputable def gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x theorem coe_gramSchmidtNormedBasis {x} (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : (gramSchmidtNormedBasis hs hs' : ι → E x) = (gramSchmidtNormed s · x) := - Basis.coe_mk _ _ + Module.Basis.coe_mk _ _ noncomputable def gramSchmidtOrthonormalBasis {x} [Fintype ι] (hs : LinearIndependent ℝ (s · x)) (hs' : ⊤ ≤ Submodule.span ℝ (Set.range (s · x))) : @@ -338,9 +321,9 @@ lemma contMDiffAt_aux (hs : CMDiffAt n (T% s) x) (ht : CMDiffAt n (T% t) x) (hs' def ContMDiffWithinAt.orthogonalProjection (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! - letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).orthogonalProjection (t x); + letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).starProjection (t x); CMDiffAt[u] n (T% S) x := by - simp_rw [Submodule.orthogonalProjection_singleton] + simp_rw [Submodule.starProjection_singleton] exact (contMDiffWithinAt_aux hs ht hs').smul_section hs lemma contMDiffWithinAt_inner (hs : CMDiffAt[u] n (T% s) x) (hs' : s x ≠ 0) : @@ -362,6 +345,7 @@ variable {s : ι → (x : B) → E x} {u : Set B} {x : B} {i : ι} lemma gramSchmidt_contMDiffWithinAt (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) {i : ι} (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by + sorry /- TODO: this simp lemma loops now; not sure why! simp_rw [VectorBundle.gramSchmidt_def] apply (hs i).sub_section apply ContMDiffWithinAt.sum_section @@ -375,7 +359,7 @@ lemma gramSchmidt_contMDiffWithinAt (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) apply ContMDiffWithinAt.orthogonalProjection (gramSchmidt_contMDiffWithinAt hs this) (hs i) apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i -decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' +decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' -/ lemma gramSchmidt_contMDiffAt (hs : ∀ i, CMDiffAt n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index e14129f1d6850b..b90a9fe120f797 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -22,7 +22,7 @@ is an isometry) and prove the Levi-Civita connection is a metric connection -/ -open Bundle Filter Function Topology +open Bundle Filter Function Module Topology open scoped Bundle Manifold ContDiff @@ -32,7 +32,7 @@ variable {n : WithTop ℕ∞} {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I ∞ M] [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] - -- comes in a future PR by sgouezel; don't need this part yet + -- don't need this assumption (yet?) -- [IsRiemannianManifold I M] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 1867dda9c83dbc..1f9fa8d67e604d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -61,7 +61,7 @@ TODO add a more complete doc-string! vector bundle, local frame, smoothness -/ -open Bundle Filter Function Topology +open Bundle Filter Function Topology Module open scoped Bundle Manifold ContDiff @@ -301,7 +301,7 @@ end IsLocalFrameOn end IsLocalFrame -namespace Basis +namespace Module.Basis variable {ι : Type*} @@ -466,7 +466,7 @@ lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : --simp only [localFrame_repr] simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] -end Basis +end Module.Basis /-! # Determining smoothness of a section via its local frame coefficients We show that for finite rank bundles over a complete field, a section is smooth iff its coefficients diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index de7df4720420ac..22ff1b0f9b4e18 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -182,7 +182,7 @@ end IsOrthonormalFrameOn end smoothness -namespace Basis +namespace Module.Basis variable {b : Basis ι ℝ F} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} @@ -227,4 +227,4 @@ lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : convert InnerProductSpace.gramSchmidt_zero ℝ i apply localFrame_apply_of_notMem e b hx -end Basis +end Module.Basis diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 311d88047e3517..325cb41c8e6916 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -13,7 +13,7 @@ import Mathlib.Geometry.Manifold.Elaborators # The tensoriality criterion -/ -open Bundle Filter Function Topology +open Bundle Filter Function Topology Module open scoped Bundle Manifold ContDiff From 27dec6faf3bc957d2b18405d280980286e565e25 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 29 Jul 2025 16:07:59 +0200 Subject: [PATCH 302/601] chore: replace very non-canonical definition by a local instance --- .../Manifold/VectorBundle/LeviCivita.lean | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index b90a9fe120f797..a97f0025d4a905 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -369,16 +369,9 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : (by simp [this]) sorry -- obvious: if A + A = stuff, A = 1/2 stuff --- TODO: move to Data.Fintype.EquivFin -/-- Choose an arbitrary linear order on a `Fintype`: this is not an instance because in most -situations, choosing a linear order extending a given preorder, or a particular linear order -is preferred over choosing *any* linear order. -/ -noncomputable def Fintype.instLinearOrder {α : Type*} [Fintype α] : LinearOrder α := - LinearOrder.lift' _ (Fintype.equivFin α).injective - section -attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder Fintype.instLinearOrder +attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] @@ -400,6 +393,9 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] have : Subsingleton E := by sorry apply hE this + have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by + choose r wo using exists_wellOrder _ + exact r haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g @@ -443,7 +439,9 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] -- Case distinction: if E is trivial, there is only one choice anyway; -- otherwise, b must be non-trivial. have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - have : Fintype ↑(Basis.ofVectorSpaceIndex ℝ E) := by infer_instance + have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by + choose r wo using exists_wellOrder _ + exact r haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` @@ -481,7 +479,10 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] congr; ext i rw [leviCivita_rhs_addX] <;> try assumption · abel - · have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + · have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have : MDiffAt (T% f) x := -- missing API lemma! (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) @@ -514,7 +515,10 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] congr; ext i rw [leviCivita_rhs_addY] <;> try assumption · abel - · have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + · have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have : MDiffAt (T% f) x := -- missing API lemma! (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) From 6b19d352373b0d055d4a59ece2f83164ccf691d4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 18:13:16 +0200 Subject: [PATCH 303/601] wip: local versions of computation lemmas --- .../Manifold/VectorBundle/LeviCivita.lean | 84 ++++++++++++++----- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index a97f0025d4a905..ba55101ff1ff5c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -55,6 +55,8 @@ section product omit [IsManifold I ∞ M] +lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl + variable (X Y) in lemma product_swap : ⟪Y, X⟫ = ⟪X, Y⟫ := by ext x @@ -74,10 +76,20 @@ lemma product_add_left : ⟪X + X', Y⟫ = ⟪X, Y⟫ + ⟪X', Y⟫ := by ext x simp [product, InnerProductSpace.add_left] +variable (X X' Y) in +@[simp] +lemma product_add_left_apply (x) : ⟪X + X', Y⟫ x = ⟪X, Y⟫ x + ⟪X', Y⟫ x := by + simp [product, InnerProductSpace.add_left] + variable (X Y Y') in lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] +variable (X X' Y) in +@[simp] +lemma product_add_right_apply (x) : ⟪X, Y + Y'⟫ x = ⟪X, Y⟫ x + ⟪X, Y'⟫ x := by + rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left_apply] + variable (X Y) in @[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] @@ -119,6 +131,10 @@ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := MDifferentiable.inner_bundle hY hZ +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +lemma fooAt {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : MDiffAt ⟪Y, Z⟫ x := + MDifferentiableAt.inner_bundle hY hZ + namespace CovariantDerivative -- Let `cov` be a covariant derivative on `TM`. @@ -149,7 +165,7 @@ lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by congr exact product_swap I Z Y -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x} omit [IsManifold I ∞ M] in variable (X X' Y Z) in @@ -157,20 +173,32 @@ lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z ext x simp [rhs_aux] +variable (X) in +@[simp] +lemma rhs_aux_addY_apply (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X (Y + Y') Z x = rhs_aux I X Y Z x + rhs_aux I X Y' Z x := by + simp only [rhs_aux] + rw [product_add_left, mfderiv_add (fooAt hY hZ) (fooAt hY' hZ)] + simp; congr + variable (X) in lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by ext x - simp only [rhs_aux] - rw [product_add_left, mfderiv_add ((foo hY hZ) x) ((foo hY' hZ) x)] - simp; congr + exact rhs_aux_addY_apply I X (hY x) (hY' x) (hZ x) variable (X) in -lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by +@[simp] +lemma rhs_aux_addZ_apply (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + rhs_aux I X Y (Z + Z') x = rhs_aux I X Y Z x + rhs_aux I X Y Z' x := by unfold rhs_aux + rw [product_add_right, mfderiv_add (fooAt hY hZ) (fooAt hY hZ')]; simp; congr + +variable (X) in +lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by ext x - rw [product_add_right, mfderiv_add ((foo hY hZ) x) ((foo hY hZ') x)]; simp; congr + exact rhs_aux_addZ_apply I X (hY x) (hZ x) (hZ' x) omit [IsManifold I ∞ M] in variable (X Y Z) in @@ -225,22 +253,31 @@ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -- TODO: relax assumptions; I only need differentiability at x! @[simp] lemma leviCivita_rhs'_addX_apply [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : leviCivita_rhs' I (X + X') Y Z x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X' Y Z x := by simp only [leviCivita_rhs'] - have h : VectorField.mlieBracket I (X + X') Y = - VectorField.mlieBracket I X Y + VectorField.mlieBracket I X' Y := by - ext x - simp [VectorField.mlieBracket_add_left (W := Y) (hX x) (hX' x)] - have h' : VectorField.mlieBracket I (X + X') Z = - VectorField.mlieBracket I X Z + VectorField.mlieBracket I X' Z := by - ext x - simp [VectorField.mlieBracket_add_left (W := Z) (hX x) (hX' x)] - simp only [rhs_aux_addX, h, h', Pi.add_apply, Pi.sub_apply] - rw [rhs_aux_addY, rhs_aux_addZ] <;> try assumption - rw [product_add_left, product_add_right, product_add_right] - simp only [Pi.add_apply] + have h : VectorField.mlieBracket I (X + X') Y x = + VectorField.mlieBracket I X Y x + VectorField.mlieBracket I X' Y x := by + simp [VectorField.mlieBracket_add_left (W := Y) (hX) (hX')] + have h' : VectorField.mlieBracket I (X + X') Z x = + VectorField.mlieBracket I X Z x + VectorField.mlieBracket I X' Z x := by + simp [VectorField.mlieBracket_add_left (W := Z) (hX) (hX')] + have := hY x; have := hZ x + simp only [rhs_aux_addX, Pi.add_apply, Pi.sub_apply] + -- XXX: this is not elegant; is there a better way? + simp only [product_apply, h, h'] + simp only [← product_apply] + + simp only [product_add_left_apply] + rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + have h3 : inner ℝ (Y x) (VectorField.mlieBracket I X Z x + VectorField.mlieBracket I X' Z x) + = inner ℝ (Y x) (VectorField.mlieBracket I X Z x) + inner ℝ (Y x) (VectorField.mlieBracket I X' Z x) := by + sorry + have h4 : inner ℝ (Z x) (VectorField.mlieBracket I X Y x + VectorField.mlieBracket I X' Y x) + = inner ℝ (Z x) (VectorField.mlieBracket I X Y x) + inner ℝ (Z x) (VectorField.mlieBracket I X' Y x) := sorry + rw [h3, h4] + simp only [← product_apply] --, Pi.add_apply] abel lemma leviCivita_rhs'_addX [CompleteSpace E] @@ -248,7 +285,12 @@ lemma leviCivita_rhs'_addX [CompleteSpace E] leviCivita_rhs' I (X + X') Y Z = leviCivita_rhs' I X Y Z + leviCivita_rhs' I X' Y Z := by ext x - simp [leviCivita_rhs'_addX_apply _ hX hX' hY hZ] + simp [leviCivita_rhs'_addX_apply _ (hX x) (hX' x) hY hZ] + +lemma leviCivita_rhs_addX_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by + sorry -- divide the previous equation by 2 lemma leviCivita_rhs_addX [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : From 2d37e7aeb83c5281228c3d8d24cffe48b54c761e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 18:46:59 +0200 Subject: [PATCH 304/601] chore: remove some differentiability hypotheses --- .../Manifold/VectorBundle/LeviCivita.lean | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index ba55101ff1ff5c..6dfcb765406a48 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -250,34 +250,24 @@ section leviCivita_rhs variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] --- TODO: relax assumptions; I only need differentiability at x! @[simp] lemma leviCivita_rhs'_addX_apply [CompleteSpace E] - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivita_rhs' I (X + X') Y Z x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X' Y Z x := by simp only [leviCivita_rhs'] have h : VectorField.mlieBracket I (X + X') Y x = VectorField.mlieBracket I X Y x + VectorField.mlieBracket I X' Y x := by - simp [VectorField.mlieBracket_add_left (W := Y) (hX) (hX')] + simp [VectorField.mlieBracket_add_left (W := Y) hX hX'] have h' : VectorField.mlieBracket I (X + X') Z x = VectorField.mlieBracket I X Z x + VectorField.mlieBracket I X' Z x := by - simp [VectorField.mlieBracket_add_left (W := Z) (hX) (hX')] - have := hY x; have := hZ x + simp [VectorField.mlieBracket_add_left (W := Z) hX hX'] simp only [rhs_aux_addX, Pi.add_apply, Pi.sub_apply] - -- XXX: this is not elegant; is there a better way? - simp only [product_apply, h, h'] - simp only [← product_apply] - - simp only [product_add_left_apply] + -- We have to rewrite back and forth: the Lie bracket is only additive at x, + -- as we are only asking for differentiability at x. + simp_rw [product_apply, h, h', inner_add_right, ← product_apply, product_add_left_apply] rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption - have h3 : inner ℝ (Y x) (VectorField.mlieBracket I X Z x + VectorField.mlieBracket I X' Z x) - = inner ℝ (Y x) (VectorField.mlieBracket I X Z x) + inner ℝ (Y x) (VectorField.mlieBracket I X' Z x) := by - sorry - have h4 : inner ℝ (Z x) (VectorField.mlieBracket I X Y x + VectorField.mlieBracket I X' Y x) - = inner ℝ (Z x) (VectorField.mlieBracket I X Y x) + inner ℝ (Z x) (VectorField.mlieBracket I X' Y x) := sorry - rw [h3, h4] - simp only [← product_apply] --, Pi.add_apply] abel lemma leviCivita_rhs'_addX [CompleteSpace E] @@ -285,30 +275,45 @@ lemma leviCivita_rhs'_addX [CompleteSpace E] leviCivita_rhs' I (X + X') Y Z = leviCivita_rhs' I X Y Z + leviCivita_rhs' I X' Y Z := by ext x - simp [leviCivita_rhs'_addX_apply _ (hX x) (hX' x) hY hZ] + simp [leviCivita_rhs'_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] lemma leviCivita_rhs_addX_apply [CompleteSpace E] - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by sorry -- divide the previous equation by 2 lemma leviCivita_rhs_addX [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by - sorry -- divide the previous equation by 2 + ext x + simp [leviCivita_rhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] -variable (X Y Z) in +variable (Y Z) in lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by -- TODO: do I need to assume X is differentiable? sorry -variable (X Z) in +lemma leviCivita_rhs'_addY_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + leviCivita_rhs' I X (Y + Y') Z x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X Y' Z x := by + sorry -- TODO: prove this! + +lemma leviCivita_rhs_addY_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + leviCivita_rhs I X (Y + Y') Z x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X Y' Z x := by + sorry -- divide the previous equation by 2 + lemma leviCivita_rhs_addY [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : leviCivita_rhs I X (Y + Y') Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y' Z := by - sorry -- divide the previous equation by 2 + ext x + simp [leviCivita_rhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] +-- TODO: write a point-wise version of this! lemma leviCivita_rhs'_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs' I X Y (Z + Z') = @@ -538,7 +543,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have hg : MDiff g := sorry -- might need this (hopefully not!) rw [Finset.smul_sum] congr; ext i - rw [leviCivita_rhs_smulX _ _ _ _ hg hX] + rw [leviCivita_rhs_smulX _ _ _ hg hX] simp [← smul_assoc] smul_const_σ X σ a x hx := by unfold lcCandidate_aux @@ -547,16 +552,12 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] -- want leviCivita_rhs_smulY (with a constant) sorry addσ X σ σ' x hσ hσ' hx := by - have hX : MDiff (T% X) := sorry -- missing assumption! - -- TODO: these should not be necessary with a local version of addY! - have hσ2 : MDiff (T% σ) := sorry - have hσ'2 : MDiff (T% σ') := sorry + have hX : MDiffAt (T% X) x := sorry -- missing assumption! unfold lcCandidate_aux dsimp simp [← Finset.sum_add_distrib, ← add_smul] congr; ext i - rw [leviCivita_rhs_addY] <;> try assumption - · abel + rw [leviCivita_rhs_addY_apply] <;> try assumption · have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by choose r wo using exists_wellOrder _ exact r @@ -565,7 +566,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have : MDiffAt (T% f) x := -- missing API lemma! (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) |>.mdifferentiableAt le_rfl - -- TODO: need a local version of leviCivita_rhs_addX! + -- `this` does it, except for some mismatch because we chose different linear orders?? sorry leibniz := by sorry From bfc02439438b8d9529fa504f7cfa3fa3cdaa96a9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 19:03:28 +0200 Subject: [PATCH 305/601] Tinkering with the linear order: perhaps revert the previous change? --- .../Geometry/Manifold/VectorBundle/LeviCivita.lean | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 6dfcb765406a48..dfa18e5fb3145e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -526,9 +526,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] congr; ext i rw [leviCivita_rhs_addX] <;> try assumption · abel - · have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by - choose r wo using exists_wellOrder _ - exact r + · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have : MDiffAt (T% f) x := -- missing API lemma! @@ -558,16 +556,14 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivita_rhs_addY_apply] <;> try assumption - · have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by - choose r wo using exists_wellOrder _ - exact r - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + · let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := by sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have : MDiffAt (T% f) x := -- missing API lemma! (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) |>.mdifferentiableAt le_rfl - -- `this` does it, except for some mismatch because we chose different linear orders?? - sorry + -- mismatch between different orders; the sorry above + convert this <;> sorry leibniz := by sorry From 2ba81a14f423d04f0da516988f2f8910ad91a346 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 23:09:46 +0200 Subject: [PATCH 306/601] Prove all 'just divide by two' lemmas --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index dfa18e5fb3145e..6ac8db65ccc2b6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -280,8 +280,8 @@ lemma leviCivita_rhs'_addX [CompleteSpace E] lemma leviCivita_rhs_addX_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by - sorry -- divide the previous equation by 2 + leviCivita_rhs I (X + X') Y Z x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X' Y Z x := by + simp [leviCivita_rhs, leviCivita_rhs'_addX_apply I hX hX' hY hZ, left_distrib] lemma leviCivita_rhs_addX [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : @@ -305,7 +305,7 @@ lemma leviCivita_rhs_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : leviCivita_rhs I X (Y + Y') Z x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X Y' Z x := by - sorry -- divide the previous equation by 2 + simp [leviCivita_rhs, leviCivita_rhs'_addY_apply I hX hY hY' hZ, left_distrib] lemma leviCivita_rhs_addY [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : @@ -337,7 +337,7 @@ lemma leviCivita_rhs'_addZ [CompleteSpace E] lemma leviCivita_rhs_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by - sorry -- divide previous equation by two + simp [leviCivita_rhs, leviCivita_rhs'_addZ I hX hY hZ hZ'] lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by From 28d43042936aec7d9d14772c51c237625e5ba29d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 23:21:56 +0200 Subject: [PATCH 307/601] Prove addY; polish addX --- .../Manifold/VectorBundle/LeviCivita.lean | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 6ac8db65ccc2b6..0c328ad3b19893 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -256,17 +256,12 @@ lemma leviCivita_rhs'_addX_apply [CompleteSpace E] (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivita_rhs' I (X + X') Y Z x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X' Y Z x := by - simp only [leviCivita_rhs'] - have h : VectorField.mlieBracket I (X + X') Y x = - VectorField.mlieBracket I X Y x + VectorField.mlieBracket I X' Y x := by - simp [VectorField.mlieBracket_add_left (W := Y) hX hX'] - have h' : VectorField.mlieBracket I (X + X') Z x = - VectorField.mlieBracket I X Z x + VectorField.mlieBracket I X' Z x := by - simp [VectorField.mlieBracket_add_left (W := Z) hX hX'] - simp only [rhs_aux_addX, Pi.add_apply, Pi.sub_apply] + simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. - simp_rw [product_apply, h, h', inner_add_right, ← product_apply, product_add_left_apply] + simp_rw [product_apply, VectorField.mlieBracket_add_left (W := Y) hX hX', + VectorField.mlieBracket_add_left (W := Z) hX hX', inner_add_right, ← product_apply, + product_add_left_apply] rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel @@ -299,7 +294,14 @@ lemma leviCivita_rhs'_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : leviCivita_rhs' I X (Y + Y') Z x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X Y' Z x := by - sorry -- TODO: prove this! + simp only [leviCivita_rhs', Pi.add_apply, Pi.sub_apply, product_add_left_apply] + rw [rhs_aux_addX, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + -- We have to rewrite back and forth: the Lie bracket is only additive at x, + -- as we are only asking for differentiability at x. + simp only [product_apply] + simp only [Pi.add_apply, VectorField.mlieBracket_add_right (V := X) hY hY', + VectorField.mlieBracket_add_right (V := Z) hY hY', inner_add_right, ← product_apply] + abel lemma leviCivita_rhs_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) From c41cc6ec423645ca7f4728e6d6380c53591d7a19 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 23:32:22 +0200 Subject: [PATCH 308/601] Add point-wise version of addZ --- .../Manifold/VectorBundle/LeviCivita.lean | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 0c328ad3b19893..83cf2472604819 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -315,31 +315,36 @@ lemma leviCivita_rhs_addY [CompleteSpace E] ext x simp [leviCivita_rhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] --- TODO: write a point-wise version of this! +lemma leviCivita_rhs'_addZ_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + leviCivita_rhs' I X Y (Z + Z') x = + leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X Y Z' x := by + simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] + rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + simp only [product_apply] + simp only [VectorField.mlieBracket_add_right (V := X) hZ hZ', + VectorField.mlieBracket_add_left (W := Y) hZ hZ', inner_add_right, ← product_apply] + abel + lemma leviCivita_rhs'_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs' I X Y (Z + Z') = leviCivita_rhs' I X Y Z + leviCivita_rhs' I X Y Z' := by - simp only [leviCivita_rhs'] ext x - have h : VectorField.mlieBracket I X (Z + Z') = - VectorField.mlieBracket I X Z + VectorField.mlieBracket I X Z' := by - ext x - simp [VectorField.mlieBracket_add_right (V := X) (hZ x) (hZ' x)] - have h' : VectorField.mlieBracket I (Z + Z') Y = - VectorField.mlieBracket I Z Y + VectorField.mlieBracket I Z' Y := by - ext x - simp [VectorField.mlieBracket_add_left (W := Y) (hZ x) (hZ' x)] - simp only [rhs_aux_addX, h, h', Pi.add_apply, Pi.sub_apply] - rw [rhs_aux_addY, rhs_aux_addZ] <;> try assumption - rw [product_add_left, product_add_right, product_add_right] - simp only [Pi.add_apply] - abel + exact leviCivita_rhs'_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + +lemma leviCivita_rhs_addZ_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + leviCivita_rhs I X Y (Z + Z') x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X Y Z' x := by + simp [leviCivita_rhs, leviCivita_rhs'_addZ_apply I hX hY hZ hZ', left_distrib] lemma leviCivita_rhs_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by - simp [leviCivita_rhs, leviCivita_rhs'_addZ I hX hY hZ hZ'] + ext x + exact leviCivita_rhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by From 97fa818163eae2749ffdce6dd45241725a55e215 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 1 Aug 2025 23:37:26 +0200 Subject: [PATCH 309/601] One sorry's assumptions are clear now --- .../Geometry/Manifold/VectorBundle/LeviCivita.lean | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 83cf2472604819..ba02a8d8e7c372 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -524,23 +524,21 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e) e.baseSet where addX X X' σ x := by -- these three sorries seem to be necessary! - have hX : MDiff (T% X) := sorry - have hX' : MDiff (T% X') := sorry - have hσ : MDiff (T% σ) := sorry + have hX : MDiffAt (T% X) x := sorry + have hX' : MDiffAt (T% X') x := sorry + have hσ : MDiffAt (T% σ) x := sorry intro hx unfold lcCandidate_aux simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i - rw [leviCivita_rhs_addX] <;> try assumption - · abel + rw [leviCivita_rhs_addX_apply] <;> try assumption · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have : MDiffAt (T% f) x := -- missing API lemma! (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) |>.mdifferentiableAt le_rfl - -- TODO: need a local version of leviCivita_rhs_addX! - sorry + sorry -- convert this works, except for different local orders... smulX X σ g x hx := by unfold lcCandidate_aux dsimp From 5281a8a86b96a49deda3a6035018b62bbaf0e4af Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 2 Aug 2025 00:43:27 +0200 Subject: [PATCH 310/601] wip: smulX --- get an additional term! --- .../Manifold/VectorBundle/LeviCivita.lean | 70 ++++++++++++++++++- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index ba02a8d8e7c372..1d81fa645dd37f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -284,11 +284,75 @@ lemma leviCivita_rhs_addX [CompleteSpace E] ext x simp [leviCivita_rhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] -variable (Y Z) in +variable {I} in +lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : + letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + letI A := dfY * ⟪Z, X⟫ x + leviCivita_rhs' I (f • X) Y Z x = f x • leviCivita_rhs' I X Y Z x + A + A := by + -- TODO: do I need to assume X is differentiable? yes, I think so! + unfold leviCivita_rhs' + rw [rhs_aux_smulX] + rw [rhs_aux_smulY, rhs_aux_smulZ] <;> try assumption -- TODO: want more surgical reasoning + rotate_left; iterate 6 sorry + have h := VectorField.mlieBracket_smul_left (W := Z) hf hX + simp + simp only [product_apply] + simp only [VectorField.mlieBracket_smul_left (W := Z) hf hX, + VectorField.mlieBracket_smul_left (W := Y) hf hX] + simp only [inner_add_right, ← product_apply] + simp only [neg_smul, inner_neg_right] + have h1 : + letI dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x); + inner ℝ (Y x) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) • X x) = dfZ * ⟪X, Y⟫ x := by + simp only [product] + rw [← real_inner_smul_left, real_inner_smul_right, real_inner_smul_left, real_inner_comm] + have h2 : + letI dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x); + inner ℝ (Z x) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) • X x) = dfZ * ⟪Z, X⟫ x := by + simp only [product] + rw [← real_inner_smul_left, real_inner_smul_right, real_inner_smul_left] + simp only [h1, h2] + clear h1 h2 + set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + set dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) + have h3 : inner ℝ (Y x) (f x • VectorField.mlieBracket I X Z x) = + f x * ⟪Y, VectorField.mlieBracket I X Z⟫ x := sorry + have h4 : ⟪f • X, VectorField.mlieBracket I Z Y⟫ x = f x * ⟪X, VectorField.mlieBracket I Z Y⟫ x := sorry + have h5 : inner ℝ (Z x) (f x • VectorField.mlieBracket I X Y x) = f x * ⟪Z, VectorField.mlieBracket I X Y⟫ x := sorry + rw [h3, h4, h5] + set A := ⟪Y, VectorField.mlieBracket I X Z⟫ + set B := ⟪Z, VectorField.mlieBracket I X Y⟫ + set C := ⟪X, VectorField.mlieBracket I Z Y⟫ + set R := dfZ * ⟪X, Y⟫ x + set R' := dfY * ⟪Z, X⟫ x + + calc f x * rhs_aux I X Y Z x + (f x * rhs_aux I Y Z X x + R') - (f x * rhs_aux I Z X Y x + R) - (-R + f x * A x) - (-R' + f x * B x) + f x * C x + _ = f x * rhs_aux I X Y Z x + f x * rhs_aux I Y Z X x + R' - f x * rhs_aux I Z X Y x - R + R - f x * A x + R' - f x * B x + f x * C x := by + abel + _ = f x * rhs_aux I X Y Z x + f x * rhs_aux I Y Z X x - f x * rhs_aux I Z X Y x - f x * A x - f x * B x + f x * C x + R' + R' := by + abel + _ = (f x * rhs_aux I X Y Z x + f x * rhs_aux I Y Z X x - f x * rhs_aux I Z X Y x - f x * A x - f x * B x + f x * C x) + R' + R' := by + abel + _ = f x * (rhs_aux I X Y Z x + rhs_aux I Y Z X x - rhs_aux I Z X Y x - A x - B x + C x) + R' + R' := by + congr 1 + congr 2 + sorry -- why abel not successful? + _ = _ := by + abel + +#exit + +variable {I} in +lemma leviCivita_rhs_smulX_apply {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : + leviCivita_rhs I (f • X) Y Z x = f x • leviCivita_rhs I X Y Z x := by + simp [leviCivita_rhs, leviCivita_rhs'_smulX_apply (Y := Y) (Z := Z) hf hX, + ← mul_assoc, mul_comm _ (f x)] + +variable {I} in lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by - -- TODO: do I need to assume X is differentiable? - sorry + ext x + exact leviCivita_rhs_smulX_apply (hf x) (hX x) lemma leviCivita_rhs'_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) From 3b19897f35134271a1aefc2fd85e04b0a839d330 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 2 Aug 2025 01:52:52 +0200 Subject: [PATCH 311/601] Finish smulX; I'm still worried about the extra term. Find the foundatations of that computation first, then resume here! --- .../Manifold/VectorBundle/LeviCivita.lean | 100 ++++++++++-------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 1d81fa645dd37f..20c9fbdcac80e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -206,13 +206,27 @@ lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I ext x simp [rhs_aux] +variable (X) in +lemma rhs_aux_smulY_apply {f : M → ℝ} + (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI A (x) : ℝ := (mfderiv% f x) (X x) + rhs_aux I X (f • Y) Z x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by + rw [rhs_aux, product_smul_left, mfderiv_smul (fooAt hY hZ) hf] + variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : letI A (x) : ℝ := (mfderiv% f x) (X x) rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by ext x - rw [rhs_aux, product_smul_left, mfderiv_smul (foo hY hZ x) (hf x)] - congr + simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] + +variable (X) in +lemma rhs_aux_smulZ_apply {f : M → ℝ} + (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI A (x) : ℝ := (mfderiv% f x) (X x) + rhs_aux I X Y (f • Z) x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by + rw [rhs_aux_swap, rhs_aux_smulY_apply, rhs_aux_swap, product_swap] + exacts [hf, hZ, hY] variable (X) in lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : @@ -285,21 +299,17 @@ lemma leviCivita_rhs_addX [CompleteSpace E] simp [leviCivita_rhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] variable {I} in -lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : +lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) letI A := dfY * ⟪Z, X⟫ x leviCivita_rhs' I (f • X) Y Z x = f x • leviCivita_rhs' I X Y Z x + A + A := by - -- TODO: do I need to assume X is differentiable? yes, I think so! unfold leviCivita_rhs' - rw [rhs_aux_smulX] - rw [rhs_aux_smulY, rhs_aux_smulZ] <;> try assumption -- TODO: want more surgical reasoning - rotate_left; iterate 6 sorry - have h := VectorField.mlieBracket_smul_left (W := Z) hf hX - simp - simp only [product_apply] - simp only [VectorField.mlieBracket_smul_left (W := Z) hf hX, - VectorField.mlieBracket_smul_left (W := Y) hf hX] - simp only [inner_add_right, ← product_apply] + simp only [Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption + simp only [product_apply, VectorField.mlieBracket_smul_left (W := Z) hf hX, + VectorField.mlieBracket_smul_left (W := Y) hf hX, inner_add_right] + simp only [← product_apply] simp only [neg_smul, inner_neg_right] have h1 : letI dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x); @@ -315,44 +325,49 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffA clear h1 h2 set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) set dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) - have h3 : inner ℝ (Y x) (f x • VectorField.mlieBracket I X Z x) = - f x * ⟪Y, VectorField.mlieBracket I X Z⟫ x := sorry - have h4 : ⟪f • X, VectorField.mlieBracket I Z Y⟫ x = f x * ⟪X, VectorField.mlieBracket I Z Y⟫ x := sorry - have h5 : inner ℝ (Z x) (f x • VectorField.mlieBracket I X Y x) = f x * ⟪Z, VectorField.mlieBracket I X Y⟫ x := sorry - rw [h3, h4, h5] + have h4 : ⟪f • X, VectorField.mlieBracket I Z Y⟫ x = + f x * ⟪X, VectorField.mlieBracket I Z Y⟫ x := by + rw [product_apply, Pi.smul_apply', real_inner_smul_left] + have h5 : inner ℝ (Z x) (f x • VectorField.mlieBracket I X Y x) = + f x * ⟪Z, VectorField.mlieBracket I X Y⟫ x := by + rw [product_apply, real_inner_smul_right] + rw [real_inner_smul_right (Y x), h4, h5] set A := ⟪Y, VectorField.mlieBracket I X Z⟫ set B := ⟪Z, VectorField.mlieBracket I X Y⟫ set C := ⟪X, VectorField.mlieBracket I Z Y⟫ set R := dfZ * ⟪X, Y⟫ x set R' := dfY * ⟪Z, X⟫ x - - calc f x * rhs_aux I X Y Z x + (f x * rhs_aux I Y Z X x + R') - (f x * rhs_aux I Z X Y x + R) - (-R + f x * A x) - (-R' + f x * B x) + f x * C x - _ = f x * rhs_aux I X Y Z x + f x * rhs_aux I Y Z X x + R' - f x * rhs_aux I Z X Y x - R + R - f x * A x + R' - f x * B x + f x * C x := by - abel - _ = f x * rhs_aux I X Y Z x + f x * rhs_aux I Y Z X x - f x * rhs_aux I Z X Y x - f x * A x - f x * B x + f x * C x + R' + R' := by - abel - _ = (f x * rhs_aux I X Y Z x + f x * rhs_aux I Y Z X x - f x * rhs_aux I Z X Y x - f x * A x - f x * B x + f x * C x) + R' + R' := by + set E := rhs_aux I X Y Z x + set F := rhs_aux I Y Z X x + set G := rhs_aux I Z X Y x + calc f x * E + (f x * F + R') - (f x * G + R) - (-R + f x * A x) - (-R' + f x * B x) + f x * C x + _ = (f x * E + f x * F - f x * G - f x * A x - f x * B x + f x * C x) + R' + R' := by abel - _ = f x * (rhs_aux I X Y Z x + rhs_aux I Y Z X x - rhs_aux I Z X Y x - A x - B x + C x) + R' + R' := by - congr 1 - congr 2 - sorry -- why abel not successful? - _ = _ := by - abel - -#exit - + _ = f x * (E + F - G - A x - B x + C x) + R' + R' := by ring + _ = _ := by ac_rfl +#print axioms leviCivita_rhs'_smulX_apply variable {I} in -lemma leviCivita_rhs_smulX_apply {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : - leviCivita_rhs I (f • X) Y Z x = f x • leviCivita_rhs I X Y Z x := by - simp [leviCivita_rhs, leviCivita_rhs'_smulX_apply (Y := Y) (Z := Z) hf hX, - ← mul_assoc, mul_comm _ (f x)] +lemma leviCivita_rhs_smulX_apply [CompleteSpace E] {f : M → ℝ} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + letI A := dfY * ⟪Z, X⟫ x + leviCivita_rhs I (f • X) Y Z x = f x • leviCivita_rhs I X Y Z x + A := by + simp only [leviCivita_rhs, one_div, Pi.smul_apply, smul_eq_mul] + simp_rw [leviCivita_rhs'_smulX_apply (I := I) hf hX hY hZ] + rw [← mul_assoc, mul_comm (f x), left_distrib, left_distrib] + set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + set A := dfY * ⟪Z, X⟫ x + rw [add_assoc, show 2⁻¹ * A + 2⁻¹ * A = A by ring] + congr 1 + rw [smul_eq_mul]; rw [mul_assoc] +-- TODO: need an extra term; how to state this in the nicest way? variable {I} in -lemma leviCivita_rhs_smulX {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : +lemma leviCivita_rhs_smulX [CompleteSpace E] {f : M → ℝ} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by ext x - exact leviCivita_rhs_smulX_apply (hf x) (hX x) + sorry -- exact leviCivita_rhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) lemma leviCivita_rhs'_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) @@ -610,8 +625,9 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have hg : MDiff g := sorry -- might need this (hopefully not!) rw [Finset.smul_sum] congr; ext i - rw [leviCivita_rhs_smulX _ _ _ hg hX] - simp [← smul_assoc] + sorry -- TODO: fix this once all the smul computations are sorry-free! + --rw [leviCivita_rhs_smulX _ _ _ hg hX] + --simp [← smul_assoc] smul_const_σ X σ a x hx := by unfold lcCandidate_aux dsimp From f02d0f4a1725351c03db1eb9eeb94e77924d2713 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 10:30:04 +0200 Subject: [PATCH 312/601] cherry-pick: partition of unity lemmas --- .../Geometry/Manifold/PartitionOfUnity.lean | 103 +++++++++++++++--- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index 39642dda8f752f..11ce8b4609b1dd 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -5,6 +5,7 @@ Authors: Yury Kudryashov -/ import Mathlib.Geometry.Manifold.Algebra.Structures import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Topology.MetricSpace.PartitionOfUnity import Mathlib.Topology.ShrinkingLemma @@ -58,7 +59,7 @@ smooth bump function, partition of unity universe uι uE uH uM uF -open Function Filter Module Set +open Bundle Function Filter Module Set open scoped Topology Manifold ContDiff noncomputable section @@ -573,29 +574,103 @@ end SmoothPartitionOfUnity variable [SigmaCompactSpace M] [T2Space M] {t : M → Set F} {n : ℕ∞} +/-- Let `V` be a vector bundle over a σ-compact Hausdorff finite dimensional topological manifold +`M`. Let `t : M → Set (V x)` be a family of convex sets in the fibers of `V`. +Suppose that for each point `x₀ : M` there exists a neighborhood `U_x₀` of `x₀` and a local +section `s_loc : M → V x` such that `s_loc` is $C^n$ smooth on `U_x₀` (when viewed as a map to +the total space of the bundle) and `s_loc y ∈ t y` for all `y ∈ U_x₀`. +Then there exists a global $C^n$ smooth section `s : Cₛ^n⟮I_M; F_fiber, V⟯` such that +`s x ∈ t x` for all `x : M`. +-/ +theorem exists_contMDiffOn_section_forall_mem_convex_of_local + {F_fiber : Type*} [NormedAddCommGroup F_fiber] [NormedSpace ℝ F_fiber] + (V : M → Type*) [∀ x, AddCommGroup (V x)] [∀ x, TopologicalSpace (V x)] [∀ x, Module ℝ (V x)] + [TopologicalSpace (TotalSpace F_fiber V)] [FiberBundle F_fiber V] [VectorBundle ℝ F_fiber V] + (t : ∀ x, Set (V x)) (ht_conv : ∀ x, Convex ℝ (t x)) + (Hloc : + ∀ x₀ : M, ∃ U_x₀ ∈ 𝓝 x₀, ∃ (s_loc : (x : M) → V x), + (ContMDiffOn I (I.prod 𝓘(ℝ, F_fiber)) n + (fun x ↦ TotalSpace.mk' F_fiber x (s_loc x)) U_x₀) ∧ + (∀ y ∈ U_x₀, s_loc y ∈ t y)) : + ∃ s : Cₛ^n⟮I; F_fiber, V⟯, ∀ x : M, s x ∈ t x := by + choose W h_nhds s_loc s_smooth h_mem_t using Hloc + -- Construct an open cover from the interiors of the given neighborhoods. + let U (x : M) : Set M := interior (W x) + have hU_covers_univ : univ ⊆ ⋃ x, U x := by + intro x_pt _ + simp only [mem_iUnion] + exact ⟨x_pt, mem_interior_iff_mem_nhds.mpr (h_nhds x_pt)⟩ + -- Obtain a smooth partition of unity subordinate to this open cover. + obtain ⟨ρ, hρU⟩ : ∃ ρ : SmoothPartitionOfUnity M I M univ, ρ.IsSubordinate U := + SmoothPartitionOfUnity.exists_isSubordinate + I isClosed_univ U (fun x ↦ isOpen_interior) hU_covers_univ + -- Define the global section `s` by taking a weighted sum of the local sections. + let s x : V x := ∑ᶠ j, (ρ j x) • s_loc j x + -- Prove that `s`, when viewed as a map to the total space, is smooth. + have (j : M) : ContMDiff I (I.prod 𝓘(ℝ, F_fiber)) n + (fun x ↦ TotalSpace.mk' F_fiber x ((ρ j x) • (s_loc j x))) := by + refine ContMDiffOn.smul_section_of_tsupport ?_ isOpen_interior (hρU j) + ((s_smooth j).mono interior_subset) + exact ((ρ j).contMDiff).of_le (sup_eq_left.mp rfl) |>.contMDiffOn + have hs : ContMDiff I (I.prod 𝓘(ℝ, F_fiber)) n (fun x ↦ TotalSpace.mk' F_fiber x (s x)) := by + apply ContMDiff.finsum_section_of_locallyFinite ?_ this + -- Future: can grind do this? + apply ρ.locallyFinite.subset fun i x hx ↦ ?_ + rw [support] + rw [mem_setOf_eq] at hx ⊢ + exact left_ne_zero_of_smul hx + -- Construct the smooth section and prove it lies in the convex sets `t x`. + refine ⟨⟨s, hs⟩, fun x ↦ ?_⟩ + apply (ht_conv x).finsum_mem (ρ.nonneg · x) (ρ.sum_eq_one (mem_univ x)) + intro j h_ρjx_ne_zero + have h_x_in_tsupport_ρj : x ∈ tsupport (ρ j) := subset_closure (mem_support.mpr h_ρjx_ne_zero) + have h_x_in_Umap_j : x ∈ W j := interior_subset (hρU j h_x_in_tsupport_ρj) + exact h_mem_t j x h_x_in_Umap_j + +/-- Let `V` be a vector bundle over a σ-compact Hausdorff finite dimensional topological manifold +`M`. Let `t : M → Set (V x)` be a family of convex sets in the fibers of `V`. +Suppose that for each point `x₀ : M` there exists a neighborhood `U_x₀` of `x₀` and a local +section `s_loc : M → V x` such that `s_loc` is $C^∞$ smooth on `U_x₀` (when viewed as a map to +the total space of the bundle) and `s_loc y ∈ t y` for all `y ∈ U_x₀`. +Then there exists a global smooth section `s : Cₛ^∞⟮I_M; F_fiber, V⟯` such that +`s x ∈ t x` for all `x : M`. +-/ +theorem exists_smooth_section_forall_mem_convex_of_local + {F_fiber : Type*} [NormedAddCommGroup F_fiber] [NormedSpace ℝ F_fiber] + (V : M → Type*) [∀ x, NormedAddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [TopologicalSpace (TotalSpace F_fiber V)] [FiberBundle F_fiber V] [VectorBundle ℝ F_fiber V] + (t : ∀ x, Set (V x)) (ht_conv : ∀ x, Convex ℝ (t x)) + (Hloc : + ∀ x₀ : M, ∃ U_x₀ ∈ 𝓝 x₀, ∃ (s_loc : (x : M) → V x), + (ContMDiffOn I (I.prod 𝓘(ℝ, F_fiber)) ∞ (fun x ↦ TotalSpace.mk' F_fiber x (s_loc x)) U_x₀) ∧ + (∀ y ∈ U_x₀, s_loc y ∈ t y)) : + ∃ s : Cₛ^∞⟮I; F_fiber, V⟯, ∀ x : M, s x ∈ t x := + exists_contMDiffOn_section_forall_mem_convex_of_local I V t ht_conv Hloc + /-- Let `M` be a σ-compact Hausdorff finite dimensional topological manifold. Let `t : M → Set F` be a family of convex sets. Suppose that for each point `x : M` there exists a neighborhood `U ∈ 𝓝 x` and a function `g : M → F` such that `g` is $C^n$ smooth on `U` and `g y ∈ t y` for all -`y ∈ U`. Then there exists a $C^n$ smooth function `g : C^∞⟮I, M; 𝓘(ℝ, F), F⟯` such that `g x ∈ t x` -for all `x`. See also `exists_smooth_forall_mem_convex_of_local` and +`y ∈ U`. Then there exists a $C^n$ smooth function `g : C^n⟮I, M; 𝓘(ℝ, F), F⟯` such that `g x ∈ t x` +for all `x`. + +This is a special case of `exists_contMDiffOn_section_forall_mem_convex_of_local` where `V` is the +trivial bundle. See also `exists_smooth_forall_mem_convex_of_local` and `exists_smooth_forall_mem_convex_of_local_const`. -/ theorem exists_contMDiffOn_forall_mem_convex_of_local (ht : ∀ x, Convex ℝ (t x)) (Hloc : ∀ x : M, ∃ U ∈ 𝓝 x, ∃ g : M → F, ContMDiffOn I 𝓘(ℝ, F) n g U ∧ ∀ y ∈ U, g y ∈ t y) : - ∃ g : C^n⟮I, M; 𝓘(ℝ, F), F⟯, ∀ x, g x ∈ t x := by - choose U hU g hgs hgt using Hloc - obtain ⟨f, hf⟩ := - SmoothPartitionOfUnity.exists_isSubordinate I isClosed_univ (fun x => interior (U x)) - (fun x => isOpen_interior) fun x _ => mem_iUnion.2 ⟨x, mem_interior_iff_mem_nhds.2 (hU x)⟩ - refine ⟨⟨fun x => ∑ᶠ i, f i x • g i x, - hf.contMDiff_finsum_smul (fun i => isOpen_interior) fun i => (hgs i).mono interior_subset⟩, - fun x => f.finsum_smul_mem_convex (mem_univ x) (fun i hi => hgt _ _ ?_) (ht _)⟩ - exact interior_subset (hf _ <| subset_closure hi) + ∃ g : C^n⟮I, M; 𝓘(ℝ, F), F⟯, ∀ x, g x ∈ t x := + let ⟨s, hs⟩ := exists_contMDiffOn_section_forall_mem_convex_of_local I (fun _ ↦ F) t ht + (fun x₀ ↦ let ⟨U, hU, g, hgs, hgt⟩ := Hloc x₀ + ⟨U, hU, g, fun y hy ↦ Bundle.contMDiffWithinAt_section |>.mpr <| hgs y hy, hgt⟩) + ⟨⟨s, (Bundle.contMDiffAt_section _ |>.mp <| s.contMDiff ·)⟩, hs⟩ /-- Let `M` be a σ-compact Hausdorff finite dimensional topological manifold. Let `t : M → Set F` be a family of convex sets. Suppose that for each point `x : M` there exists a neighborhood `U ∈ 𝓝 x` and a function `g : M → F` such that `g` is smooth on `U` and `g y ∈ t y` for all `y ∈ U`. Then there exists a smooth function `g : C^∞⟮I, M; 𝓘(ℝ, F), F⟯` such that `g x ∈ t x` for all `x`. -See also `exists_contMDiffOn_forall_mem_convex_of_local` and + +This is a special case of `exists_smooth_section_forall_mem_convex_of_local` where `V` is the +trivial bundle. See also `exists_contMDiffOn_forall_mem_convex_of_local` and `exists_smooth_forall_mem_convex_of_local_const`. -/ theorem exists_smooth_forall_mem_convex_of_local (ht : ∀ x, Convex ℝ (t x)) (Hloc : ∀ x : M, ∃ U ∈ 𝓝 x, ∃ g : M → F, ContMDiffOn I 𝓘(ℝ, F) ∞ g U ∧ ∀ y ∈ U, g y ∈ t y) : @@ -605,7 +680,7 @@ theorem exists_smooth_forall_mem_convex_of_local (ht : ∀ x, Convex ℝ (t x)) /-- Let `M` be a σ-compact Hausdorff finite dimensional topological manifold. Let `t : M → Set F` be a family of convex sets. Suppose that for each point `x : M` there exists a vector `c : F` such that for all `y` in a neighborhood of `x` we have `c ∈ t y`. Then there exists a smooth function -`g : C^∞⟮I, M; 𝓘(ℝ, F), F⟯` such that `g x ∈ t x` for all `x`. See also +`g : C^∞⟮I, M; 𝓘(ℝ, F), F⟯` such that `g x ∈ t x` for all `x`. See also `exists_contMDiffOn_forall_mem_convex_of_local` and `exists_smooth_forall_mem_convex_of_local`. -/ theorem exists_smooth_forall_mem_convex_of_local_const (ht : ∀ x, Convex ℝ (t x)) (Hloc : ∀ x : M, ∃ c : F, ∀ᶠ y in 𝓝 x, c ∈ t y) : ∃ g : C^∞⟮I, M; 𝓘(ℝ, F), F⟯, ∀ x, g x ∈ t x := From d3482d8cc99d914f97653dd7d88d63d97b16351c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 10:34:14 +0200 Subject: [PATCH 313/601] chore: cherry-pick more --- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 7 ++++ .../Manifold/VectorBundle/SmoothSection.lean | 35 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index 345eb828a8c3f4..3b2527224fe48c 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -821,6 +821,13 @@ theorem ContMDiffWithinAt.congr (h : ContMDiffWithinAt I I' n f s x) (h₁ : ∀ (hx : f₁ x = f x) : ContMDiffWithinAt I I' n f₁ s x := (contDiffWithinAt_localInvariantProp n).liftPropWithinAt_congr h h₁ hx +/-- Version of `ContMDiffWithinAt.congr` where `x` need not be contained in `s`, +but `f` and `f₁` are equal on a set containing both. -/ +theorem ContMDiffWithinAt.congr' (h : ContMDiffWithinAt I I' n f s x) (h₁ : ∀ y ∈ t, f₁ y = f y) + (hst : s ⊆ t) (hxt : x ∈ t) : + ContMDiffWithinAt I I' n f₁ s x := + h.congr (fun _y hy ↦ h₁ _ (hst hy)) (h₁ x hxt) + theorem contMDiffWithinAt_congr (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : f₁ x = f x) : ContMDiffWithinAt I I' n f₁ s x ↔ ContMDiffWithinAt I I' n f s x := (contDiffWithinAt_localInvariantProp n).liftPropWithinAt_congr_iff h₁ hx diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 56b1f1847c03c5..313b2b427ed23b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -294,6 +294,41 @@ lemma ContMDiff.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := fun x ↦ .sum_section_of_locallyFinite ht fun i ↦ ht' i x +-- Future: the next four lemmas can presumably be generalised, but some hypotheses on the supports +-- of the sections `t i` are necessary. +lemma ContMDiffWithinAt.finsum_section_of_locallyFinite + (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) + (ht' : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : + ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) u x₀ := by + apply (ContMDiffWithinAt.sum_section_of_locallyFinite ht ht').congr' (t := Set.univ) + (fun y hy ↦ ?_) (by simp) trivial + rw [← tsum_eq_finsum] + choose U hu hfin using ht y + have : {x | t x y ≠ 0} ⊆ {i | ((fun i ↦ {x | t i x ≠ 0}) i ∩ U).Nonempty} := by + intro x hx + rw [Set.mem_setOf] at hx ⊢ + use y + simpa using ⟨hx, mem_of_mem_nhds hu⟩ + exact Set.Finite.subset hfin this + +lemma ContMDiffAt.finsum_section_of_locallyFinite + (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) + (ht' : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : + ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by + simp_rw [← contMDiffWithinAt_univ] at ht' ⊢ + exact ContMDiffWithinAt.finsum_section_of_locallyFinite ht ht' + +lemma ContMDiffOn.finsum_section_of_locallyFinite + (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) + (ht' : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : + ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) u := + fun x hx ↦ ContMDiffWithinAt.finsum_section_of_locallyFinite ht fun i ↦ ht' i x hx + +lemma ContMDiff.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) + (ht' : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : + ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := + fun x ↦ ContMDiffAt.finsum_section_of_locallyFinite ht fun i ↦ ht' i x + end operations /-- Bundled `n` times continuously differentiable sections of a vector bundle. From bbd2315c4c870492dcfca42d17de2c237bc190c1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 10:39:37 +0200 Subject: [PATCH 314/601] chore: cherry-pick wip work from 28056, TODO finish it using orthonormal frames --- Mathlib.lean | 1 + .../Riemannian/ExistsRiemannianMetric.lean | 295 ++++++++++++++++++ .../Manifold/VectorBundle/LeviCivita.lean | 2 +- 3 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9970a96054b8e4..5e8a0678c547aa 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3760,6 +3760,7 @@ import Mathlib.Geometry.Manifold.Metrizable import Mathlib.Geometry.Manifold.PartitionOfUnity import Mathlib.Geometry.Manifold.PoincareConjecture import Mathlib.Geometry.Manifold.Riemannian.Basic +import Mathlib.Geometry.Manifold.Riemannian.ExistsRiemannianMetric import Mathlib.Geometry.Manifold.Riemannian.PathELength import Mathlib.Geometry.Manifold.Sheaf.Basic import Mathlib.Geometry.Manifold.Sheaf.LocallyRingedSpace diff --git a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean new file mode 100644 index 00000000000000..bd4c9571557410 --- /dev/null +++ b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean @@ -0,0 +1,295 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.PartitionOfUnity +import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame +import Mathlib.Geometry.Manifold.VectorBundle.Riemannian + +/-! ## Existence of a Riemannian bundle metric +Using a partition of unity, we prove that every finite-dimensional smooth vector bundle +admits a smooth Riemannian metric. + +## TODO +- this should work for C^n; prove the same for topological bundles and add it there +- also deduce that every manifold can be made Riemannian... +-/ + +open Bundle ContDiff Manifold + +-- Let E be a smooth vector bundle over a manifold E + +variable + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace ℝ EB] + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners ℝ EB HB} {n : WithTop ℕ∞} + {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] + {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + {E : B → Type*} [TopologicalSpace (TotalSpace F E)] + [∀ x, TopologicalSpace (E x)] [∀ x, AddCommGroup (E x)] [∀ x, Module ℝ (E x)] + [FiberBundle F E] [VectorBundle ℝ F E] + [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + +section + +variable (E) in +/-- This is the bundle `Hom_ℝ(E, T)`, where `T` is the rank one trivial bundle over `B`. -/ +private def V : (b : B) → Type _ := (fun b ↦ E b →L[ℝ] Trivial B ℝ b) + +noncomputable instance : (x : B) → TopologicalSpace (V E x) := by + unfold V + infer_instance + +noncomputable instance : (x : B) → AddCommGroup (V E x) := by + unfold V + infer_instance + +noncomputable instance (x : B) : Module ℝ (V E x) := by + unfold V + infer_instance + +noncomputable instance : TopologicalSpace (TotalSpace (F →L[ℝ] ℝ) (V E)) := by + unfold V + infer_instance + +noncomputable instance : FiberBundle (F →L[ℝ] ℝ) (V E) := by + unfold V + infer_instance + +noncomputable instance : VectorBundle ℝ (F →L[ℝ] ℝ) (V E) := by + unfold V + infer_instance + +noncomputable instance : ContMDiffVectorBundle n (F →L[ℝ] ℝ) (V E) IB := by + unfold V + infer_instance + +instance (x : B) : ContinuousAdd (V E x) := by + unfold V + infer_instance + +instance (x : B) : ContinuousSMul ℝ (V E x) := by + unfold V + infer_instance + +instance (x : B) : IsTopologicalAddGroup (V E x) := by + unfold V + infer_instance + +example : ContMDiffVectorBundle n (F →L[ℝ] F →L[ℝ] ℝ) (fun b ↦ E b →L[ℝ] V E b) IB := + ContMDiffVectorBundle.continuousLinearMap (IB := IB) (n := n) + (F₁ := F) (E₁ := E) (F₂ := F →L[ℝ] ℝ) (E₂ := V E) + +variable (E) in +/-- The real vector bundle `Hom(E, Hom(E, T)) = Hom(E, V)`, whose fiber at `x` is +(equivalent to) the space of continuous real bilinear maps `E x → E x → ℝ`. -/ +private def W : (b : B) → Type _ := fun b ↦ E b →L[ℝ] V E b + +noncomputable instance (x : B) : AddCommGroup (W E x) := by + unfold W + infer_instance + +noncomputable instance (x : B) : Module ℝ (W E x) := by + unfold W + infer_instance + +noncomputable instance : TopologicalSpace (TotalSpace (F →L[ℝ] F →L[ℝ] ℝ) (W E)) := by + unfold W + infer_instance + +noncomputable instance (x : B) : TopologicalSpace (W E x) := by + unfold W + infer_instance + +noncomputable instance : FiberBundle (F →L[ℝ] F →L[ℝ] ℝ) (W E) := by + unfold W + infer_instance + +noncomputable instance : VectorBundle ℝ (F →L[ℝ] F →L[ℝ] ℝ) (W E) := by + unfold W + infer_instance + +noncomputable instance : ContMDiffVectorBundle n (F →L[ℝ] F →L[ℝ] ℝ) (W E) IB := by + unfold W + infer_instance + +end + +variable (E) in +/-- The first condition imposed on sections of `W`: they should give rise to a symmetric +pairing on each fibre `E x`. -/ +private def condition1 (x : B) : Set (E x →L[ℝ] E x →L[ℝ] ℝ) := + {φ | ∀ v w : E x, φ v w = φ w v} + +variable (E) in +/-- The second condition imposed on sections of `W`: they should give rise to a positive definite +pairing on each fibre `E x`. -/ +private def condition2 (x : B) : Set (E x →L[ℝ] E x →L[ℝ] ℝ) := + {φ | ∀ v : E x, v ≠ 0 → 0 < φ v v} + +omit [TopologicalSpace B] in +lemma convex_condition1 (x : B) : Convex ℝ (condition1 E x) := by + intro φ hφ ψ hψ s t hs ht hst v w + simp [hφ v w, hψ v w] + +omit [TopologicalSpace B] in +lemma convex_condition2 (x : B) : Convex ℝ (condition2 E x) := by + unfold condition2 + intro φ hφ ψ hψ s t hs ht hst + intro v hv + rw [Set.mem_setOf] at hφ hψ + have aux := Convex.min_le_combo ((φ v) v) ((ψ v) v) hs ht hst + have : 0 < min ((φ v) v) ((ψ v) v) := lt_min (hφ v hv) (hψ v hv) + simpa using gt_of_ge_of_gt aux this + +variable (E) in +/-- Conditions imposed on sections of `W`: they should give rise to a positive definite symmetric +pairing on each fibre `E x`. -/ +def condition (x : B) : Set (W E x) := by + unfold W V Bundle.Trivial + exact condition1 E x ∩ condition2 E x + +omit [TopologicalSpace B] in +lemma convex_condition (x : B) : Convex ℝ (condition E x) := + Convex.inter (convex_condition1 x) (convex_condition2 x) + +variable [FiniteDimensional ℝ EB] [IsManifold IB ∞ B] [SigmaCompactSpace B] [T2Space B] + +-- TODO: construct a local section which is smooth in my coords, +-- and has all the definiteness properties I'll want later! +variable (E) in +def local_section_at (x₀ : B) : (x : B) → W E x := sorry + +variable (E F) in +lemma contMDiff_localSection (x₀ : B) : + letI t := trivializationAt F E x₀ + ContMDiffOn IB (IB.prod 𝓘(ℝ, F →L[ℝ] F →L[ℝ] ℝ)) ∞ + (fun x ↦ TotalSpace.mk' (F →L[ℝ] F →L[ℝ] ℝ) x (local_section_at E x₀ x)) t.baseSet := + sorry + +-- MAYBE: also make a definition nhd, which is the nhd on which local_section_at stays pos. def. +lemma is_good_localSection (x₀ : B) : + ∀ y ∈ (trivializationAt F E x₀).baseSet, local_section_at E x₀ y ∈ condition E y := by + intro y hy + unfold condition + simp only [id_eq] + erw [Set.mem_setOf] + refine ⟨?_, ?_⟩ + · sorry -- symmetry + · sorry -- pos. definite + +lemma hloc_TODO (x₀ : B) : + ∃ U_x₀ ∈ nhds x₀, ∃ s_loc : (x : B) → W E x, + ContMDiffOn IB (IB.prod 𝓘(ℝ, F →L[ℝ] F →L[ℝ] ℝ)) ∞ + (fun x ↦ TotalSpace.mk' (F →L[ℝ] F →L[ℝ] ℝ) x (s_loc x)) U_x₀ ∧ + ∀ y ∈ U_x₀, s_loc y ∈ condition E y := by + letI t := trivializationAt F E x₀ + have := t.open_baseSet.mem_nhds <| FiberBundle.mem_baseSet_trivializationAt' x₀ + use t.baseSet, this, local_section_at E x₀ + exact ⟨contMDiff_localSection F E x₀, is_good_localSection x₀⟩ + +variable (E F IB) in +/-- Key step in the construction of a Riemannian metric on `E`: we construct a smooth section +of the bundle `W = Hom(E, Hom(E, T))` with the right properties (translating into symmetric +and positive definiteness of the resulting metric. -/ +noncomputable def foo_aux : Cₛ^∞⟮IB; F →L[ℝ] F →L[ℝ] ℝ, W E⟯ := + Classical.choose <| + exists_contMDiffOn_section_forall_mem_convex_of_local IB (V := W E) (n := (⊤ : ℕ∞)) + (condition E) convex_condition hloc_TODO + +variable (E F IB) in +lemma foo_aux_prop (x₀ : B) : foo_aux IB F E x₀ ∈ condition E x₀ := by + apply Classical.choose_spec <| + exists_contMDiffOn_section_forall_mem_convex_of_local IB (V := W E) (n := (⊤ : ℕ∞)) + (condition E) convex_condition hloc_TODO + +-- In what generality does this hold? +lemma aux_special (G : Type*) [NormedAddCommGroup G] [NormedSpace ℝ G] [FiniteDimensional ℝ G] + (φ : G →L[ℝ] G →L[ℝ] ℝ) (hpos : ∀ v : G, v ≠ 0 → 0 < φ v v) : + Bornology.IsVonNBounded ℝ {v | (φ v) v < 1} := by + -- Proof sketch: choose a basis {b_i} of G. + -- Each `φ b_i b_i` is non-zero by hypothesis, hence has positive norm. + -- By finite-dimensionality of `G`, we have `0 < r := min ‖φ b_i b_i‖`, + -- thus B(r, 0) is contained in the image of the unit ball under v ↦ φ v v. + sorry + +section aux + +variable {G : Type*} [AddCommGroup G] [TopologicalSpace G] [Module ℝ G] + [ContinuousAdd G] [ContinuousSMul ℝ G] [FiniteDimensional ℝ G] + +-- XXX: this is also a norm, not just a seminorm! +noncomputable def mynorm (φ : G →L[ℝ] G →L[ℝ] ℝ) : Seminorm ℝ G where + toFun v := Real.sqrt (φ v v) + map_zero' := by simp + add_le' r s := by sorry -- shouldn't be difficult + neg' r := by simp + smul' a v := by simp [← mul_assoc, ← Real.sqrt_mul_self_eq_abs, Real.sqrt_mul (mul_self_nonneg a)] + +-- noncomputable def mynorm_space (φ : G →L[ℝ] G →L[ℝ] ℝ) : SeminormedAddCommGroup G where +-- norm := mynorm φ +-- dist_self x := by simp +-- dist_comm x y := by +-- simp only [mynorm] +-- change Real.sqrt (φ (x - y) (x - y)) = Real.sqrt (φ (y - x) (y - x)) +-- sorry -- is just neg, so provable +-- dist_triangle := sorry -- follows from add_le' above (probably not difficult) + +-- attribute [local instance] mynorm_space +-- noncomputable def mynorm_space2 (φ : G →L[ℝ] G →L[ℝ] ℝ) : NormedSpace ℝ G where + +noncomputable def aux (φ : G →L[ℝ] G →L[ℝ] ℝ) : SeminormFamily ℝ G (Fin 1) := fun _ ↦ mynorm φ + +lemma bar (φ : G →L[ℝ] G →L[ℝ] ℝ) (hpos : ∀ v : G, v ≠ 0 → 0 < φ v v) : WithSeminorms (aux φ) := + -- In finite dimension there is a single topological vector space structure... + -- and mynorm defines a norm, hence a TVS structure. + sorry + +end aux + +-- golfing suggestions welcome +lemma qux {α : Type*} [Unique α] (s : Finset α) : s = ∅ ∨ s = {default} := by + by_cases h : s = ∅ + · simp [h] + · rw [Finset.eq_singleton_iff_nonempty_unique_mem] + refine Or.inr ⟨Finset.nonempty_iff_ne_empty.mpr h, fun x hx ↦ Unique.uniq _ _⟩ + +lemma aux_tvs (G : Type*) [AddCommGroup G] [TopologicalSpace G] [Module ℝ G] + [ContinuousAdd G] [ContinuousSMul ℝ G] [FiniteDimensional ℝ G] + (φ : G →L[ℝ] G →L[ℝ] ℝ) (hpos : ∀ v : G, v ≠ 0 → 0 < φ v v) : + Bornology.IsVonNBounded ℝ {v | (φ v) v < 1} := by + -- Proof sketch (courtesy of Sébastien Gouezel): + -- Phi gives you a norm, which defines the same topology as the initial one + -- (as in finite dimension there is a single topological vector space structure). + -- The unit ball for the norm is von Neumann bounded wrt the topology defined by the norm + -- (we have this in mathlib), so also for the initial topology. + rw [WithSeminorms.isVonNBounded_iff_finset_seminorm_bounded (p := aux φ) (bar φ hpos)] + intro I + letI J : Finset (Fin 1) := {1} + suffices ∃ r > 0, ∀ x ∈ {v | (φ v) v < 1}, (J.sup (aux φ)) x < r by + obtain (rfl | h) := qux I + · use 1; simp + · convert this + simp only [Set.mem_setOf_eq, Finset.sup_singleton, J] + refine ⟨1, by norm_num, fun x h ↦ ?_⟩ + simp only [aux, mynorm] + change Real.sqrt (φ x x) < 1 + rw [Real.sqrt_lt' (by norm_num)] + simp [h] + +-- TODO: is the finite-dimensionality actually required? +-- Are the TVS hypotheses actually a restriction? +noncomputable def foo + [∀ x, FiniteDimensional ℝ (E x)] [∀ x, ContinuousAdd (E x)] [∀ x, ContinuousSMul ℝ (E x)] : + ContMDiffRiemannianMetric IB ∞ F E where + inner := foo_aux IB F E + symm b := (foo_aux_prop IB F E b).1 + pos b := (foo_aux_prop IB F E b).2 + isVonNBounded b := aux_tvs (E b) (foo_aux IB F E b) (foo_aux_prop IB F E b).2 + contMDiff := (foo_aux IB F E).contMDiff + +-- /-- Every `C^n` vector bundle whose fibre admits a `C^n` partition of unity +-- is a `C^n` Riemannian vector bundle. (The Lean statement assumes an inner product on each fibre +-- already, which is why there are no other assumptions yet??) -/ +-- lemma ContDiffVectorBundle.isContMDiffRiemannianBundle : IsContMDiffRiemannianBundle IB n F E := +-- ⟨RMetric IB E, rMetric_contMDiff, fun x v w ↦ rMetric_eq x v w⟩ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 20c9fbdcac80e1..62aa8111c0f41c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -14,7 +14,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Riemannian This file will define the Levi-Civita connection on any Riemannian manifold. Details to be written! - +TODO: refactor this file, to make Levi-Civita take a Riemannian metric instead! TODO: more generally, define a notion of metric connections (e.g., those whose parallel transport From 4d2b28db55b326e7aadaec90cb362b8f38110854 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 19:47:30 +0200 Subject: [PATCH 315/601] chore(LieBracket): two small tweaks --- Mathlib/Geometry/Manifold/VectorField/LieBracket.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index b0600efcff9829..a2b7409334f12a 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -367,7 +367,7 @@ lemma mlieBracketWithin_const_smul_left mlieBracketWithin I (c • V) W s x = c • mlieBracketWithin I V W s x := by have aux := mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs simp [mfderivWithin_const] at aux - convert aux + exact aux lemma mlieBracket_const_smul_left (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) : @@ -381,7 +381,7 @@ lemma mlieBracketWithin_const_smul_right mlieBracketWithin I V (c • W) s x = c • mlieBracketWithin I V W s x := by have aux := mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs simp [mfderivWithin_const] at aux - convert aux + exact aux lemma mlieBracket_const_smul_right (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : From ed37d1bd5f7bb47f4ed72e09e7e10a125a8e0337 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 19:49:26 +0200 Subject: [PATCH 316/601] chore: cherry-pick current WIP from 26743's branch --- .../Manifold/VectorField/LieBracket.lean | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index a2b7409334f12a..b9f375fc5de88e 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -318,10 +318,47 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA rw [mpullbackWithin_smul] set V' := (mpullbackWithin 𝓘(𝕜, E) I (↑(extChartAt I x).symm) V (range I)) set W' := (mpullbackWithin 𝓘(𝕜, E) I (↑(extChartAt I x).symm) W (range I)) - -- idea: rewrite by lieBracketWithin_smul_right - -- recognise the terms on the rhs, done - -- let aux := lieBracketWithin_smul_right (V := V') (W := W') - --simp [mfderivWithin_eq_fderivWithin] + -- cherry-picked from here, to finish! + set f' := (f ∘ (extChartAt I x).symm) + set s' := ((extChartAt I x).symm ⁻¹' s ∩ range I) + set x' := (extChartAt I x) x + change mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (lieBracketWithin 𝕜 V' (fun y ↦ f' y • W' y) s') x = + (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x + + f x • mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (lieBracketWithin 𝕜 V' W' s') x + -- Step 1: rewrite using lieBracketWithin_smul_right + let aux := lieBracketWithin_smul_right (V := V') (W := W') (s := s') (f := f') (x := x') + have hf' : DifferentiableWithinAt 𝕜 f' s' x' := sorry + have hW' : DifferentiableWithinAt 𝕜 W' s' x' := sorry + have hs' : UniqueDiffWithinAt 𝕜 s' x' := sorry + let aux' := aux hf' hW' hs' + + trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun x₀ ↦ (lieBracketWithin 𝕜 V' (f' • W') s') x₀) x + · rfl + -- issue: silent defeq abuse, a map E → E vs a map tangent space -> tangent space + let A (x₀) := (fderivWithin 𝕜 f' s' x₀) (V' x₀) • W' x₀ + let B (x₀) := f' x₀ • lieBracketWithin 𝕜 V' W' s' x₀ + -- thus, this does not typecheck... + -- trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun y ↦ A y + B y) x + -- · sorry + + -- first part to get the claim + have : mpullback I 𝓘(𝕜, E) (extChartAt I x) A x + = (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x := by + unfold A + simp [mfderivWithin, hf] + simp [mpullback] + congr + · simp [V'] + sorry + · sorry + have : mpullback I 𝓘(𝕜, E) (extChartAt I x) B x + = f x • mpullback I 𝓘(𝕜, E) (↑(extChartAt I x)) (lieBracketWithin 𝕜 V' W' s') x := by + simp only [B] + trans mpullback I 𝓘(𝕜, E) (↑(extChartAt I x)) (f' • lieBracketWithin 𝕜 V' W' s') x + · rfl + rw [mpullback_smul (V := lieBracketWithin 𝕜 V' W' s')] + simp [f'] + -- adding these identities should prove the claim sorry /-- From 902d19096d53181377c26476348ee6b2011f3c97 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 20:02:53 +0200 Subject: [PATCH 317/601] Three easy sorries --- Mathlib/Geometry/Manifold/VectorField/LieBracket.lean | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index b9f375fc5de88e..d399e5d68d0a8b 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -326,11 +326,12 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x + f x • mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (lieBracketWithin 𝕜 V' W' s') x -- Step 1: rewrite using lieBracketWithin_smul_right - let aux := lieBracketWithin_smul_right (V := V') (W := W') (s := s') (f := f') (x := x') - have hf' : DifferentiableWithinAt 𝕜 f' s' x' := sorry - have hW' : DifferentiableWithinAt 𝕜 W' s' x' := sorry - have hs' : UniqueDiffWithinAt 𝕜 s' x' := sorry - let aux' := aux hf' hW' hs' + have hf' : DifferentiableWithinAt 𝕜 f' s' x' := by + -- Is this worth a separate lemma? + obtain ⟨_, hf⟩ := mdifferentiableWithinAt_iff.mp hf + rwa [extChartAt_self_eq] at hf + let aux := lieBracketWithin_smul_right (V := V') hf' + hW.differentiableWithinAt_mpullbackWithin_vectorField hs trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun x₀ ↦ (lieBracketWithin 𝕜 V' (f' • W') s') x₀) x · rfl From 7fae63c6f559008038e7f47ea058163e1a3d7223 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 20:04:34 +0200 Subject: [PATCH 318/601] Tweak --- Mathlib/Geometry/Manifold/VectorField/LieBracket.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index d399e5d68d0a8b..ef83508cf358a1 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -333,7 +333,7 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA let aux := lieBracketWithin_smul_right (V := V') hf' hW.differentiableWithinAt_mpullbackWithin_vectorField hs - trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun x₀ ↦ (lieBracketWithin 𝕜 V' (f' • W') s') x₀) x + trans mpullback I 𝓘(𝕜, E) (extChartAt I x) ((lieBracketWithin 𝕜 V' (f' • W') s') ·) x · rfl -- issue: silent defeq abuse, a map E → E vs a map tangent space -> tangent space let A (x₀) := (fderivWithin 𝕜 f' s' x₀) (V' x₀) • W' x₀ @@ -362,6 +362,8 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA -- adding these identities should prove the claim sorry +#exit + /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. From d96442e0474d1be125a36407095a4ea81560ffc2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 21:26:35 +0200 Subject: [PATCH 319/601] Progress: one helper computation looks solid, another might be wrong as-is?? --- .../Manifold/VectorField/LieBracket.lean | 75 ++++++++++++++++--- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index ef83508cf358a1..df514a601335af 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -305,6 +305,27 @@ lemma _root_.MDifferentiableWithinAt.differentiableWithinAt_mpullbackWithin_vect exact ((contMDiff_snd_tangentBundle_modelSpace E 𝓘(𝕜, E)).contMDiffAt.mdifferentiableAt le_rfl).comp_mdifferentiableWithinAt _ this +variable (W x) in +omit [CompleteSpace E] in +lemma aux_computation : + (mfderiv I 𝓘(𝕜, E) (extChartAt I x) x).inverse + ((mfderivWithin 𝓘(𝕜, E) I ((extChartAt I x).symm) (range I) ((extChartAt I x) x)).inverse + (W ((extChartAt I x).symm ((extChartAt I x) x)))) + = W x := by + set φ := extChartAt I x + set x' := (extChartAt I x) x + rw [extChartAt_to_inv x] + calc + _ = ((mfderiv I 𝓘(𝕜, E) φ x).inverse.comp + (mfderivWithin 𝓘(𝕜, E) I φ.symm (range I) x').inverse) (W x) := rfl + _ = (ContinuousLinearMap.id 𝕜 _) (W x) := by + congr + rw [← ContinuousLinearMap.IsInvertible.inverse_comp_of_left, + ← ContinuousLinearMap.inverse_id, + mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (mem_extChartAt_source x)] + exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) + _ = W x := by simp + /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. Version within a set. @@ -335,24 +356,56 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA trans mpullback I 𝓘(𝕜, E) (extChartAt I x) ((lieBracketWithin 𝕜 V' (f' • W') s') ·) x · rfl - -- issue: silent defeq abuse, a map E → E vs a map tangent space -> tangent space + -- We need the cast, since on the nose `B` is a map `E → E`, + -- while we need a map between tangent spaces. let A (x₀) := (fderivWithin 𝕜 f' s' x₀) (V' x₀) • W' x₀ - let B (x₀) := f' x₀ • lieBracketWithin 𝕜 V' W' s' x₀ - -- thus, this does not typecheck... - -- trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun y ↦ A y + B y) x - -- · sorry - - -- first part to get the claim - have : mpullback I 𝓘(𝕜, E) (extChartAt I x) A x + let B (x₀) : TangentSpace 𝓘(𝕜, E) x₀ := f' x₀ • lieBracketWithin 𝕜 V' W' s' x₀ + trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun y ↦ A y + B y) x + · simp only [mpullback_apply] + congr + -- missing lemma; first part of the claim + have h1 : mpullback I 𝓘(𝕜, E) (extChartAt I x) A x = (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x := by unfold A simp [mfderivWithin, hf] simp [mpullback] + have cleanup1 : I ((chartAt H x) x) = x' := rfl + have cleanup2 : f ∘ (chartAt H x).symm ∘ ↑I.symm = f' := rfl + rw [cleanup1, cleanup2] congr - · simp [V'] - sorry · sorry - have : mpullback I 𝓘(𝕜, E) (extChartAt I x) B x + have : V' x' = V x := by + simp only [V', x'] + set φ := (extChartAt I x) + simp only [mpullbackWithin] + -- is this actually true? not sure! + --have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt_symm + -- V (x := x) (s := Set.univ) + --have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt + -- V (x := x) (s := Set.univ) + symm + sorry + --convert this + exact aux_computation x W + + -- · simp only [V'] + -- #check VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt + -- show mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) x' = V x + -- have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt + -- -- missing lemma! + -- simp only [mpullbackWithin] + -- simp only [mfderivWithin] + -- have : MDifferentiableWithinAt 𝓘(𝕜, E) I (↑(extChartAt I x).symm) (range ↑I) x' := sorry + -- simp only [this, if_true] + -- simp only [pullbackWithin] + -- --simp + + -- simp [mpullbackWithin] + -- ext + -- simp + -- rw? + -- sorry + have h2 : mpullback I 𝓘(𝕜, E) (extChartAt I x) B x = f x • mpullback I 𝓘(𝕜, E) (↑(extChartAt I x)) (lieBracketWithin 𝕜 V' W' s') x := by simp only [B] trans mpullback I 𝓘(𝕜, E) (↑(extChartAt I x)) (f' • lieBracketWithin 𝕜 V' W' s') x From c781a19d269de6f8c4fc8bf43eec9ae57bdcbba8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 21:36:10 +0200 Subject: [PATCH 320/601] Glue sorry done; some tweaks --- .../Manifold/VectorField/LieBracket.lean | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index df514a601335af..8ff01b6044a80e 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -337,11 +337,11 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA (mfderivWithin I 𝓘(𝕜) f s x) (V x) • (W x) + (f x) • mlieBracketWithin I V W s x := by simp only [mlieBracketWithin] rw [mpullbackWithin_smul] - set V' := (mpullbackWithin 𝓘(𝕜, E) I (↑(extChartAt I x).symm) V (range I)) - set W' := (mpullbackWithin 𝓘(𝕜, E) I (↑(extChartAt I x).symm) W (range I)) - -- cherry-picked from here, to finish! - set f' := (f ∘ (extChartAt I x).symm) - set s' := ((extChartAt I x).symm ⁻¹' s ∩ range I) + -- Simplify local notation a bit. + set V' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) + set W' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm W (range I) + set f' := f ∘ (extChartAt I x).symm + set s' := (extChartAt I x).symm ⁻¹' s ∩ range I set x' := (extChartAt I x) x change mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (lieBracketWithin 𝕜 V' (fun y ↦ f' y • W' y) s') x = (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x + @@ -406,14 +406,10 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA -- rw? -- sorry have h2 : mpullback I 𝓘(𝕜, E) (extChartAt I x) B x - = f x • mpullback I 𝓘(𝕜, E) (↑(extChartAt I x)) (lieBracketWithin 𝕜 V' W' s') x := by - simp only [B] - trans mpullback I 𝓘(𝕜, E) (↑(extChartAt I x)) (f' • lieBracketWithin 𝕜 V' W' s') x - · rfl - rw [mpullback_smul (V := lieBracketWithin 𝕜 V' W' s')] - simp [f'] - -- adding these identities should prove the claim - sorry + = f x • mpullback I 𝓘(𝕜, E) (extChartAt I x) (lieBracketWithin 𝕜 V' W' s') x := by + simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] + -- Adding these identities proves the claim. + rw [← Pi.add_def, mpullback_add_apply]; congr #exit From 699fd173c8039a2a485f95fa18d78d0f9ee4d5d1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 22:02:15 +0200 Subject: [PATCH 321/601] Other computation is close: holds once I restrict my set of consideration --- .../Manifold/VectorField/LieBracket.lean | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 8ff01b6044a80e..b332a3c57a314d 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -326,6 +326,41 @@ lemma aux_computation : exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) _ = W x := by simp +lemma aux_computation2 : + (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) ((extChartAt I x) x)).inverse (V x) + = V x := by + set φ := extChartAt I x + set x' := (extChartAt I x) x + -- this is almost true: it is true within a smaller set (namely extChartAt I x).target... + have : mfderivWithin 𝓘(𝕜, E) I φ.symm (range I) (φ x) = ContinuousLinearMap.id 𝕜 _ := by + rw [mfderivWithin] + have : MDifferentiableWithinAt 𝓘(𝕜, E) I (↑φ.symm) (range ↑I) (φ x) := + mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) + simp? [this] says + simp only [this, ↓reduceIte, writtenInExtChartAt, extChartAt, PartialHomeomorph.extend, + PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, PartialHomeomorph.toFun_eq_coe, + PartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, + PartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, + PartialEquiv.trans_refl, PartialEquiv.refl_symm, PartialEquiv.refl_coe, CompTriple.comp_eq, + preimage_id_eq, id_eq, modelWithCornersSelf_coe, range_id, inter_univ] + rw [extChartAt_to_inv x, ← extChartAt_coe] + have : fderivWithin 𝕜 (φ ∘ φ.symm) (range I) (φ x) = fderivWithin 𝕜 id (range I) (φ x) := by + refine fderivWithin_congr' ?_ ?_ + · intro x' hx' + simp + refine PartialEquiv.right_inv φ ?_ + rw [@extChartAt_target] + refine ⟨?_, hx'⟩ + rw [mem_preimage] -- not necessarily true, though... + sorry + · sorry + rw [this] + exact fderivWithin_id <| I.uniqueDiffOn.uniqueDiffWithinAt (mem_range_self _) + rw [this] + rw [ContinuousLinearMap.inverse_id] + exact rfl + +#exit /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. Version within a set. @@ -354,8 +389,7 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA let aux := lieBracketWithin_smul_right (V := V') hf' hW.differentiableWithinAt_mpullbackWithin_vectorField hs - trans mpullback I 𝓘(𝕜, E) (extChartAt I x) ((lieBracketWithin 𝕜 V' (f' • W') s') ·) x - · rfl + rw [← Pi.smul_def'] -- We need the cast, since on the nose `B` is a map `E → E`, -- while we need a map between tangent spaces. let A (x₀) := (fderivWithin 𝕜 f' s' x₀) (V' x₀) • W' x₀ @@ -372,12 +406,15 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA have cleanup1 : I ((chartAt H x) x) = x' := rfl have cleanup2 : f ∘ (chartAt H x).symm ∘ ↑I.symm = f' := rfl rw [cleanup1, cleanup2] - congr - · sorry + congr 1 + · sorry -- is the sorry below have : V' x' = V x := by simp only [V', x'] - set φ := (extChartAt I x) + --set φ := (extChartAt I x) simp only [mpullbackWithin] + rw [extChartAt_to_inv x] + + -- is this actually true? not sure! --have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt_symm -- V (x := x) (s := Set.univ) From 62e78c88a1aaf19f4b0ed50aca240fe1b15bb69c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 22:17:47 +0200 Subject: [PATCH 322/601] This version of my computation is true, does it suffice? --- .../Manifold/VectorField/LieBracket.lean | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index b332a3c57a314d..6a7c0dee525654 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -326,6 +326,37 @@ lemma aux_computation : exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) _ = W x := by simp +-- does this version suffice for my purposes below? +lemma aux_computation2' : + (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (extChartAt I x).target ((extChartAt I x) x)).inverse (V x) + = V x := by + set φ := extChartAt I x + set x' := (extChartAt I x) x + -- this is almost true: it is true within a smaller set (namely extChartAt I x).target... + have : mfderivWithin 𝓘(𝕜, E) I φ.symm φ.target (φ x) = ContinuousLinearMap.id 𝕜 _ := by + rw [mfderivWithin] + have : MDifferentiableWithinAt 𝓘(𝕜, E) I φ.symm φ.target (φ x) := by + have := mdifferentiableWithinAt_extChartAt_symm (I := I) (mem_extChartAt_target x) + exact this.mono (extChartAt_target_subset_range x) + simp only [this, if_true] + simp only [writtenInExtChartAt, extChartAt, PartialHomeomorph.extend, + PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, PartialHomeomorph.toFun_eq_coe, + PartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, + PartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, + PartialEquiv.trans_refl, PartialEquiv.refl_symm, PartialEquiv.refl_coe, CompTriple.comp_eq, + preimage_id_eq, id_eq, modelWithCornersSelf_coe, range_id, inter_univ] + rw [extChartAt_to_inv x, ← extChartAt_coe] + -- debug why this is needed! + change fderivWithin 𝕜 (↑(extChartAt I x) ∘ ↑φ.symm) (extChartAt I x).target (φ x) = _ + have : fderivWithin 𝕜 (φ ∘ φ.symm) (extChartAt I x).target (φ x) = + fderivWithin 𝕜 id (extChartAt I x).target (φ x) := + fderivWithin_congr' (fun x' hx' ↦ PartialEquiv.right_inv φ hx') (mem_extChartAt_target x) + rw [this] + exact fderivWithin_id (uniqueDiffWithinAt_extChartAt_target x) + rw [this] + rw [ContinuousLinearMap.inverse_id] + exact rfl + lemma aux_computation2 : (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) ((extChartAt I x) x)).inverse (V x) = V x := by @@ -349,7 +380,7 @@ lemma aux_computation2 : · intro x' hx' simp refine PartialEquiv.right_inv φ ?_ - rw [@extChartAt_target] + rw [extChartAt_target] refine ⟨?_, hx'⟩ rw [mem_preimage] -- not necessarily true, though... sorry @@ -360,7 +391,6 @@ lemma aux_computation2 : rw [ContinuousLinearMap.inverse_id] exact rfl -#exit /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. Version within a set. From 8f78aa209da9ac0b5e72a273ffad6ae967db3a0a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 22 Aug 2025 22:30:32 +0200 Subject: [PATCH 323/601] Clean up: intuitively, what I have should suffice; need to think to fix the last gaps --- .../Manifold/VectorField/LieBracket.lean | 51 +++++-------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 6a7c0dee525654..15309beb0e0c1b 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -327,12 +327,13 @@ lemma aux_computation : _ = W x := by simp -- does this version suffice for my purposes below? +variable (x V) in +omit [CompleteSpace E] in lemma aux_computation2' : (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (extChartAt I x).target ((extChartAt I x) x)).inverse (V x) = V x := by set φ := extChartAt I x set x' := (extChartAt I x) x - -- this is almost true: it is true within a smaller set (namely extChartAt I x).target... have : mfderivWithin 𝓘(𝕜, E) I φ.symm φ.target (φ x) = ContinuousLinearMap.id 𝕜 _ := by rw [mfderivWithin] have : MDifferentiableWithinAt 𝓘(𝕜, E) I φ.symm φ.target (φ x) := by @@ -346,17 +347,18 @@ lemma aux_computation2' : PartialEquiv.trans_refl, PartialEquiv.refl_symm, PartialEquiv.refl_coe, CompTriple.comp_eq, preimage_id_eq, id_eq, modelWithCornersSelf_coe, range_id, inter_univ] rw [extChartAt_to_inv x, ← extChartAt_coe] - -- debug why this is needed! + -- debug why this line is needed! change fderivWithin 𝕜 (↑(extChartAt I x) ∘ ↑φ.symm) (extChartAt I x).target (φ x) = _ have : fderivWithin 𝕜 (φ ∘ φ.symm) (extChartAt I x).target (φ x) = fderivWithin 𝕜 id (extChartAt I x).target (φ x) := fderivWithin_congr' (fun x' hx' ↦ PartialEquiv.right_inv φ hx') (mem_extChartAt_target x) rw [this] exact fderivWithin_id (uniqueDiffWithinAt_extChartAt_target x) - rw [this] - rw [ContinuousLinearMap.inverse_id] + rw [this, ContinuousLinearMap.inverse_id] exact rfl +variable (x V) in +omit [CompleteSpace E] in lemma aux_computation2 : (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) ((extChartAt I x) x)).inverse (V x) = V x := by @@ -387,8 +389,7 @@ lemma aux_computation2 : · sorry rw [this] exact fderivWithin_id <| I.uniqueDiffOn.uniqueDiffWithinAt (mem_range_self _) - rw [this] - rw [ContinuousLinearMap.inverse_id] + rw [this, ContinuousLinearMap.inverse_id] exact rfl /-- @@ -438,48 +439,20 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA rw [cleanup1, cleanup2] congr 1 · sorry -- is the sorry below + -- This statement is not fully true, but I only need a weaker version... + -- if V' x' is a tangent vector within s, i.e. my aux_computation' should suffice! + -- Make this intuitive hunch rigorous! have : V' x' = V x := by - simp only [V', x'] - --set φ := (extChartAt I x) - simp only [mpullbackWithin] + simp only [V', x', mpullbackWithin] rw [extChartAt_to_inv x] - - - -- is this actually true? not sure! - --have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt_symm - -- V (x := x) (s := Set.univ) - --have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt - -- V (x := x) (s := Set.univ) - symm - sorry - --convert this + exact aux_computation2 x V exact aux_computation x W - - -- · simp only [V'] - -- #check VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt - -- show mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) x' = V x - -- have := VectorField.eventuallyEq_mpullback_mpullbackWithin_extChartAt - -- -- missing lemma! - -- simp only [mpullbackWithin] - -- simp only [mfderivWithin] - -- have : MDifferentiableWithinAt 𝓘(𝕜, E) I (↑(extChartAt I x).symm) (range ↑I) x' := sorry - -- simp only [this, if_true] - -- simp only [pullbackWithin] - -- --simp - - -- simp [mpullbackWithin] - -- ext - -- simp - -- rw? - -- sorry have h2 : mpullback I 𝓘(𝕜, E) (extChartAt I x) B x = f x • mpullback I 𝓘(𝕜, E) (extChartAt I x) (lieBracketWithin 𝕜 V' W' s') x := by simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] -- Adding these identities proves the claim. rw [← Pi.add_def, mpullback_add_apply]; congr -#exit - /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. From 50ca83ae89a05c5d2118a31a053fa075e0f42229 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 23 Aug 2025 12:01:32 +0200 Subject: [PATCH 324/601] Small tweaks: don't understand the last sorry yet --- .../Manifold/VectorField/LieBracket.lean | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 15309beb0e0c1b..b7830ea8381d90 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -330,8 +330,8 @@ lemma aux_computation : variable (x V) in omit [CompleteSpace E] in lemma aux_computation2' : - (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (extChartAt I x).target ((extChartAt I x) x)).inverse (V x) - = V x := by + letI φ := extChartAt I x + (mfderivWithin 𝓘(𝕜, E) I φ.symm φ.target (φ x)).inverse (V x) = V x := by set φ := extChartAt I x set x' := (extChartAt I x) x have : mfderivWithin 𝓘(𝕜, E) I φ.symm φ.target (φ x) = ContinuousLinearMap.id 𝕜 _ := by @@ -360,8 +360,8 @@ lemma aux_computation2' : variable (x V) in omit [CompleteSpace E] in lemma aux_computation2 : - (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) ((extChartAt I x) x)).inverse (V x) - = V x := by + letI φ := extChartAt I x + (mfderivWithin 𝓘(𝕜, E) I φ.symm (range I) (φ x)).inverse (V x) = V x := by set φ := extChartAt I x set x' := (extChartAt I x) x -- this is almost true: it is true within a smaller set (namely extChartAt I x).target... @@ -420,7 +420,7 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA let aux := lieBracketWithin_smul_right (V := V') hf' hW.differentiableWithinAt_mpullbackWithin_vectorField hs - rw [← Pi.smul_def'] + -- rw [← Pi.smul_def'] -- We need the cast, since on the nose `B` is a map `E → E`, -- while we need a map between tangent spaces. let A (x₀) := (fderivWithin 𝕜 f' s' x₀) (V' x₀) • W' x₀ @@ -428,30 +428,26 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun y ↦ A y + B y) x · simp only [mpullback_apply] congr - -- missing lemma; first part of the claim - have h1 : mpullback I 𝓘(𝕜, E) (extChartAt I x) A x - = (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x := by - unfold A - simp [mfderivWithin, hf] - simp [mpullback] - have cleanup1 : I ((chartAt H x) x) = x' := rfl - have cleanup2 : f ∘ (chartAt H x).symm ∘ ↑I.symm = f' := rfl - rw [cleanup1, cleanup2] - congr 1 - · sorry -- is the sorry below - -- This statement is not fully true, but I only need a weaker version... - -- if V' x' is a tangent vector within s, i.e. my aux_computation' should suffice! - -- Make this intuitive hunch rigorous! - have : V' x' = V x := by - simp only [V', x', mpullbackWithin] - rw [extChartAt_to_inv x] - exact aux_computation2 x V - exact aux_computation x W - have h2 : mpullback I 𝓘(𝕜, E) (extChartAt I x) B x - = f x • mpullback I 𝓘(𝕜, E) (extChartAt I x) (lieBracketWithin 𝕜 V' W' s') x := by - simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] - -- Adding these identities proves the claim. - rw [← Pi.add_def, mpullback_add_apply]; congr + -- We prove the equality of each summand separately. + rw [← Pi.add_def, mpullback_add_apply]; congr; swap + · simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] + + -- This part is still TODO/ in progress!! + unfold A + simp [mfderivWithin, hf] + simp [mpullback] + have cleanup1 : I ((chartAt H x) x) = x' := rfl + have cleanup2 : f ∘ (chartAt H x).symm ∘ I.symm = f' := rfl + rw [cleanup1, cleanup2, ← aux_computation x W] + congr -- congr 1 is less strong + -- This statement is not fully true, but I only need a weaker version... + -- if V' x' is a tangent vector within s, i.e. my aux_computation' should suffice! + -- Make this intuition hunch rigorous! + have : V' x' = V x := by + simp only [V', x', mpullbackWithin] + rw [extChartAt_to_inv x] + exact aux_computation2 x V + exact this /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function From 46e84429eaffc10212ba81d3c0b06c027e175ee2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 27 Aug 2025 22:27:18 +0200 Subject: [PATCH 325/601] chore(LeviCivita): polish and documentation Write a paragraph about the defeq abuse in leviCivita_rhs --- .../Manifold/VectorBundle/LeviCivita.lean | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 62aa8111c0f41c..08647c8efd9b1f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -51,6 +51,7 @@ noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := local notation "⟪" X ", " Y "⟫" => product I X Y +-- Basic API for the product of two vector fields. section product omit [IsManifold I ∞ M] @@ -127,12 +128,15 @@ synthesized fun x ↦ instNormedAddCommGroupOfRiemannianBundle x inferred fun b ↦ inst✝⁷ -/ +-- TODO: diagnose and fix this, and replace by `MDifferentiable(At).inner_bundle! + variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in -lemma foo (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := +lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := MDifferentiable.inner_bundle hY hZ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in -lemma fooAt {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : MDiffAt ⟪Y, Z⟫ x := +lemma MDifferentiableAt.inner_bundle' {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + MDiffAt ⟪Y, Z⟫ x := MDifferentiableAt.inner_bundle hY hZ namespace CovariantDerivative @@ -141,19 +145,31 @@ namespace CovariantDerivative -- TODO: include in cheat sheet! variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) --- TODO: make g part of the notation! +/-- Predicate saying for a connection `∇` on a Riemannian manifold `M` to be compatible with the +ambient metric, i.e. for all smooth vector fields `X`, `Y` and `Z` on `M`, we have +`X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ def IsCompatible : Prop := ∀ X Y Z : Π x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! ∀ x : M, mfderiv% ⟪Y, Z⟫ x (X x) = ⟪cov X Y, Z⟫ x + ⟪Y, cov X Z⟫ x --- TODO: make g part of the notation! -/-- A covariant derivative on `TM` is called the **Levi-Civita connection** for a Riemannian metric -`g` on `M` iff it is torsion-free and compatible with `g`. -/ +/-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** +iff it is torsion-free and compatible with `g`. +Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a +version depending on a choice of Riemannian metric on `M`. +-/ def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree --- This is mild defeq abuse, right? variable (X Y Z) in +/-- The first term in the definition of the candidate Levi-Civita connection: +`rhs_aux I X Y Z = X ⟨Y, Z⟩ = x ↦ d(⟨Y, Z⟩)_x (X x)`. + +This definition contains mild defeq abuse, which is invisible on paper: +The function `⟨Y, Z⟩` maps `M` into `ℝ`, hence its differential at a point `x` maps `T_p M` +to an element of the tangent space of `ℝ`. A summand `⟨Y, [X, Z]⟩`, however, yields an honest +real number: Lean complains that these have different types. +Fortunately, `ℝ` is defeq to its own tangent space; casting `rhs_aux` to the real numbers +allows the addition to type-check. -/ noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv% ⟪Y, Z⟫ x (X x)) section rhs_aux @@ -165,20 +181,20 @@ lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by congr exact product_swap I Z Y -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x} - omit [IsManifold I ∞ M] in variable (X X' Y Z) in lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by ext x simp [rhs_aux] +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x} + variable (X) in @[simp] lemma rhs_aux_addY_apply (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X (Y + Y') Z x = rhs_aux I X Y Z x + rhs_aux I X Y' Z x := by simp only [rhs_aux] - rw [product_add_left, mfderiv_add (fooAt hY hZ) (fooAt hY' hZ)] + rw [product_add_left, mfderiv_add (hY.inner_bundle' hZ) (hY'.inner_bundle' hZ)] simp; congr variable (X) in @@ -192,7 +208,7 @@ variable (X) in lemma rhs_aux_addZ_apply (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : rhs_aux I X Y (Z + Z') x = rhs_aux I X Y Z x + rhs_aux I X Y Z' x := by unfold rhs_aux - rw [product_add_right, mfderiv_add (fooAt hY hZ) (fooAt hY hZ')]; simp; congr + rw [product_add_right, mfderiv_add (hY.inner_bundle' hZ) (hY.inner_bundle' hZ')]; simp; congr variable (X) in lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : @@ -211,7 +227,7 @@ lemma rhs_aux_smulY_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : letI A (x) : ℝ := (mfderiv% f x) (X x) rhs_aux I X (f • Y) Z x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by - rw [rhs_aux, product_smul_left, mfderiv_smul (fooAt hY hZ) hf] + rw [rhs_aux, product_smul_left, mfderiv_smul (hY.inner_bundle' hZ) hf] variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : @@ -239,7 +255,6 @@ end rhs_aux variable {x : M} --- XXX: inlining rhs_aux here makes things not typecheck any more! variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If ∇ is a Levi-Civita connection on `TM`, then From c68be46b890369c1c651dbace46f42dbaac3e31b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 27 Aug 2025 22:38:30 +0200 Subject: [PATCH 326/601] chore: cherry-pick #print sorries command from #25179 --- Mathlib.lean | 1 + .../Manifold/VectorBundle/LeviCivita.lean | 1 + Mathlib/Util/PrintSorries.lean | 161 ++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 Mathlib/Util/PrintSorries.lean diff --git a/Mathlib.lean b/Mathlib.lean index 5e8a0678c547aa..ffcf1e9e0e8bee 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6665,6 +6665,7 @@ import Mathlib.Util.MemoFix import Mathlib.Util.Notation3 import Mathlib.Util.PPOptions import Mathlib.Util.ParseCommand +import Mathlib.Util.PrintSorries import Mathlib.Util.Qq import Mathlib.Util.Simp import Mathlib.Util.SleepHeartbeats diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 08647c8efd9b1f..79a79176143d8a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -7,6 +7,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +import Mathlib.Util.PrintSorries /-! # The Levi-Civita connection diff --git a/Mathlib/Util/PrintSorries.lean b/Mathlib/Util/PrintSorries.lean new file mode 100644 index 00000000000000..895c213bc65624 --- /dev/null +++ b/Mathlib/Util/PrintSorries.lean @@ -0,0 +1,161 @@ +/- +Copyright (c) 2025 Henrik Böving, Yaël Dillies, Kyle Miller. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Henrik Böving, Yaël Dillies, Kyle Miller +-/ +import Mathlib.Lean.Expr.Basic + +/-! +# Tracking uses of `sorry` + +This file provides a `#print sorries` command to help find out why a given declaration is not +sorry-free. `#print sorries foo` returns a non-sorry-free declaration `bar` which `foo` depends on, +if such a `bar` exists. + +The `#print sorries in CMD` combinator prints all sorries appearing in the declarations defined +by the given command. + +## TODO + +* Add configuration options. `#print sorries +positions -types` would print file/line/col + information and not print the types. +* Make versions for other axioms/constants. + The `#print sorries` command itself shouldn't be generalized, since `sorry` is a special concept, + representing unfinished proofs, and it has special support for "go to definition", etc. +* Move to ImportGraph? + +copy-pasted from #25179 +-/ + +open Lean Meta Elab Command + +namespace Mathlib.PrintSorries + +/-- Type of intermediate computation of sorry-tracking. -/ +structure State where + /-- The set of already visited declarations. -/ + visited : NameSet := {} + /-- The set of `sorry` expressions that have been found. + Note that unlabeled sorries will only be reported in the *first* declaration that uses them, + even if a later definition independently has a direct use of `sorryAx`. -/ + sorries : Std.HashSet Expr := {} + /-- The uses of `sorry` that were found. -/ + sorryMsgs : Array MessageData := #[] + +/-- +Collects all uses of `sorry` by the declaration `c`. +It finds all transitive uses as well. + +This is a version of `Lean.CollectAxioms.collect` that keeps track of enough information to print +each use of `sorry`. +-/ +partial def collect (c : Name) : StateT State MetaM Unit := do + let collectExpr (e : Expr) : StateT State MetaM Unit := do + /- + We assume most declarations do not contain sorry. + The `getUsedConstants` function is very efficient compared to `forEachExpr'`, + since `forEachExpr'` needs to instantiate fvars. + Visiting constants first also guarantees that we attribute sorries to the first + declaration that included it. Recall that `sorry` might appear in the type of a theorem, + which leads to the `sorry` appearing directly in any declarations that use it. + This is one reason we need the `State.sorries` set as well. + The other reason is that we match entire sorry applications, + so `forEachExpr'`'s cache won't prevent over-reporting if `sorry` is a function. + -/ + let consts := e.getUsedConstants + consts.forM collect + if consts.contains ``sorryAx then + let visitSorry (e : Expr) : StateT State MetaM Unit := do + unless (← get).sorries.contains e do + let mut msg := m!"{.ofConstName c} has {e}" + if e.isSyntheticSorry then + msg := msg ++ " (from error)" + try + msg := msg ++ " of type" ++ indentExpr (← inferType e) + catch _ => pure () + msg ← addMessageContext msg + modify fun s => + { s with + sorries := s.sorries.insert e + sorryMsgs := s.sorryMsgs.push msg } + Meta.forEachExpr' e fun e => do + if e.isSorry then + if let some _ := isLabeledSorry? e then + visitSorry <| e.getBoundedAppFn (e.getAppNumArgs - 3) + else + visitSorry <| e.getBoundedAppFn (e.getAppNumArgs - 2) + return false + else + -- Otherwise continue visiting subexpressions + return true + let s ← get + unless s.visited.contains c do + modify fun s => { s with visited := s.visited.insert c } + let env ← getEnv + match env.checked.get.find? c with + | some (.axiomInfo v) => collectExpr v.type + | some (.defnInfo v) => collectExpr v.type *> collectExpr v.value + | some (.thmInfo v) => collectExpr v.type *> collectExpr v.value + | some (.opaqueInfo v) => collectExpr v.type *> collectExpr v.value + | some (.quotInfo _) => pure () + | some (.ctorInfo v) => collectExpr v.type + | some (.recInfo v) => collectExpr v.type + | some (.inductInfo v) => collectExpr v.type *> v.ctors.forM collect + | none => pure () + +/-- +Prints all uses of `sorry` inside a list of declarations. +Displayed sorries are hoverable and support "go to definition". +-/ +def collectSorries (constNames : Array Name) : MetaM (Array MessageData) := do + let (_, s) ← (constNames.forM collect).run {} + pure s.sorryMsgs + +/-- +- `#print sorries` prints all sorries that the current module depends on. +- `#print sorries id1 id2 ... idn` prints all sorries that the provided declarations depend on. +- `#print sorries in CMD` prints all the sorries in declarations added by the command. + +Displayed sorries are hoverable and support "go to definition". +-/ +syntax (name := printSorriesStx) "#print " &"sorries" (ppSpace ident)* : command + +/-- +Collects sorries in the given constants and logs a message. +-/ +def evalCollectSorries (names : Array Name) : CommandElabM Unit := do + let msgs ← liftTermElabM <| collectSorries names + if msgs.isEmpty then + logInfo m!"Declarations are sorry-free!" + else + logInfo <| MessageData.joinSep msgs.toList "\n" + +elab_rules : command + | `(#print%$tk1 sorries%$tk2 $idents*) => do + let mut names ← liftCoreM <| idents.flatMapM fun id => + return (← realizeGlobalConstWithInfos id).toArray + if names.isEmpty then + names ← (← getEnv).checked.get.constants.map₂.foldlM (init := #[]) fun acc name _ => + return if ← name.isBlackListed then acc else acc.push name + withRef (mkNullNode #[tk1, tk2]) <| evalCollectSorries names + +@[inherit_doc printSorriesStx] +syntax "#print " &"sorries" " in " command : command + +elab_rules : command + | `(#print%$tk1 sorries%$tk2 in $cmd:command) => do + let oldEnv ← getEnv + try + elabCommand cmd + finally + let newEnv ← getEnv + let names ← newEnv.checked.get.constants.map₂.foldlM (init := #[]) fun acc name _ => do + if oldEnv.constants.map₂.contains name then + return acc + else if ← name.isBlackListed then + return acc + else + return acc.push name + withRef (mkNullNode #[tk1, tk2]) <| evalCollectSorries names + +end Mathlib.PrintSorries From a338d0956dc24251acb15b78467cd8aca7668c29 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 27 Aug 2025 23:15:41 +0200 Subject: [PATCH 327/601] Small polish; golf one proof --- .../Manifold/VectorBundle/LeviCivita.lean | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 79a79176143d8a..897a5ba74b3852 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -259,7 +259,7 @@ variable {x : M} variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If ∇ is a Levi-Civita connection on `TM`, then -`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ +`2 ⟨∇ X Y, Z⟩ = leviCivita_rhs' I X Y Z` for all vector fields `Z`. -/ noncomputable def leviCivita_rhs' : M → ℝ := rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y - ⟪Y ,(VectorField.mlieBracket I X Z)⟫ @@ -268,8 +268,8 @@ noncomputable def leviCivita_rhs' : M → ℝ := variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: -If ∇ is a Levi-Civita connection on `TM`, then -`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all vector fields `Z`. -/ +If `∇` is a Levi-Civita connection on `TM`, then +`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all smooth vector fields `X`, `Y` and `Z`. -/ noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • leviCivita_rhs' I X Y Z omit [IsManifold I ∞ M] in @@ -314,6 +314,8 @@ lemma leviCivita_rhs_addX [CompleteSpace E] ext x simp [leviCivita_rhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] +open VectorField + variable {I} in lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : @@ -323,10 +325,10 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} unfold leviCivita_rhs' simp only [Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption - simp only [product_apply, VectorField.mlieBracket_smul_left (W := Z) hf hX, - VectorField.mlieBracket_smul_left (W := Y) hf hX, inner_add_right] - simp only [← product_apply] - simp only [neg_smul, inner_neg_right] + simp only [product_apply, mlieBracket_smul_left (W := Z) hf hX, + mlieBracket_smul_left (W := Y) hf hX, inner_add_right] + -- Combining this line with the previous one fails. + simp only [← product_apply, neg_smul, inner_neg_right] have h1 : letI dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x); inner ℝ (Y x) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) • X x) = dfZ * ⟪X, Y⟫ x := by @@ -338,30 +340,28 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} simp only [product] rw [← real_inner_smul_left, real_inner_smul_right, real_inner_smul_left] simp only [h1, h2] - clear h1 h2 set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) set dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) - have h4 : ⟪f • X, VectorField.mlieBracket I Z Y⟫ x = - f x * ⟪X, VectorField.mlieBracket I Z Y⟫ x := by + have h3 : ⟪f • X, mlieBracket I Z Y⟫ x = f x * ⟪X, mlieBracket I Z Y⟫ x := by rw [product_apply, Pi.smul_apply', real_inner_smul_left] - have h5 : inner ℝ (Z x) (f x • VectorField.mlieBracket I X Y x) = - f x * ⟪Z, VectorField.mlieBracket I X Y⟫ x := by + have h4 : inner ℝ (Z x) (f x • mlieBracket I X Y x) = f x * ⟪Z, mlieBracket I X Y⟫ x := by rw [product_apply, real_inner_smul_right] - rw [real_inner_smul_right (Y x), h4, h5] - set A := ⟪Y, VectorField.mlieBracket I X Z⟫ - set B := ⟪Z, VectorField.mlieBracket I X Y⟫ - set C := ⟪X, VectorField.mlieBracket I Z Y⟫ - set R := dfZ * ⟪X, Y⟫ x - set R' := dfY * ⟪Z, X⟫ x - set E := rhs_aux I X Y Z x - set F := rhs_aux I Y Z X x - set G := rhs_aux I Z X Y x - calc f x * E + (f x * F + R') - (f x * G + R) - (-R + f x * A x) - (-R' + f x * B x) + f x * C x - _ = (f x * E + f x * F - f x * G - f x * A x - f x * B x + f x * C x) + R' + R' := by - abel - _ = f x * (E + F - G - A x - B x + C x) + R' + R' := by ring - _ = _ := by ac_rfl -#print axioms leviCivita_rhs'_smulX_apply + rw [real_inner_smul_right (Y x), h3, h4] + -- set A := ⟪Y, mlieBracket I X Z⟫ with hA + -- set B := ⟪Z, mlieBracket I X Y⟫ + -- set C := ⟪X, mlieBracket I Z Y⟫ + -- set R := dfZ * ⟪X, Y⟫ x with hR + -- set R' := dfY * ⟪Z, X⟫ x with hR' + -- set E := rhs_aux I X Y Z x + -- set F := rhs_aux I Y Z X x + -- set G := rhs_aux I Z X Y x + -- Push all applications of `x` inwards, then it's indeed obvious. + simp + ring + +-- The term `2 A` is a bit surprising, but seems to be correct: the only sorry is for the +-- product rule of the Lie bracket, which seems correct. + variable {I} in lemma leviCivita_rhs_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : @@ -377,13 +377,14 @@ lemma leviCivita_rhs_smulX_apply [CompleteSpace E] {f : M → ℝ} congr 1 rw [smul_eq_mul]; rw [mul_assoc] --- TODO: need an extra term; how to state this in the nicest way? variable {I} in lemma leviCivita_rhs_smulX [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by + letI dfY (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + letI A (x) := dfY x * ⟪Z, X⟫ x + leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z + A := by ext x - sorry -- exact leviCivita_rhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) + exact leviCivita_rhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) lemma leviCivita_rhs'_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) From 202a60533be50df90c0408e42c5717a4291bffec Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 27 Aug 2025 23:16:20 +0200 Subject: [PATCH 328/601] wip: proving leviCivita_rhs_smulZ sorry Add the same helper lemmas as before... still need think harder! --- .../Manifold/VectorBundle/LeviCivita.lean | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 897a5ba74b3852..1d9576453a55e3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -442,6 +442,52 @@ lemma leviCivita_rhs_addZ [CompleteSpace E] ext x exact leviCivita_rhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) +lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivita_rhs' I X Y (f • Z) x = f x • leviCivita_rhs' I X Y Z x := by + simp only [leviCivita_rhs'] + simp [rhs_aux_smulX] + rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] + beta_reduce + have h1 : VectorField.mlieBracket I X (f • Z) x = + f x • VectorField.mlieBracket I X Z x + mfderiv% f x (X x) • Z x := by + rw [VectorField.mlieBracket_smul_right hf hZ, add_comm] + have h2 : VectorField.mlieBracket I (f • Z) Y x = + -(mfderiv% f x (Y x)) • Z x + f x • VectorField.mlieBracket I Z Y x := by + rw [VectorField.mlieBracket_smul_left hf hZ] + --rw [h1, h2]; beta_reduce + --simp only [smul_eq_mul, product_add_right_apply] + set A := rhs_aux I X Y Z x + set B := rhs_aux I Y Z X x + set C := rhs_aux I Z X Y x + -- continue here! + sorry + -- simp_rw [product_apply] + -- set D' := (mfderiv% f x) (X x) + -- set D := (fun x ↦ (mfderiv% f x) (X x)) • Z + + -- --rw [product_add_right, product_add_right] + -- -- These are all science fiction, and not fully true! + -- rw [product_smul_left, product_smul_right, product_smul_right] + -- set E := ⟪Z, VectorField.mlieBracket I X Y⟫ + -- set F := ⟪Y, VectorField.mlieBracket I X Z⟫ + -- set G := ⟪X, VectorField.mlieBracket I Z Y⟫ + -- -- apart from science fiction mistakes, this is "an easy computation" + -- simp; abel_nf + -- sorry + +lemma leviCivita_rhs'_smulZ [CompleteSpace E] {f : M → ℝ} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivita_rhs' I X Y (f • Z) = f • leviCivita_rhs' I X Y Z := by + ext x + exact leviCivita_rhs'_smulZ_apply I (hf x) (hX x) (hY x) (hZ x) + +lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by + simp only [leviCivita_rhs] + rw [smul_comm, leviCivita_rhs'_smulZ I hf hX hY hZ] +/- old proof attempt was: lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ : MDiff (T% Z)) : leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs, leviCivita_rhs'] @@ -472,7 +518,7 @@ lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ set G := ⟪X, VectorField.mlieBracket I Z Y⟫ -- apart from science fiction mistakes, this is "an easy computation" simp; abel_nf - sorry + sorry -/ end leviCivita_rhs From 920aecf013ca531013dc3cec5550e9578b47628b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 28 Aug 2025 23:50:42 +0200 Subject: [PATCH 329/601] Uniqueness of Levi-Civita is sorry-free: I had a typo, which might explain the extra terms. Need to fix a few proofs, though. --- .../Manifold/VectorBundle/LeviCivita.lean | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 1d9576453a55e3..ad39ab5aa34bc8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -263,7 +263,7 @@ If ∇ is a Levi-Civita connection on `TM`, then noncomputable def leviCivita_rhs' : M → ℝ := rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y - ⟪Y ,(VectorField.mlieBracket I X Z)⟫ - - ⟪Z, (VectorField.mlieBracket I X Y)⟫ + - ⟪Z, (VectorField.mlieBracket I Y X)⟫ + ⟪X, (VectorField.mlieBracket I Z Y)⟫ variable (X Y Z) in @@ -533,9 +533,7 @@ lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = lemma isolate_aux {α : Type*} [AddCommGroup α] (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : A + A = X + Y - Z - D - E + F := by - trans (X + Y - Z) - D - E + F - · rw [h]; abel - · abel + rw [h]; abel variable (X Y Z) in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term @@ -554,16 +552,15 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : simp only [aux I Y Z X cov h, A, C, E, product_swap _ (cov X Y) Z] have eq3 : rhs_aux I Z X Y = B + C + F := by simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] - -- add (I) and (II), subtract (III) + -- Add eq1 and eq2 and subtract eq3. have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by rw [eq1, eq2, eq3]; abel - - -- solve for ⟪cov X Y, Z⟫ and obtain the claim - simp only [leviCivita_rhs] -- - D - E + F - ext x + -- Solve for ⟪cov X Y, Z⟫ and obtain the claim. have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) (by simp [this]) - sorry -- obvious: if A + A = stuff, A = 1/2 stuff + have almoster : A + A = leviCivita_rhs' I X Y Z := by simp only [leviCivita_rhs', *] + simp only [leviCivita_rhs, ← almoster, smul_add] + ext; simp; ring section From fc56818e1e7a6d89c18be80b3511c5c9630e661a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 28 Aug 2025 23:58:48 +0200 Subject: [PATCH 330/601] Fix two proofs --- Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index ad39ab5aa34bc8..af4d81af3209d1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -289,7 +289,7 @@ lemma leviCivita_rhs'_addX_apply [CompleteSpace E] simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. - simp_rw [product_apply, VectorField.mlieBracket_add_left (W := Y) hX hX', + simp_rw [product_apply, VectorField.mlieBracket_add_right (V := Y) hX hX', VectorField.mlieBracket_add_left (W := Z) hX hX', inner_add_right, ← product_apply, product_add_left_apply] rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption @@ -344,7 +344,7 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} set dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) have h3 : ⟪f • X, mlieBracket I Z Y⟫ x = f x * ⟪X, mlieBracket I Z Y⟫ x := by rw [product_apply, Pi.smul_apply', real_inner_smul_left] - have h4 : inner ℝ (Z x) (f x • mlieBracket I X Y x) = f x * ⟪Z, mlieBracket I X Y⟫ x := by + have h4 : inner ℝ (Z x) (f x • mlieBracket I Y X x) = f x * ⟪Z, mlieBracket I Y X⟫ x := by rw [product_apply, real_inner_smul_right] rw [real_inner_smul_right (Y x), h3, h4] -- set A := ⟪Y, mlieBracket I X Z⟫ with hA @@ -395,8 +395,10 @@ lemma leviCivita_rhs'_addY_apply [CompleteSpace E] -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. simp only [product_apply] - simp only [Pi.add_apply, VectorField.mlieBracket_add_right (V := X) hY hY', + simp only [Pi.add_apply, mlieBracket_add_left (W := X) hY hY', VectorField.mlieBracket_add_right (V := Z) hY hY', inner_add_right, ← product_apply] + have : mlieBracket I (Y + Y') X x = mlieBracket I (Y) X x + mlieBracket I Y' X x := by + exact mlieBracket_add_left (W := X) hY hY' abel lemma leviCivita_rhs_addY_apply [CompleteSpace E] @@ -562,6 +564,8 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : simp only [leviCivita_rhs, ← almoster, smul_add] ext; simp; ring +#exit + section attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder From 4533be277117da563f2e6bb923445db86841afcd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 29 Aug 2025 00:03:34 +0200 Subject: [PATCH 331/601] Fix the final proof: now, all + 2 A terms disappear again. --- .../Manifold/VectorBundle/LeviCivita.lean | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index af4d81af3209d1..dd69245599300c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -319,14 +319,12 @@ open VectorField variable {I} in lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - letI A := dfY * ⟪Z, X⟫ x - leviCivita_rhs' I (f • X) Y Z x = f x • leviCivita_rhs' I X Y Z x + A + A := by + leviCivita_rhs' I (f • X) Y Z x = f x • leviCivita_rhs' I X Y Z x := by unfold leviCivita_rhs' simp only [Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption simp only [product_apply, mlieBracket_smul_left (W := Z) hf hX, - mlieBracket_smul_left (W := Y) hf hX, inner_add_right] + mlieBracket_smul_right (V := Y) hf hX, inner_add_right] -- Combining this line with the previous one fails. simp only [← product_apply, neg_smul, inner_neg_right] have h1 : @@ -346,7 +344,7 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} rw [product_apply, Pi.smul_apply', real_inner_smul_left] have h4 : inner ℝ (Z x) (f x • mlieBracket I Y X x) = f x * ⟪Z, mlieBracket I Y X⟫ x := by rw [product_apply, real_inner_smul_right] - rw [real_inner_smul_right (Y x), h3, h4] + rw [real_inner_smul_right (Y x), h3]--, h4] -- set A := ⟪Y, mlieBracket I X Z⟫ with hA -- set B := ⟪Z, mlieBracket I X Y⟫ -- set C := ⟪X, mlieBracket I Z Y⟫ @@ -357,32 +355,22 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} -- set G := rhs_aux I Z X Y x -- Push all applications of `x` inwards, then it's indeed obvious. simp - ring - --- The term `2 A` is a bit surprising, but seems to be correct: the only sorry is for the --- product rule of the Lie bracket, which seems correct. + ring_nf + congr variable {I} in lemma leviCivita_rhs_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - letI A := dfY * ⟪Z, X⟫ x - leviCivita_rhs I (f • X) Y Z x = f x • leviCivita_rhs I X Y Z x + A := by + leviCivita_rhs I (f • X) Y Z x = f x • leviCivita_rhs I X Y Z x := by simp only [leviCivita_rhs, one_div, Pi.smul_apply, smul_eq_mul] simp_rw [leviCivita_rhs'_smulX_apply (I := I) hf hX hY hZ] - rw [← mul_assoc, mul_comm (f x), left_distrib, left_distrib] - set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - set A := dfY * ⟪Z, X⟫ x - rw [add_assoc, show 2⁻¹ * A + 2⁻¹ * A = A by ring] - congr 1 - rw [smul_eq_mul]; rw [mul_assoc] + rw [← mul_assoc, mul_comm (f x), smul_eq_mul] + ring variable {I} in lemma leviCivita_rhs_smulX [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI dfY (x) : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - letI A (x) := dfY x * ⟪Z, X⟫ x - leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z + A := by + leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by ext x exact leviCivita_rhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) @@ -564,8 +552,6 @@ lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : simp only [leviCivita_rhs, ← almoster, smul_add] ext; simp; ring -#exit - section attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder From e28f01fbbace8e8f01337342e2d52863898857b0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 29 Aug 2025 00:25:18 +0200 Subject: [PATCH 332/601] chore: fix gramSchmidt_contDiffWithinAt I don't understand why the old proof broke, but this fixes it for now --- .../Manifold/VectorBundle/GramSchmidtOrtho.lean | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 5fa6375e7551fe..0220ae4a687cec 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -345,8 +345,14 @@ variable {s : ι → (x : B) → E x} {u : Set B} {x : B} {i : ι} lemma gramSchmidt_contMDiffWithinAt (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) {i : ι} (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by - sorry /- TODO: this simp lemma loops now; not sure why! - simp_rw [VectorBundle.gramSchmidt_def] + -- XXX: this `suffices` used to be just `simp only [VectorBundle.gramSchmidt_def]` + suffices CMDiffAt[u] n (T% (fun x ↦ s i x - ∑ j ∈ Iio i, + (ℝ ∙ VectorBundle.gramSchmidt s j x).starProjection (s i x))) x by + simp_rw [VectorBundle.gramSchmidt] + apply this.congr + · intro x hx + rw [InnerProductSpace.gramSchmidt_def]; simp + · rw [InnerProductSpace.gramSchmidt_def]; simp apply (hs i).sub_section apply ContMDiffWithinAt.sum_section intro i' hi' @@ -359,7 +365,7 @@ lemma gramSchmidt_contMDiffWithinAt (hs : ∀ i, CMDiffAt[u] n (T% (s i)) x) apply ContMDiffWithinAt.orthogonalProjection (gramSchmidt_contMDiffWithinAt hs this) (hs i) apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this termination_by i -decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' -/ +decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' lemma gramSchmidt_contMDiffAt (hs : ∀ i, CMDiffAt n (T% (s i)) x) (hs' : LinearIndependent ℝ ((s · x) ∘ ((↑) : Set.Iic i → ι))) : From 7b656a735d92105cda17fa842a1d8ec7540d4010 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 29 Aug 2025 00:25:40 +0200 Subject: [PATCH 333/601] Uniqueness of the Levi-Civita connection is truly sorry-free! --- .../Manifold/VectorBundle/LeviCivita.lean | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index dd69245599300c..e38d5ca73e4b55 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -565,17 +565,15 @@ vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ lemma congr_of_forall_product [FiniteDimensional ℝ E] (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by by_cases hE : Subsingleton E - · sorry + · ext x + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + apply Subsingleton.allEq _ ext x letI b := Basis.ofVectorSpace ℝ E letI t := trivializationAt E (TangentSpace I : M → Type _) x have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := by - by_contra! - have : IsEmpty ↑(Basis.ofVectorSpaceIndex ℝ E) := not_nonempty_iff.mp this - have : Subsingleton E := by - sorry - apply hE this + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by choose r wo using exists_wellOrder _ exact r @@ -592,10 +590,6 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] have h₂ : ⟪X', real i⟫ x = (hframe.repr i) X' x := by rw [hframe.repr_eq_inner' _ hx] simp [real, real_inner_comm] - -- this would work, except that h is unapplied, but my results are applied... - --simp_rw [hframe'.repr_eq_inner' _ hx] - --specialize h (real i) - --simp [real_inner_comm] rw [← h₁, ← h₂, h (real i)] /-- The Levi-Civita connection on `(M, g)` is uniquely determined, From f2e300ce41189c0b7df7652135df0f824d92329c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 29 Aug 2025 18:46:58 +0200 Subject: [PATCH 334/601] Try the smulZ lemma a bit harder: enough! --- .../Manifold/VectorBundle/LeviCivita.lean | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index e38d5ca73e4b55..c0d8f326faa2e4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -439,17 +439,47 @@ lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} simp [rhs_aux_smulX] rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] beta_reduce + + set A := rhs_aux I X Y Z x + set B := rhs_aux I Y Z X x + set C := rhs_aux I Z X Y x + + -- Apply the product rule for the lie bracket. have h1 : VectorField.mlieBracket I X (f • Z) x = f x • VectorField.mlieBracket I X Z x + mfderiv% f x (X x) • Z x := by rw [VectorField.mlieBracket_smul_right hf hZ, add_comm] have h2 : VectorField.mlieBracket I (f • Z) Y x = -(mfderiv% f x (Y x)) • Z x + f x • VectorField.mlieBracket I Z Y x := by rw [VectorField.mlieBracket_smul_left hf hZ] + -- -- Again, we need to go into the product and back out again. + -- simp only [product_apply] + -- rw [h1, h2, inner_add_right, inner_smul_right_eq_smul] + -- simp only [← product_apply] + + -- Let's try to encapsulate more. + have h1' : ⟪Y, mlieBracket I X (f • Z)⟫ x = + f x • ⟪Y, mlieBracket I X Z⟫ x + ⟪Y, mfderiv% f x (X x) • Z⟫ x := by + rw [product_apply, h1, inner_add_right, inner_smul_right] + congr + rw [h1'] + set D := ⟪Y, mlieBracket I X Z⟫ x + + set X'' := ⟪Y, (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) • Z⟫ x + + + have aux : ⟪f • Z, mlieBracket I Y X⟫ x = f x • ⟪Z, mlieBracket I Y X⟫ x := by + rw [product_smul_left]; simp + + rw [product_smul_left] + --simp_rw [product_smul_left] + + --simp only [product_add_right_apply] + set D := ⟪Y, mlieBracket I X Z⟫ x + set E := ⟪Z, mlieBracket I Y X⟫ x + set F := ⟪X, mlieBracket I Z Y⟫ x --rw [h1, h2]; beta_reduce --simp only [smul_eq_mul, product_add_right_apply] - set A := rhs_aux I X Y Z x - set B := rhs_aux I Y Z X x - set C := rhs_aux I Z X Y x + -- continue here! sorry -- simp_rw [product_apply] @@ -466,6 +496,7 @@ lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} -- simp; abel_nf -- sorry +#exit lemma leviCivita_rhs'_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : leviCivita_rhs' I X Y (f • Z) = f • leviCivita_rhs' I X Y Z := by From 23dd09f3727125df0e8eee30890432931b9d586e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 29 Aug 2025 19:10:31 +0200 Subject: [PATCH 335/601] Some sorries in isCovariantDerivativeOn_lcCandidate_aux --- .../Manifold/VectorBundle/LeviCivita.lean | 80 +++++++++++-------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index c0d8f326faa2e4..dc64e789fef753 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -496,7 +496,6 @@ lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} -- simp; abel_nf -- sorry -#exit lemma leviCivita_rhs'_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : leviCivita_rhs' I X Y (f • Z) = f • leviCivita_rhs' I X Y Z := by @@ -641,12 +640,14 @@ theorem isLeviCivita_uniqueness [FiniteDimensional ℝ E] noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := + open scoped Classical in fun X Y x ↦ + if hE : Subsingleton E then X x else -- Choose a trivialisation of `TM` near `x`. + -- Since `E` is non-trivial, `b` is non-empty. letI b := Basis.ofVectorSpace ℝ E - -- Case distinction: if E is trivial, there is only one choice anyway; - -- otherwise, b must be non-trivial. - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by choose r wo using exists_wellOrder _ exact r @@ -670,61 +671,72 @@ variable (X Y) in -- using e on e.baseSet yields the same result as above. lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) : - lcCandidate I M X Y x = lcCandidate_aux I e X Y x := sorry + lcCandidate I M X Y x = lcCandidate_aux I e X Y x := by + by_cases hE : Subsingleton E + · simp [lcCandidate, lcCandidate_aux, hE] + · simp only [lcCandidate, lcCandidate_aux, hE, ↓reduceDIte] + -- Now, start the real proof. + sorry -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e) e.baseSet where - addX X X' σ x := by + addX X X' σ x hx := by + by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] -- these three sorries seem to be necessary! have hX : MDiffAt (T% X) x := sorry have hX' : MDiffAt (T% X') x := sorry have hσ : MDiffAt (T% σ) x := sorry - intro hx - unfold lcCandidate_aux + simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivita_rhs_addX_apply] <;> try assumption - · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) - have : MDiffAt (T% f) x := -- missing API lemma! - (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) - |>.mdifferentiableAt le_rfl - sorry -- convert this works, except for different local orders... + let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry + set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have : MDiffAt (T% f) x := -- missing API lemma! + (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) + |>.mdifferentiableAt le_rfl + sorry -- convert this works, except for different local orders... smulX X σ g x hx := by - unfold lcCandidate_aux - dsimp + by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] + simp only [lcCandidate_aux, hE, ↓reduceDIte] have hX : MDiff (T% X) := sorry -- might need this (hopefully not!) have hg : MDiff g := sorry -- might need this (hopefully not!) rw [Finset.smul_sum] congr; ext i - sorry -- TODO: fix this once all the smul computations are sorry-free! - --rw [leviCivita_rhs_smulX _ _ _ hg hX] - --simp [← smul_assoc] + rw [leviCivita_rhs_smulX] <;> try assumption + rotate_left + · sorry -- missing hyp! + · sorry -- missing hyp! + simp [← smul_assoc] smul_const_σ X σ a x hx := by - unfold lcCandidate_aux - dsimp + by_cases hE : Subsingleton E; · have : X x = 0 := sorry; simp [lcCandidate_aux, hE, this] + simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i -- want leviCivita_rhs_smulY (with a constant) sorry addσ X σ σ' x hσ hσ' hx := by have hX : MDiffAt (T% X) x := sorry -- missing assumption! - unfold lcCandidate_aux - dsimp - simp [← Finset.sum_add_distrib, ← add_smul] + by_cases hE : Subsingleton E; · have : X x = 0 := sorry; simp [lcCandidate_aux, hE, this] + simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivita_rhs_addY_apply] <;> try assumption - · let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := by sorry - set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) - have : MDiffAt (T% f) x := -- missing API lemma! - (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) - |>.mdifferentiableAt le_rfl - -- mismatch between different orders; the sorry above - convert this <;> sorry - leibniz := by + let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := by sorry + set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have : MDiffAt (T% f) x := -- missing API lemma! + (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) + |>.mdifferentiableAt le_rfl + -- mismatch between different orders; the sorry above + convert this <;> sorry + leibniz X σ g x hσ hg hx := by + by_cases hE : Subsingleton E + · have : X x = 0 := sorry + simp [lcCandidate_aux, hE, this] + simp only [lcCandidate_aux, hE, ↓reduceDIte] sorry -- The candidate definition is a covariant derivative on each local frame's domain. From b5b3d48e11d7478ab424a5a1b52624d4fd214f49 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 00:39:11 +0200 Subject: [PATCH 336/601] My candidate is torsion-free: let's go via the Christoffel symbols. Might be more work, but this work will be worth it medium-term. Start generalising the definition of torsion-freeness to open sets. --- .../VectorBundle/CovariantDerivative.lean | 28 ++++---- .../Manifold/VectorBundle/LeviCivita.lean | 68 ++++++++++++++++++- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 29f872072c7007..5f6705dd33a867 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1120,29 +1120,31 @@ end horiz section torsion namespace CovariantDerivative -variable [h : IsManifold I ∞ M] - --- The torsion tensor of a covariant derivative on the tangent bundle `TM`. -variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} - -variable (cov) in -noncomputable def torsion : +/-- The torsion of a covariant derivative on the tangent bundle `TM` -/ +noncomputable def torsion + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - fun X Y ↦ cov X Y - cov Y X - VectorField.mlieBracket I X Y + fun X Y ↦ f X Y - f Y X - VectorField.mlieBracket I X Y -variable {X X' Y : Π x : M, TangentSpace I x} +variable + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {X X' Y : Π x : M, TangentSpace I x} -variable (X) in -lemma torsion_self : torsion cov X X = 0 := by +variable (f X) in +lemma torsion_self : torsion f X X = 0 := by simp [torsion] variable (X Y) in -lemma torsion_antisymm : torsion cov X Y = - torsion cov Y X := by +lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by simp only [torsion] rw [VectorField.mlieBracket_swap] module -variable (X) in +variable [h : IsManifold I ∞ M] +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} + +variable (f X) in @[simp] lemma torsion_zero : torsion cov 0 X = 0 := by ext x diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index dc64e789fef753..093bd52983bb41 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -767,9 +767,75 @@ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ apply isCovariantDerivativeOn_existence_candidate I _ +/-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` +with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, +this is a function `Γᵢⱼᵏ : M → ℝ`, whose value outside of `U` is meaningless. -/ +noncomputable def christoffelSymbol + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + {U : Set M} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := + hs.repr k (f (s i) (s j)) + +-- Lemma 4.3 in Lee, Chapter 5: first term still missing +variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + +lemma foobar (hf : IsCovariantDerivativeOn E f U) + (hs : IsLocalFrameOn I E 1 s U) (x : M) : + f X Y x = ∑ k, + let S₁ := ∑ i, ∑ j, (hs.repr i X) * (hs.repr j Y) * (christoffelSymbol I f hs i j k) + let S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! + S₁ x • s k x := + -- straightforward computation: write Y = ∑ i, hs.repr i Y and use linearity and Leibniz rule + sorry + +/- TODO: prove some basic properties, such as +- the Christoffel symbols are linear in cov +- if (s_i) is a smooth local frame on U, then cov is smooth on U iff each Christoffel symbol is (?) +- prove a `spec` equality +- deduce: two covariant derivatives are equal iff their Christoffel symbols are equal +-/ + +-- Exercise 4.2(b) in Lee, Chapter 4 +/-- A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U` and +any local coordinate frame, the Christoffel symbols `Γᵢⱼᵏ` are symmetric. + +TODO: figure out the right quantifiers here! +right now, I just have one fixed coordinate frame... will this do?? +-/ +lemma isTorsionFree_iff_christoffelSymbols + (hf : IsCovariantDerivativeOn E f U) {x : M} : + cov.IsTorsionFree ↔ + ∀ x ∈ U, + -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. + -- TODO: does the following do what I want?? + letI cs := christoffelSymbol I f + ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (trivializationAt E _ x)) + ∀ i j k, cs i j k = cs j i k := by + sorry + lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by + -- If `E` is trivial, the Levi-Civita connection is always zero and all proofs are trivial. + by_cases hE : Subsingleton E + · have (y : M) (X : TangentSpace I y) : X = 0 := by + have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) + apply Subsingleton.eq_zero X + refine ⟨?_, ?_⟩ + · intro X Y Z x + simp only [LeviCivitaConnection] + unfold lcCandidate + simp [this] + · simp only [isTorsionFree_def, LeviCivitaConnection] + unfold lcCandidate torsion + ext; simp [this] + simp only [LeviCivitaConnection] + unfold lcCandidate + simp only [lcCandidate_aux, hE, ↓reduceDIte] refine ⟨?_, ?_⟩ - · sorry -- compatible + · intro X Y Z x + dsimp + simp [product_apply] + sorry -- compatible · sorry -- torsion-free end CovariantDerivative From 4b0b15fa2bf0a9c89b56e614c8805ae229ffd1ed Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 09:48:00 +0200 Subject: [PATCH 337/601] chore: generalise torsion-freeness to an open set --- .../VectorBundle/CovariantDerivative.lean | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 5f6705dd33a867..e82b4d208a506c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1232,12 +1232,32 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] · intro σ τ τ' hτ hτ' exact cov.torsion_add_right_apply hτ hτ' +-- TODO: define a torsion tensor of a covariant derivative, +-- and related torsion-freeness to this +-- (That will not work for torsion-freeness on a set, though.) + set_option linter.style.commandStart true +/-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ +noncomputable def IsTorsionFreeOn + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + (U : Set M) : Prop := + ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 + +-- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, +-- so it would apply here as well + variable (cov) in /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ def IsTorsionFree : Prop := torsion cov = 0 +@[simp] +lemma isTorsionFreeOn_univ : IsTorsionFreeOn cov univ ↔ IsTorsionFree cov := by + simp only [IsTorsionFree, IsTorsionFreeOn] + refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩ + ext X Y x + simp [h x] + lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] -- This should be obvious, I'm doing something wrong. From c6fc6e7dcd96ba60c306c8ebc78a417069c0d49a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 10:23:13 +0200 Subject: [PATCH 338/601] Reduce torsion-freeness to local frames: wip --- .../VectorBundle/CovariantDerivative.lean | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index e82b4d208a506c..49fb825e1635e9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1275,6 +1275,62 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ apply congr_fun simp_all [torsion] +-- OTDO: torsion-free iff on open cover! + +variable {n} in +lemma aux1 {ι : Type*} [Fintype ι] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (X Y : (x : M) → TangentSpace I x) : + torsion f X Y x = ∑ i, (hs.repr i) X x • torsion f (s i) Y x := + have hU : U ∈ 𝓝 x := sorry + have aux := hs.repr_spec X hU + have hX : X x = ∑ i, (hs.repr i) X x • s i x := sorry + calc torsion f X Y x + _ = torsion f (fun x ↦ ∑ i, (hs.repr i) X x • s i x) Y x := by + sorry -- tensoriality and [hX] + _ = ∑ i, (torsion f (fun x ↦ (hs.repr i) X x • s i x) Y x) := sorry + _ = ∑ i, (hs.repr i) X x • (torsion f (s i) Y x) := sorry + +variable {n} in +lemma aux2 {ι : Type*} [Fintype ι] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (X Y : (x : M) → TangentSpace I x) : + torsion f X Y x = ∑ i, (hs.repr i) Y x • torsion f X (s i) x := + have hU : U ∈ 𝓝 x := sorry + have aux := hs.repr_spec Y hU + have hY : Y x = ∑ i, (hs.repr i) Y x • s i x := hs.repr_sum_eq Y hx + calc torsion f X Y x + _ = torsion f X (fun x ↦ ∑ i, (hs.repr i) Y x • s i x) x := by + sorry -- tensoriality and [hY] + _ = ∑ i, (torsion f X (fun x ↦ (hs.repr i) Y x • s i x) x) := sorry + _ = ∑ i, (hs.repr i) Y x • (torsion f X (s i) x) := by + congr with i + -- rw [torsion_smul_left_apply] -- generalise this lemma! + sorry + +/-- We can test torsion-freeness on a set using a local frame. -/ +lemma foo {ι : Type*} [Fintype ι] + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) : + IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by + rw [IsTorsionFreeOn] + refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ + intro x hx X Y + rw [aux1 hs hx] + calc + _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • torsion f (s i) (s j) x := by + congr! + rw [aux2 hs hx] + _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • 0 := by + congr! with i _ j _ + exact h i j x hx + _ = 0 := by simp + + +#exit + -- lemma the trivial connection on a normed space is torsion-free -- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry From 118560b799ca6c06d2576a4fb0aba322b82dc2cb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 10:51:48 +0200 Subject: [PATCH 339/601] chore: generalise many torsion lemmas to the local context --- .../VectorBundle/CovariantDerivative.lean | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 49fb825e1635e9..bf1fb3bf022535 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1144,6 +1144,9 @@ variable [h : IsManifold I ∞ M] -- The torsion tensor of a covariant derivative on the tangent bundle `TM`. variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} +variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) + +-- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! variable (f X) in @[simp] lemma torsion_zero : torsion cov 0 X = 0 := by @@ -1157,12 +1160,12 @@ lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_ze set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer variable (Y) in -lemma torsion_add_left_apply [CompleteSpace E] {x : M} - (hX : MDiffAt (T% X) x) - (hX' : MDiffAt (T% X') x) : - torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by - simp [torsion, cov.isCovariantDerivativeOn.addX X X' (x := x)] - rw [cov.isCovariantDerivativeOn.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] +lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] + (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : + torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by + simp [torsion, hf.addX X X' (x := x)] + rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] module variable (Y) in @@ -1170,14 +1173,14 @@ lemma torsion_add_left [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by ext x - exact cov.torsion_add_left_apply _ (hX x) (hX' x) + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) -lemma torsion_add_right_apply [CompleteSpace E] {x : M} +lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : - torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by + torsion f Y (X + X') x = torsion f Y X x + torsion f Y X' x := by rw [torsion_antisymm, Pi.neg_apply, - cov.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] + hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] simp; abel lemma torsion_add_right [CompleteSpace E] @@ -1186,11 +1189,14 @@ lemma torsion_add_right [CompleteSpace E] rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module variable (Y) in -lemma torsion_smul_left_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDiffAt f x) - (hX : MDiffAt (T% X) x) : - torsion cov (f • X) Y x = f x • torsion cov X Y x := by - simp only [torsion, cov.isCovariantDerivativeOn.smulX X Y f, Pi.sub_apply] - rw [cov.isCovariantDerivativeOn.leibniz Y hX hf, VectorField.mlieBracket_smul_left hf hX] +lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] + {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} + (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) + -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below + {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : + torsion F (f • X) Y x = f x • torsion F X Y x := by + simp only [torsion, Pi.sub_apply, hF.smulX X Y f] + rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] simp [bar, smul_sub] abel @@ -1198,20 +1204,22 @@ variable (Y) in lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : torsion cov (f • X) Y = f • torsion cov X Y := by ext x - exact cov.torsion_smul_left_apply _ (hf x) (hX x) + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) variable (X) in -lemma torsion_smul_right_apply [CompleteSpace E] {f : M → ℝ} {x : M} (hf : MDiffAt f x) - (hX : MDiffAt (T% Y) x) : - torsion cov X (f • Y) x = f x • torsion cov X Y x := by - rw [torsion_antisymm, Pi.neg_apply, torsion_smul_left_apply X hf hX, torsion_antisymm X] +lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] + {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} + (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) + {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : + torsion F X (f • Y) x = f x • torsion F X Y x := by + rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] simp variable (X) in lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : torsion cov X (f • Y) = f • torsion cov X Y := by ext x - apply cov.torsion_smul_right_apply _ (hf x) (hY x) + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) (hf x) (hY x) /-- The torsion of a covariant derivative is tensorial: the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ @@ -1224,13 +1232,13 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' · intro f σ τ hf hσ - exact cov.torsion_smul_left_apply _ hf hσ + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) hf hσ · intro σ σ' τ hσ hσ' - exact cov.torsion_add_left_apply _ hσ hσ' + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) hσ hσ' · intros f σ σ' hf hσ' - exact cov.torsion_smul_right_apply _ hf hσ' + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) hf hσ' · intro σ τ τ' hτ hτ' - exact cov.torsion_add_right_apply hτ hτ' + exact cov.isCovariantDerivativeOn.torsion_add_right_apply (by trivial) hτ hτ' -- TODO: define a torsion tensor of a covariant derivative, -- and related torsion-freeness to this From 1f017b00d9a8cf859904adc65d1dc5d251a9ee70 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 11:04:15 +0200 Subject: [PATCH 340/601] Enough computation for now --- .../VectorBundle/CovariantDerivative.lean | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index bf1fb3bf022535..1635b0b4a2411a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1301,9 +1301,10 @@ lemma aux1 {ι : Type*} [Fintype ι] _ = ∑ i, (hs.repr i) X x • (torsion f (s i) Y x) := sorry variable {n} in -lemma aux2 {ι : Type*} [Fintype ι] +lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + {U : Set M} {s : ι → (x : M) → TangentSpace I x} + (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : torsion f X Y x = ∑ i, (hs.repr i) Y x • torsion f X (s i) x := have hU : U ∈ 𝓝 x := sorry @@ -1315,13 +1316,17 @@ lemma aux2 {ι : Type*} [Fintype ι] _ = ∑ i, (torsion f X (fun x ↦ (hs.repr i) Y x • s i x) x) := sorry _ = ∑ i, (hs.repr i) Y x • (torsion f X (s i) x) := by congr with i - -- rw [torsion_smul_left_apply] -- generalise this lemma! - sorry + have hsi : MDiffAt (hs.repr i Y) x := sorry + have hsi' : MDiffAt (T% (s i)) x := sorry + have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.repr i) Y) hx hsi hsi' + rw [← this] + congr /-- We can test torsion-freeness on a set using a local frame. -/ -lemma foo {ι : Type*} [Fintype ι] +lemma foo {ι : Type*} [Fintype ι] [CompleteSpace E] (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) - {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) : + {U : Set M} {s : ι → (x : M) → TangentSpace I x} + (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by rw [IsTorsionFreeOn] refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ @@ -1330,15 +1335,12 @@ lemma foo {ι : Type*} [Fintype ι] calc _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • torsion f (s i) (s j) x := by congr! - rw [aux2 hs hx] + rw [aux2 hf hs hx] _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • 0 := by congr! with i _ j _ exact h i j x hx _ = 0 := by simp - -#exit - -- lemma the trivial connection on a normed space is torsion-free -- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry From 8331761354234ac1c61c3ec9439f37f5a56cc1e4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 11:10:16 +0200 Subject: [PATCH 341/601] wip: generalise Lee's exercise --- .../Manifold/VectorBundle/LeviCivita.lean | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index 093bd52983bb41..e9e2139ac443ab 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -796,6 +796,17 @@ lemma foobar (hf : IsCovariantDerivativeOn E f U) - deduce: two covariant derivatives are equal iff their Christoffel symbols are equal -/ +/-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. +A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, +the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ +lemma isTorsionFree_iff_christoffelSymbols + (hf : IsCovariantDerivativeOn E f U) {U : Set M} + {ι : Type*} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : + cov.IsTorsionFree ↔ + ∀ x ∈ U, ∀ i j k, christoffelSymbol I f hs i j k = christoffelSymbol I f hs j i k := by + sorry + -- Exercise 4.2(b) in Lee, Chapter 4 /-- A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U` and any local coordinate frame, the Christoffel symbols `Γᵢⱼᵏ` are symmetric. @@ -803,8 +814,8 @@ any local coordinate frame, the Christoffel symbols `Γᵢⱼᵏ` are symmetric. TODO: figure out the right quantifiers here! right now, I just have one fixed coordinate frame... will this do?? -/ -lemma isTorsionFree_iff_christoffelSymbols - (hf : IsCovariantDerivativeOn E f U) {x : M} : +lemma isTorsionFree_iff_christoffelSymbols' + (hf : IsCovariantDerivativeOn E f U) : cov.IsTorsionFree ↔ ∀ x ∈ U, -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. @@ -812,6 +823,7 @@ lemma isTorsionFree_iff_christoffelSymbols letI cs := christoffelSymbol I f ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (trivializationAt E _ x)) ∀ i j k, cs i j k = cs j i k := by + -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! sorry lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by From 1f3233fa0e7ac943b3dbf1eed4a77021a8fa80d8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 11:16:31 +0200 Subject: [PATCH 342/601] Reorder lemmas for clarity; better lemma name --- .../VectorBundle/CovariantDerivative.lean | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 1635b0b4a2411a..49960ea6b7b07b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1159,6 +1159,8 @@ lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_ze set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer +section + variable (Y) in lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) @@ -1168,13 +1170,6 @@ lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] module -variable (Y) in -lemma torsion_add_left [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : - torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) - lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : @@ -1183,11 +1178,6 @@ lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] ( hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] simp; abel -lemma torsion_add_right [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : - torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by - rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module - variable (Y) in lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} @@ -1200,12 +1190,6 @@ lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] simp [bar, smul_sub] abel -variable (Y) in -lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : - torsion cov (f • X) Y = f • torsion cov X Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) - variable (X) in lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} @@ -1215,6 +1199,26 @@ lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] simp +end + +variable (Y) in +lemma torsion_add_left [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : + torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) + +lemma torsion_add_right [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : + torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by + rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module + +variable (Y) in +lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : + torsion cov (f • X) Y = f • torsion cov X Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) + variable (X) in lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : torsion cov X (f • Y) = f • torsion cov X Y := by @@ -1323,7 +1327,8 @@ lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] congr /-- We can test torsion-freeness on a set using a local frame. -/ -lemma foo {ι : Type*} [Fintype ι] [CompleteSpace E] +lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame + {ι : Type*} [Fintype ι] [CompleteSpace E] (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : From 326e0f6340d9f60eba0a3715bd16155176bb5e84 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 11:17:37 +0200 Subject: [PATCH 343/601] Mostly prove exercise: missing sorries are more missing API :-) --- .../VectorBundle/CovariantDerivative.lean | 2 +- .../Manifold/VectorBundle/LeviCivita.lean | 33 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean index 49960ea6b7b07b..682a3709b935ba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean @@ -1329,7 +1329,7 @@ lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] /-- We can test torsion-freeness on a set using a local frame. -/ lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame {ι : Type*} [Fintype ι] [CompleteSpace E] - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean index e9e2139ac443ab..7127ab00dd1d94 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean @@ -799,13 +799,28 @@ lemma foobar (hf : IsCovariantDerivativeOn E f U) /-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ -lemma isTorsionFree_iff_christoffelSymbols - (hf : IsCovariantDerivativeOn E f U) {U : Set M} - {ι : Type*} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) +lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fintype ι] + (hf : IsCovariantDerivativeOn E f U) + {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : - cov.IsTorsionFree ↔ - ∀ x ∈ U, ∀ i j k, christoffelSymbol I f hs i j k = christoffelSymbol I f hs j i k := by - sorry + IsTorsionFreeOn f U ↔ + ∀ i j k, ∀ x ∈ U, christoffelSymbol I f hs i j k x = christoffelSymbol I f hs j i k x := by + rw [hf.isTorsionFreeOn_iff_localFrame (n := n) hs] + have (i j : ι) {x} (hx : x ∈ U) : + torsion f (s i) (s j) x = f (s i) (s j) x - f (s j) (s i) x := by + simp [torsion, hs'' i j ⟨x, hx⟩] + peel with i j + refine ⟨?_, ?_⟩ + · intro h k x hx + simp only [christoffelSymbol] + apply hs.repr_congr + specialize h x hx + rw [this i j hx, sub_eq_zero] at h + exact h + · intro h x hx + rw [this i j hx] + -- equal Christoffel symbols means equal function: separate lemma, using frames + sorry -- Exercise 4.2(b) in Lee, Chapter 4 /-- A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U` and @@ -816,7 +831,7 @@ right now, I just have one fixed coordinate frame... will this do?? -/ lemma isTorsionFree_iff_christoffelSymbols' (hf : IsCovariantDerivativeOn E f U) : - cov.IsTorsionFree ↔ + IsTorsionFreeOn f U ↔ ∀ x ∈ U, -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. -- TODO: does the following do what I want?? @@ -845,9 +860,9 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon simp only [lcCandidate_aux, hE, ↓reduceDIte] refine ⟨?_, ?_⟩ · intro X Y Z x - dsimp simp [product_apply] sorry -- compatible - · sorry -- torsion-free + · -- prove this on local base sets, then use `isTorsionFree_iff_christoffelSymbols'` + sorry end CovariantDerivative From 3bc4ec3a19b15b65a8e57aec77c33ffb2d5490d5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 12:04:12 +0200 Subject: [PATCH 344/601] chore: move CovariantDerivative, LeviCivita to a new directory In preparation for splitting out the material about the torsion of a connection. I'm torn whether CovariantDerivative should be under VectorBundle or not. Let's leave it here, we can always move things later! --- Mathlib.lean | 4 ++-- .../Basic.lean} | 0 .../VectorBundle/{ => CovariantDerivative}/LeviCivita.lean | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename Mathlib/Geometry/Manifold/VectorBundle/{CovariantDerivative.lean => CovariantDerivative/Basic.lean} (100%) rename Mathlib/Geometry/Manifold/VectorBundle/{ => CovariantDerivative}/LeviCivita.lean (99%) diff --git a/Mathlib.lean b/Mathlib.lean index ffcf1e9e0e8bee..7ecb845950a13b 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3767,11 +3767,11 @@ import Mathlib.Geometry.Manifold.Sheaf.LocallyRingedSpace import Mathlib.Geometry.Manifold.Sheaf.Smooth import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.VectorBundle.Basic -import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho import Mathlib.Geometry.Manifold.VectorBundle.Hom -import Mathlib.Geometry.Manifold.VectorBundle.LeviCivita import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.Misc diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean similarity index 100% rename from Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative.lean rename to Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean similarity index 99% rename from Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean rename to Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 7127ab00dd1d94..ab473cc78a7302 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -3,7 +3,7 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Riemannian From f483ee36bd473c1a3abbab37b15b61d32e0ee96f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 12:10:43 +0200 Subject: [PATCH 345/601] chore: move declarations about torsion of connections to a new file --- Mathlib.lean | 1 + .../CovariantDerivative/Basic.lean | 245 ---------------- .../CovariantDerivative/LeviCivita.lean | 1 + .../CovariantDerivative/Torsion.lean | 273 ++++++++++++++++++ 4 files changed, 275 insertions(+), 245 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7ecb845950a13b..3bb49f573cc034 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3769,6 +3769,7 @@ import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho import Mathlib.Geometry.Manifold.VectorBundle.Hom diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 682a3709b935ba..284f6813b9e0c4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1117,251 +1117,6 @@ lemma proj_mderiv {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) end CovariantDerivative end horiz -section torsion -namespace CovariantDerivative - -/-- The torsion of a covariant derivative on the tangent bundle `TM` -/ -noncomputable def torsion - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) : - (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - fun X Y ↦ f X Y - f Y X - VectorField.mlieBracket I X Y - -variable - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} - {X X' Y : Π x : M, TangentSpace I x} - -variable (f X) in -lemma torsion_self : torsion f X X = 0 := by - simp [torsion] - -variable (X Y) in -lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by - simp only [torsion] - rw [VectorField.mlieBracket_swap] - module - -variable [h : IsManifold I ∞ M] --- The torsion tensor of a covariant derivative on the tangent bundle `TM`. -variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} - -variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) - --- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! -variable (f X) in -@[simp] -lemma torsion_zero : torsion cov 0 X = 0 := by - ext x - simp [torsion] - -variable (X) in -@[simp] -lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp - -set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer - -section - -variable (Y) in -lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] - (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : - torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by - simp [torsion, hf.addX X X' (x := x)] - rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] - module - -lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) - (hX : MDiffAt (T% X) x) - (hX' : MDiffAt (T% X') x) : - torsion f Y (X + X') x = torsion f Y X x + torsion f Y X' x := by - rw [torsion_antisymm, Pi.neg_apply, - hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] - simp; abel - -variable (Y) in -lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} - (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) - -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below - {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : - torsion F (f • X) Y x = f x • torsion F X Y x := by - simp only [torsion, Pi.sub_apply, hF.smulX X Y f] - rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] - simp [bar, smul_sub] - abel - -variable (X) in -lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} - (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) - {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : - torsion F X (f • Y) x = f x • torsion F X Y x := by - rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] - simp - -end - -variable (Y) in -lemma torsion_add_left [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : - torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) - -lemma torsion_add_right [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : - torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by - rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module - -variable (Y) in -lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : - torsion cov (f • X) Y = f • torsion cov X Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) - -variable (X) in -lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : - torsion cov X (f • Y) = f • torsion cov X Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) (hf x) (hY x) - -/-- The torsion of a covariant derivative is tensorial: -the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ -def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] - [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {X X' Y Y' : Π x : M, TangentSpace I x} {x₀ : M} - (hX : MDiffAt (T% X) x₀) (hX' : MDiffAt (T% X') x₀) - (hY : MDiffAt (T% Y) x₀) (hY' : MDiffAt (T% Y') x₀) - (hXX' : X x₀ = X' x₀) (hYY' : Y x₀ = Y' x₀) : - (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by - apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' - · intro f σ τ hf hσ - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) hf hσ - · intro σ σ' τ hσ hσ' - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) hσ hσ' - · intros f σ σ' hf hσ' - exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) hf hσ' - · intro σ τ τ' hτ hτ' - exact cov.isCovariantDerivativeOn.torsion_add_right_apply (by trivial) hτ hτ' - --- TODO: define a torsion tensor of a covariant derivative, --- and related torsion-freeness to this --- (That will not work for torsion-freeness on a set, though.) - -set_option linter.style.commandStart true - -/-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ -noncomputable def IsTorsionFreeOn - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) - (U : Set M) : Prop := - ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 - --- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, --- so it would apply here as well - -variable (cov) in -/-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ -def IsTorsionFree : Prop := torsion cov = 0 - -@[simp] -lemma isTorsionFreeOn_univ : IsTorsionFreeOn cov univ ↔ IsTorsionFree cov := by - simp only [IsTorsionFree, IsTorsionFreeOn] - refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩ - ext X Y x - simp [h x] - -lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] - --- This should be obvious, I'm doing something wrong. -lemma isTorsionFree_iff : IsTorsionFree cov ↔ - ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by - simp [IsTorsionFree] - constructor - · intro h X Y - have : torsion cov X Y = 0 := by simp [h] - -- XXX: abel, ring, module and grind all fail here - exact eq_of_sub_eq_zero this - · intro h - ext X Y x - specialize h X Y - apply congr_fun - simp_all [torsion] - --- OTDO: torsion-free iff on open cover! - -variable {n} in -lemma aux1 {ι : Type*} [Fintype ι] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) - (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.repr i) X x • torsion f (s i) Y x := - have hU : U ∈ 𝓝 x := sorry - have aux := hs.repr_spec X hU - have hX : X x = ∑ i, (hs.repr i) X x • s i x := sorry - calc torsion f X Y x - _ = torsion f (fun x ↦ ∑ i, (hs.repr i) X x • s i x) Y x := by - sorry -- tensoriality and [hX] - _ = ∑ i, (torsion f (fun x ↦ (hs.repr i) X x • s i x) Y x) := sorry - _ = ∑ i, (hs.repr i) X x • (torsion f (s i) Y x) := sorry - -variable {n} in -lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} - (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) - (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.repr i) Y x • torsion f X (s i) x := - have hU : U ∈ 𝓝 x := sorry - have aux := hs.repr_spec Y hU - have hY : Y x = ∑ i, (hs.repr i) Y x • s i x := hs.repr_sum_eq Y hx - calc torsion f X Y x - _ = torsion f X (fun x ↦ ∑ i, (hs.repr i) Y x • s i x) x := by - sorry -- tensoriality and [hY] - _ = ∑ i, (torsion f X (fun x ↦ (hs.repr i) Y x • s i x) x) := sorry - _ = ∑ i, (hs.repr i) Y x • (torsion f X (s i) x) := by - congr with i - have hsi : MDiffAt (hs.repr i Y) x := sorry - have hsi' : MDiffAt (T% (s i)) x := sorry - have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.repr i) Y) hx hsi hsi' - rw [← this] - congr - -/-- We can test torsion-freeness on a set using a local frame. -/ -lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame - {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} - (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : - IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by - rw [IsTorsionFreeOn] - refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ - intro x hx X Y - rw [aux1 hs hx] - calc - _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • torsion f (s i) (s j) x := by - congr! - rw [aux2 hf hs hx] - _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • 0 := by - congr! with i _ j _ - exact h i j x hx - _ = 0 := by simp - --- lemma the trivial connection on a normed space is torsion-free --- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry - --- lemma: tangent bundle of E is trivial -> there exists a single trivialisation with baseSet univ --- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, --- w.r.t. to this trivialisation --- add lemmas: globalFrame is contMDiff globally - --- proof of above lemma: write sections s and t in the global frame above --- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) --- compute: their Lie bracket is zero --- compute: the other two terms cancel, done - -end CovariantDerivative -end torsion - end real diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ab473cc78a7302..e58b9ef1320629 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.VectorBundle.Riemannian diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean new file mode 100644 index 00000000000000..71726f795a7fcc --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -0,0 +1,273 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic + +/-! +# Torsion of a covariant derivative + +- define torsion of a covariant derivative (and its local version) +- torsion-free ness (local and global version) +- prove: torsion-freeness on `s` can be checked using a local frame on `s` + +TODO: add a more complete doc-string + +-/ + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] + {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] (n : WithTop ℕ∞) {V : M → Type*} + [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + +namespace CovariantDerivative + +/-- The torsion of a covariant derivative on the tangent bundle `TM` -/ +noncomputable def torsion + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) : + (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := + fun X Y ↦ f X Y - f Y X - VectorField.mlieBracket I X Y + +variable + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {X X' Y : Π x : M, TangentSpace I x} + +variable (f X) in +lemma torsion_self : torsion f X X = 0 := by + simp [torsion] + +variable (X Y) in +lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by + simp only [torsion] + rw [VectorField.mlieBracket_swap] + module + +variable [h : IsManifold I ∞ M] +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} + +variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) + +-- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! +variable (f X) in +@[simp] +lemma torsion_zero : torsion cov 0 X = 0 := by + ext x + simp [torsion] + +variable (X) in +@[simp] +lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp + +set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer + +section + +variable (Y) in +lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] + (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : + torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by + simp [torsion, hf.addX X X' (x := x)] + rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] + module + +lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) + (hX : MDiffAt (T% X) x) + (hX' : MDiffAt (T% X') x) : + torsion f Y (X + X') x = torsion f Y X x + torsion f Y X' x := by + rw [torsion_antisymm, Pi.neg_apply, + hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] + simp; abel + +variable (Y) in +lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] + {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} + (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) + -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below + {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : + torsion F (f • X) Y x = f x • torsion F X Y x := by + simp only [torsion, Pi.sub_apply, hF.smulX X Y f] + rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] + simp [bar, smul_sub] + abel + +variable (X) in +lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] + {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} + (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) + {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : + torsion F X (f • Y) x = f x • torsion F X Y x := by + rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] + simp + +end + +variable (Y) in +lemma torsion_add_left [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : + torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) + +lemma torsion_add_right [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : + torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by + rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module + +variable (Y) in +lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : + torsion cov (f • X) Y = f • torsion cov X Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) + +variable (X) in +lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : + torsion cov X (f • Y) = f • torsion cov X Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) (hf x) (hY x) + +/-- The torsion of a covariant derivative is tensorial: +the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ +def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {X X' Y Y' : Π x : M, TangentSpace I x} {x₀ : M} + (hX : MDiffAt (T% X) x₀) (hX' : MDiffAt (T% X') x₀) + (hY : MDiffAt (T% Y) x₀) (hY' : MDiffAt (T% Y') x₀) + (hXX' : X x₀ = X' x₀) (hYY' : Y x₀ = Y' x₀) : + (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by + apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' + · intro f σ τ hf hσ + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) hf hσ + · intro σ σ' τ hσ hσ' + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) hσ hσ' + · intros f σ σ' hf hσ' + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) hf hσ' + · intro σ τ τ' hτ hτ' + exact cov.isCovariantDerivativeOn.torsion_add_right_apply (by trivial) hτ hτ' + +-- TODO: define a torsion tensor of a covariant derivative, +-- and related torsion-freeness to this +-- (That will not work for torsion-freeness on a set, though.) + +set_option linter.style.commandStart true + +/-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ +noncomputable def IsTorsionFreeOn + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + (U : Set M) : Prop := + ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 + +-- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, +-- so it would apply here as well + +variable (cov) in +/-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ +def IsTorsionFree : Prop := torsion cov = 0 + +@[simp] +lemma isTorsionFreeOn_univ : IsTorsionFreeOn cov univ ↔ IsTorsionFree cov := by + simp only [IsTorsionFree, IsTorsionFreeOn] + refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩ + ext X Y x + simp [h x] + +lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] + +-- This should be obvious, I'm doing something wrong. +lemma isTorsionFree_iff : IsTorsionFree cov ↔ + ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by + simp [IsTorsionFree] + constructor + · intro h X Y + have : torsion cov X Y = 0 := by simp [h] + -- XXX: abel, ring, module and grind all fail here + exact eq_of_sub_eq_zero this + · intro h + ext X Y x + specialize h X Y + apply congr_fun + simp_all [torsion] + +-- OTDO: torsion-free iff on open cover! + +variable {n} in +lemma aux1 {ι : Type*} [Fintype ι] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (X Y : (x : M) → TangentSpace I x) : + torsion f X Y x = ∑ i, (hs.repr i) X x • torsion f (s i) Y x := + have hU : U ∈ 𝓝 x := sorry + have aux := hs.repr_spec X hU + have hX : X x = ∑ i, (hs.repr i) X x • s i x := sorry + calc torsion f X Y x + _ = torsion f (fun x ↦ ∑ i, (hs.repr i) X x • s i x) Y x := by + sorry -- tensoriality and [hX] + _ = ∑ i, (torsion f (fun x ↦ (hs.repr i) X x • s i x) Y x) := sorry + _ = ∑ i, (hs.repr i) X x • (torsion f (s i) Y x) := sorry + +variable {n} in +lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} + (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (X Y : (x : M) → TangentSpace I x) : + torsion f X Y x = ∑ i, (hs.repr i) Y x • torsion f X (s i) x := + have hU : U ∈ 𝓝 x := sorry + have aux := hs.repr_spec Y hU + have hY : Y x = ∑ i, (hs.repr i) Y x • s i x := hs.repr_sum_eq Y hx + calc torsion f X Y x + _ = torsion f X (fun x ↦ ∑ i, (hs.repr i) Y x • s i x) x := by + sorry -- tensoriality and [hY] + _ = ∑ i, (torsion f X (fun x ↦ (hs.repr i) Y x • s i x) x) := sorry + _ = ∑ i, (hs.repr i) Y x • (torsion f X (s i) x) := by + congr with i + have hsi : MDiffAt (hs.repr i Y) x := sorry + have hsi' : MDiffAt (T% (s i)) x := sorry + have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.repr i) Y) hx hsi hsi' + rw [← this] + congr + +/-- We can test torsion-freeness on a set using a local frame. -/ +lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame + {ι : Type*} [Fintype ι] [CompleteSpace E] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} + (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : + IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by + rw [IsTorsionFreeOn] + refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ + intro x hx X Y + rw [aux1 hs hx] + calc + _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • torsion f (s i) (s j) x := by + congr! + rw [aux2 hf hs hx] + _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • 0 := by + congr! with i _ j _ + exact h i j x hx + _ = 0 := by simp + +-- lemma the trivial connection on a normed space is torsion-free +-- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry + +-- lemma: tangent bundle of E is trivial -> there exists a single trivialisation with baseSet univ +-- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, +-- w.r.t. to this trivialisation +-- add lemmas: globalFrame is contMDiff globally + +-- proof of above lemma: write sections s and t in the global frame above +-- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) +-- compute: their Lie bracket is zero +-- compute: the other two terms cancel, done + +end CovariantDerivative From bf98bba1b9083e975b5a1a47dde836e9016c9456 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 12:17:11 +0200 Subject: [PATCH 346/601] Clean up: move local results up --- .../CovariantDerivative/Torsion.lean | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 71726f795a7fcc..73b4776f6afd31 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -21,18 +21,15 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] (n : WithTop ℕ∞) {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] -namespace CovariantDerivative - +-- TODO: where is a good namespace for this? /-- The torsion of a covariant derivative on the tangent bundle `TM` -/ -noncomputable def torsion +noncomputable def Bundle.torsion (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := fun X Y ↦ f X Y - f Y X - VectorField.mlieBracket I X Y @@ -51,29 +48,15 @@ lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by rw [VectorField.mlieBracket_swap] module -variable [h : IsManifold I ∞ M] --- The torsion tensor of a covariant derivative on the tangent bundle `TM`. -variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} - -variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) - --- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! -variable (f X) in -@[simp] -lemma torsion_zero : torsion cov 0 X = 0 := by - ext x - simp [torsion] - -variable (X) in -@[simp] -lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp - set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer -section +namespace IsCovariantDerivativeOn + +variable [h : IsManifold I ∞ M] +variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) variable (Y) in -lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] +lemma torsion_add_left_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by @@ -81,7 +64,7 @@ lemma _root_.IsCovariantDerivativeOn.torsion_add_left_apply [CompleteSpace E] rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] module -lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) +lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : torsion f Y (X + X') x = torsion f Y X x + torsion f Y X' x := by @@ -90,7 +73,7 @@ lemma _root_.IsCovariantDerivativeOn.torsion_add_right_apply [CompleteSpace E] ( simp; abel variable (Y) in -lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] +lemma torsion_smul_left_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below @@ -102,7 +85,7 @@ lemma _root_.IsCovariantDerivativeOn.torsion_smul_left_apply [CompleteSpace E] abel variable (X) in -lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] +lemma torsion_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : @@ -110,7 +93,32 @@ lemma _root_.IsCovariantDerivativeOn.torsion_smul_right_apply [CompleteSpace E] rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] simp -end +/-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ +noncomputable def IsTorsionFreeOn + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + (U : Set M) : Prop := + ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 + +end IsCovariantDerivativeOn + +namespace CovariantDerivative + +variable [h : IsManifold I ∞ M] +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} + +variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) + +-- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! +variable (f X) in +@[simp] +lemma torsion_zero : torsion cov 0 X = 0 := by + ext x + simp [torsion] + +variable (X) in +@[simp] +lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp variable (Y) in lemma torsion_add_left [CompleteSpace E] @@ -161,12 +169,6 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] set_option linter.style.commandStart true -/-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ -noncomputable def IsTorsionFreeOn - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) - (U : Set M) : Prop := - ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 - -- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, -- so it would apply here as well From 76533819154eba5b262118296d8cf91758e8e944 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 12:35:27 +0200 Subject: [PATCH 347/601] chore: congruence and iUnion lemmas for IsTorsionFreeOn --- .../CovariantDerivative/Torsion.lean | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 73b4776f6afd31..a92222059dce23 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -35,7 +35,7 @@ noncomputable def Bundle.torsion fun X Y ↦ f X Y - f Y X - VectorField.mlieBracket I X Y variable - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} {X X' Y : Π x : M, TangentSpace I x} variable (f X) in @@ -93,13 +93,48 @@ lemma torsion_smul_right_apply [CompleteSpace E] rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] simp +end IsCovariantDerivativeOn + /-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ noncomputable def IsTorsionFreeOn (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) (U : Set M) : Prop := ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 -end IsCovariantDerivativeOn +namespace IsTorsionFreeOn + +section changing_set + +/-! Changing set +In this changing we change `s` in `IsTorsionFreeOn F f s`. +-/ + +lemma mono {s t : Set M} (hf : IsTorsionFreeOn f t) (hst : s ⊆ t) : IsTorsionFreeOn f s := + fun _ hx _ _ ↦ hf _ (hst hx) .. + +lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn f (s i)) : + IsTorsionFreeOn f (⋃ i, s i) := by + rintro x ⟨si, ⟨i, hi⟩, hxsi⟩ X Y + exact hf i x (by simp [hi, hxsi]) X Y + +end changing_set + +/- Congruence properties -/ +section + +-- unused? +lemma congr {s : Set M} (h : IsTorsionFreeOn f s) + (hfg : ∀ {X Y : Π x : M, TangentSpace I x}, ∀ {x}, x ∈ s → f X Y x = g X Y x) : + IsTorsionFreeOn g s := by + intro x hx X Y + specialize h x hx X Y + -- now, use torsion congruence lemma, i.e. tensoriality of sorts! + -- TODO: generalise tensoriality to the local setting! + sorry + +end + +end IsTorsionFreeOn namespace CovariantDerivative @@ -183,6 +218,14 @@ lemma isTorsionFreeOn_univ : IsTorsionFreeOn cov univ ↔ IsTorsionFree cov := b ext X Y x simp [h x] +/-- If a covariant derivative `cov` is torsion-free on each set in an open cover, +it is torsion-free. -/ +def of_isTorsionFreeOn_of_open_cover {ι : Type*} {s : ι → Set M} + (hf : ∀ i, IsTorsionFreeOn cov (s i)) (hs : ⋃ i, s i = Set.univ) : + IsTorsionFree cov := by + rw [← isTorsionFreeOn_univ, ← hs] + exact IsTorsionFreeOn.iUnion hf + lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] -- This should be obvious, I'm doing something wrong. @@ -200,8 +243,6 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ apply congr_fun simp_all [torsion] --- OTDO: torsion-free iff on open cover! - variable {n} in lemma aux1 {ι : Type*} [Fintype ι] {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} From 4ce05124ac0c0a487d5d9a8cb365a09529910875 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 12:53:10 +0200 Subject: [PATCH 348/601] All hooked up well: enough for today! --- .../CovariantDerivative/LeviCivita.lean | 22 ++++++++++++++----- .../CovariantDerivative/Torsion.lean | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e58b9ef1320629..5c02fa58bdd0ec 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -856,14 +856,24 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon · simp only [isTorsionFree_def, LeviCivitaConnection] unfold lcCandidate torsion ext; simp [this] - simp only [LeviCivitaConnection] - unfold lcCandidate - simp only [lcCandidate_aux, hE, ↓reduceDIte] + --simp only [LeviCivitaConnection] + --unfold lcCandidate + --simp only [lcCandidate_aux, hE, ↓reduceDIte] refine ⟨?_, ?_⟩ - · intro X Y Z x - simp [product_apply] + · --intro X Y Z x + --simp [product_apply] sorry -- compatible - · -- prove this on local base sets, then use `isTorsionFree_iff_christoffelSymbols'` + · let s : M → Set M := fun x ↦ (trivializationAt E (fun (x : M) ↦ TangentSpace I x) x).baseSet + apply (LeviCivitaConnection I M).of_isTorsionFreeOn_of_open_cover (s := s) + swap; · sorry + intro x + simp only [s] + set t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x with t_eq + change IsTorsionFreeOn (LeviCivitaConnection I M) (t x).baseSet + have : IsCovariantDerivativeOn E (LeviCivitaConnection I M) (t x).baseSet := sorry -- shown above + rw [isTorsionFree_iff_christoffelSymbols' _ this] + intro x' hx' i j k + -- Now, compute christoffel symbols and be happy. sorry end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index a92222059dce23..c78e5fb1fc8a8b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -228,7 +228,7 @@ def of_isTorsionFreeOn_of_open_cover {ι : Type*} {s : ι → Set M} lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] --- This should be obvious, I'm doing something wrong. +-- This should be obvious; am I doing something wrong? lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by simp [IsTorsionFree] From 449424069adbc61b77f790de7a46b10605d9bfd4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 13:33:39 +0200 Subject: [PATCH 349/601] Extract Christoffel symbol computation I need --- .../CovariantDerivative/LeviCivita.lean | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 5c02fa58bdd0ec..a983fa060f68d6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -741,7 +741,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] sorry -- The candidate definition is a covariant derivative on each local frame's domain. -lemma isCovariantDerivativeOn_existence_candidate [FiniteDimensional ℝ E] +lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (lcCandidate I M) e.baseSet := by apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidate_aux I e) @@ -766,7 +766,7 @@ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : rw [← iUnion_source_chartAt H M] let t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ - apply isCovariantDerivativeOn_existence_candidate I _ + exact isCovariantDerivativeOn_lcCandidate I _ /-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, @@ -838,10 +838,18 @@ lemma isTorsionFree_iff_christoffelSymbols' -- TODO: does the following do what I want?? letI cs := christoffelSymbol I f ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (trivializationAt E _ x)) - ∀ i j k, cs i j k = cs j i k := by + ∀ i j k, cs i j k x = cs j i k x := by -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! sorry +theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x : M) : + letI t := trivializationAt E (TangentSpace I) x; + letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t + ∀ {x'}, x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), + christoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = + christoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by + sorry + lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by -- If `E` is trivial, the Levi-Civita connection is always zero and all proofs are trivial. by_cases hE : Subsingleton E @@ -864,16 +872,17 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon --simp [product_apply] sorry -- compatible · let s : M → Set M := fun x ↦ (trivializationAt E (fun (x : M) ↦ TangentSpace I x) x).baseSet - apply (LeviCivitaConnection I M).of_isTorsionFreeOn_of_open_cover (s := s) - swap; · sorry + apply (LeviCivitaConnection I M).of_isTorsionFreeOn_of_open_cover (s := s) ?_ (by aesop) intro x simp only [s] set t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x with t_eq - change IsTorsionFreeOn (LeviCivitaConnection I M) (t x).baseSet - have : IsCovariantDerivativeOn E (LeviCivitaConnection I M) (t x).baseSet := sorry -- shown above + --change IsTorsionFreeOn (LeviCivitaConnection I M) (t x).baseSet + have : IsCovariantDerivativeOn E (LeviCivitaConnection I M) (t x).baseSet := + isCovariantDerivativeOn_lcCandidate _ (t x) rw [isTorsionFree_iff_christoffelSymbols' _ this] intro x' hx' i j k -- Now, compute christoffel symbols and be happy. - sorry + have := LeviCivitaConnection.christoffelSymbol_symm I x hx' i j k + sorry -- almost there, except x vs x' convert this end CovariantDerivative From dd2775319e03a8c8f64731f9dd61a43a82de6663 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 13:48:17 +0200 Subject: [PATCH 350/601] Small clean-up, a missing simp lemma --- .../CovariantDerivative/LeviCivita.lean | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index a983fa060f68d6..a380d2851a795c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -768,6 +768,11 @@ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ exact isCovariantDerivativeOn_lcCandidate I _ +section + +omit [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] +omit [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + /-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, this is a function `Γᵢⱼᵏ : M → ℝ`, whose value outside of `U` is meaningless. -/ @@ -777,6 +782,18 @@ noncomputable def christoffelSymbol (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := hs.repr k (f (s i) (s j)) + +lemma christoffelSymbol_zero (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ι) : christoffelSymbol I 0 hs i j k = 0 := by + simp [christoffelSymbol] + +@[simp] +lemma christoffelSymbol_zero_apply (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ι) (x) : christoffelSymbol I 0 hs i j k x = 0 := by + simp [christoffelSymbol_zero] + +end + -- Lemma 4.3 in Lee, Chapter 5: first term still missing variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} @@ -848,6 +865,21 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x ∀ {x'}, x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), christoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = christoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by + by_cases hE : Subsingleton E + · have (y : M) (X : TangentSpace I y) : X = 0 := by + have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) + apply Subsingleton.eq_zero X + have (X : Π y : M, TangentSpace I y) : X = 0 := sorry + intro hx'' + intro i j k + simp only [LeviCivitaConnection] + unfold lcCandidate + simp only [lcCandidate_aux, hE, ↓reduceDIte] + + letI t := trivializationAt E (TangentSpace I) x; + letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t + have : christoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k + sorry -- this should do it! sorry lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by @@ -864,11 +896,10 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon · simp only [isTorsionFree_def, LeviCivitaConnection] unfold lcCandidate torsion ext; simp [this] - --simp only [LeviCivitaConnection] - --unfold lcCandidate - --simp only [lcCandidate_aux, hE, ↓reduceDIte] refine ⟨?_, ?_⟩ - · --intro X Y Z x + · intro X Y Z x + unfold LeviCivitaConnection lcCandidate + simp only [lcCandidate_aux, hE, ↓reduceDIte] --simp [product_apply] sorry -- compatible · let s : M → Set M := fun x ↦ (trivializationAt E (fun (x : M) ↦ TangentSpace I x) x).baseSet @@ -876,7 +907,6 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon intro x simp only [s] set t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x with t_eq - --change IsTorsionFreeOn (LeviCivitaConnection I M) (t x).baseSet have : IsCovariantDerivativeOn E (LeviCivitaConnection I M) (t x).baseSet := isCovariantDerivativeOn_lcCandidate _ (t x) rw [isTorsionFree_iff_christoffelSymbols' _ this] From 09514b12fde326242923c36a2bfec6503624441d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 23:21:51 +0200 Subject: [PATCH 351/601] Minor tweaks --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 10 ++++++++-- .../VectorBundle/CovariantDerivative/Torsion.lean | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index a380d2851a795c..15f1786ff18cef 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -847,7 +847,7 @@ any local coordinate frame, the Christoffel symbols `Γᵢⱼᵏ` are symmetric. TODO: figure out the right quantifiers here! right now, I just have one fixed coordinate frame... will this do?? -/ -lemma isTorsionFree_iff_christoffelSymbols' +lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional ℝ E] [IsManifold I ∞ M] (hf : IsCovariantDerivativeOn E f U) : IsTorsionFreeOn f U ↔ ∀ x ∈ U, @@ -856,8 +856,14 @@ lemma isTorsionFree_iff_christoffelSymbols' letI cs := christoffelSymbol I f ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (trivializationAt E _ x)) ∀ i j k, cs i j k x = cs j i k x := by + letI t := (trivializationAt E (fun (x : M) ↦ TangentSpace I x)) + have hs (x) := + ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (t x)) + -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! - sorry + rw [isTorsionFreeOn_iff_christoffelSymbols (ι := (↑(Basis.ofVectorSpaceIndex ℝ E))) I hf] + -- issues with quantifier order in the statement... prove both directions separately, at each x? + repeat sorry theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x : M) : letI t := trivializationAt E (TangentSpace I) x; diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index c78e5fb1fc8a8b..07a743bf729ee5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -258,6 +258,7 @@ lemma aux1 {ι : Type*} [Fintype ι] _ = ∑ i, (torsion f (fun x ↦ (hs.repr i) X x • s i x) Y x) := sorry _ = ∑ i, (hs.repr i) X x • (torsion f (s i) Y x) := sorry +-- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x variable {n} in lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} From d33d7dba1691619d7302a506a68380ec81321731 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 30 Aug 2025 23:22:43 +0200 Subject: [PATCH 352/601] chore: ChristoffelSymbol should be UpperCamelBase --- .../CovariantDerivative/LeviCivita.lean | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 15f1786ff18cef..e1476ee3bc7ef4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -776,7 +776,7 @@ omit [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] /-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, this is a function `Γᵢⱼᵏ : M → ℝ`, whose value outside of `U` is meaningless. -/ -noncomputable def christoffelSymbol +noncomputable def ChristoffelSymbol (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) {U : Set M} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := @@ -784,12 +784,12 @@ noncomputable def christoffelSymbol lemma christoffelSymbol_zero (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} - (hs : IsLocalFrameOn I E n s U) (i j k : ι) : christoffelSymbol I 0 hs i j k = 0 := by - simp [christoffelSymbol] + (hs : IsLocalFrameOn I E n s U) (i j k : ι) : ChristoffelSymbol I 0 hs i j k = 0 := by + simp [ChristoffelSymbol] @[simp] lemma christoffelSymbol_zero_apply (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} - (hs : IsLocalFrameOn I E n s U) (i j k : ι) (x) : christoffelSymbol I 0 hs i j k x = 0 := by + (hs : IsLocalFrameOn I E n s U) (i j k : ι) (x) : ChristoffelSymbol I 0 hs i j k x = 0 := by simp [christoffelSymbol_zero] end @@ -801,7 +801,7 @@ variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSp lemma foobar (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E 1 s U) (x : M) : f X Y x = ∑ k, - let S₁ := ∑ i, ∑ j, (hs.repr i X) * (hs.repr j Y) * (christoffelSymbol I f hs i j k) + let S₁ := ∑ i, ∑ j, (hs.repr i X) * (hs.repr j Y) * (ChristoffelSymbol I f hs i j k) let S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! S₁ x • s k x := -- straightforward computation: write Y = ∑ i, hs.repr i Y and use linearity and Leibniz rule @@ -822,7 +822,7 @@ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fin {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : IsTorsionFreeOn f U ↔ - ∀ i j k, ∀ x ∈ U, christoffelSymbol I f hs i j k x = christoffelSymbol I f hs j i k x := by + ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by rw [hf.isTorsionFreeOn_iff_localFrame (n := n) hs] have (i j : ι) {x} (hx : x ∈ U) : torsion f (s i) (s j) x = f (s i) (s j) x - f (s j) (s i) x := by @@ -830,7 +830,7 @@ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fin peel with i j refine ⟨?_, ?_⟩ · intro h k x hx - simp only [christoffelSymbol] + simp only [ChristoffelSymbol] apply hs.repr_congr specialize h x hx rw [this i j hx, sub_eq_zero] at h @@ -853,7 +853,7 @@ lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional ℝ E] [IsManifol ∀ x ∈ U, -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. -- TODO: does the following do what I want?? - letI cs := christoffelSymbol I f + letI cs := ChristoffelSymbol I f ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (trivializationAt E _ x)) ∀ i j k, cs i j k x = cs j i k x := by letI t := (trivializationAt E (fun (x : M) ↦ TangentSpace I x)) @@ -869,8 +869,8 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t ∀ {x'}, x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), - christoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = - christoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by + ChristoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = + ChristoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by by_cases hE : Subsingleton E · have (y : M) (X : TangentSpace I y) : X = 0 := by have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) @@ -884,7 +884,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t - have : christoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k + have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k sorry -- this should do it! sorry From 09ffcf8579ee841a6d6f2a03b4b7c9ffb5fea8d3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 00:11:50 +0200 Subject: [PATCH 353/601] Small tweaks, one sorry and an auxiliary lemma All added lemmas are nice to have, though seemingly unused for my argument. --- .../CovariantDerivative/LeviCivita.lean | 57 ++++++++++++++++--- .../VectorBundle/OrthonormalFrame.lean | 2 +- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e1476ee3bc7ef4..81aa2904c0946a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -3,7 +3,6 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Tangent @@ -768,10 +767,11 @@ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ exact isCovariantDerivativeOn_lcCandidate I _ +-- TODO: move this section to `Torsion.lean` section -omit [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -omit [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] +--omit [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] +--omit [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] /-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, @@ -782,6 +782,49 @@ noncomputable def ChristoffelSymbol (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := hs.repr k (f (s i) (s j)) +variable {U : Set M} + {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + +-- Note that this result is false if `{s i}` is merely a local frame. +lemma eq_product_apply [Fintype ι] + (hf : IsCovariantDerivativeOn E f U) + (hs : IsOrthonormalFrameOn I E n s U) + (i j k : ι) (hx : x ∈ U) : + ChristoffelSymbol I f hs.toIsLocalFrameOn i j k x = ⟪f (s i) (s j), (s k)⟫ x := by + -- Choose a linear order on ι: which one really does not matter for our result. + have : LinearOrder ι := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot ι := by sorry + rw [ChristoffelSymbol, hs.repr_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] + +lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] + (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) + (hs : IsLocalFrameOn I E n s U) + (hfg : ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x) : + ∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x := by + have (i j : ι) : ∀ x ∈ U, f (s i) (s j) x = g (s i) (s j) x := by + intro x hx + rw [hs.eq_iff_repr hx] + exact fun k ↦ hfg i j k x hx + intro X Y x hx + -- use linearity now, another separate lemma! + sorry + +/-- Two covariant derivatives on `U` are equal on `U` if and only if all of their +covariant derivatives w.r.t. some local frame on `U` are equal on `U`. -/ +lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ι] + (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) + (hs : IsLocalFrameOn I E n s U) : + (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x) ↔ + ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x := + ⟨fun hfg _i _j _k _x hx ↦ hs.repr_congr (hfg _ _ _ hx ) .., + fun h X Y x hx ↦ hf.congr_of_christoffelSymbol_eq I hg hs h X Y x hx⟩ + +-- TODO: global version for convenience, with an alias for the interesting direction! + +variable (hs : IsLocalFrameOn I E n s U) lemma christoffelSymbol_zero (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (i j k : ι) : ChristoffelSymbol I 0 hs i j k = 0 := by @@ -814,12 +857,13 @@ lemma foobar (hf : IsCovariantDerivativeOn E f U) - deduce: two covariant derivatives are equal iff their Christoffel symbols are equal -/ +-- errors: omit [IsContMDiffRiemannianBundle I 1 E fun x ↦ TangentSpace I x] in /-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fintype ι] (hf : IsCovariantDerivativeOn E f U) - {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) -- (hx : x ∈ U) (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : IsTorsionFreeOn f U ↔ ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by @@ -836,9 +880,8 @@ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fin rw [this i j hx, sub_eq_zero] at h exact h · intro h x hx - rw [this i j hx] - -- equal Christoffel symbols means equal function: separate lemma, using frames - sorry + rw [this i j hx, sub_eq_zero, hs.eq_iff_repr hx] + exact fun k ↦ h k x hx -- Exercise 4.2(b) in Lee, Chapter 4 /-- A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U` and diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 22ff1b0f9b4e18..d23ce21a1da667 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -127,7 +127,7 @@ lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : -- variable (t) in -- lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : -- hs.repr i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by --- sorry -- need a versio of b.repr_apply_apply for *orthogonal* bases +-- sorry -- need a version of b.repr_apply_apply for *orthogonal* bases /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : From dcbd776ca8205c6d2901bc3c5ab896ade7c52e81 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 09:16:33 +0200 Subject: [PATCH 354/601] chore(LeviCivita): better abstraction for the 'enter and exit the product' again --- .../CovariantDerivative/LeviCivita.lean | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 81aa2904c0946a..bfb345db94d277 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -43,7 +43,7 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ -variable {X X' Y Y' Z Z' : Π x : M, TangentSpace I x} +variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} /-- The scalar product of two vector fields -/ noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := @@ -120,6 +120,25 @@ lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product end product +-- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) +-- only hold point-wise. They abstract the expanding and unexpanding of `product`. +omit [IsManifold I ∞ M] in +lemma product_congr_left {x} (h : X x = X' x) : product I X Y x = product I X' Y x := by + rw [product_apply, h, ← product_apply] + +omit [IsManifold I ∞ M] in +lemma product_congr_left₂ {x} (h : X x = X' x + X'' x) : + product I X Y x = product I X' Y x + product I X'' Y x := by + rw [product_apply, h, inner_add_left, ← product_apply] +omit [IsManifold I ∞ M] in +lemma product_congr_right {x} (h : Y x = Y' x) : product I X Y x = product I X Y' x := by + rw [product_apply, h, ← product_apply] + +omit [IsManifold I ∞ M] in +lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : + product I X Y x = product I X Y' x + product I X Y'' x := by + rw [product_apply, h, inner_add_right, ← product_apply] + set_option linter.style.commandStart false -- custom elaborators not handled well yet /- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` @@ -289,10 +308,10 @@ lemma leviCivita_rhs'_addX_apply [CompleteSpace E] simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. - simp_rw [product_apply, VectorField.mlieBracket_add_right (V := Y) hX hX', - VectorField.mlieBracket_add_left (W := Z) hX hX', inner_add_right, ← product_apply, - product_add_left_apply] - rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + -- Fortunately, the `product_congr_right₂` lemma abstracts this very well. + rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := Y) hX hX'), + product_congr_right₂ I (VectorField.mlieBracket_add_left (W := Z) hX hX'), + product_add_left_apply, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel lemma leviCivita_rhs'_addX [CompleteSpace E] @@ -323,6 +342,7 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} unfold leviCivita_rhs' simp only [Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption + -- TODO: add the right congr_right lemma to avoid the product_apply, ← product_apply dance! simp only [product_apply, mlieBracket_smul_left (W := Z) hf hX, mlieBracket_smul_right (V := Y) hf hX, inner_add_right] -- Combining this line with the previous one fails. @@ -382,11 +402,9 @@ lemma leviCivita_rhs'_addY_apply [CompleteSpace E] rw [rhs_aux_addX, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. - simp only [product_apply] - simp only [Pi.add_apply, mlieBracket_add_left (W := X) hY hY', - VectorField.mlieBracket_add_right (V := Z) hY hY', inner_add_right, ← product_apply] - have : mlieBracket I (Y + Y') X x = mlieBracket I (Y) X x + mlieBracket I Y' X x := by - exact mlieBracket_add_left (W := X) hY hY' + rw [product_congr_right₂ I (mlieBracket_add_left (W := X) hY hY')] + rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := Z) hY hY')] + simp only [Pi.add_apply] abel lemma leviCivita_rhs_addY_apply [CompleteSpace E] @@ -407,10 +425,9 @@ lemma leviCivita_rhs'_addZ_apply [CompleteSpace E] leviCivita_rhs' I X Y (Z + Z') x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X Y Z' x := by simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] - rw [rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption - simp only [product_apply] - simp only [VectorField.mlieBracket_add_right (V := X) hZ hZ', - VectorField.mlieBracket_add_left (W := Y) hZ hZ', inner_add_right, ← product_apply] + rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := X) hZ hZ'), + product_congr_right₂ I (VectorField.mlieBracket_add_left (W := Y) hZ hZ'), + rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel lemma leviCivita_rhs'_addZ [CompleteSpace E] From c60d6e2959669024499f160455e4880b28d752a9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 09:29:58 +0200 Subject: [PATCH 355/601] smulZ computation complete! --- .../CovariantDerivative/LeviCivita.lean | 99 ++++--------------- 1 file changed, 19 insertions(+), 80 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index bfb345db94d277..f82c80b2926cba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -452,66 +452,37 @@ lemma leviCivita_rhs_addZ [CompleteSpace E] lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivita_rhs' I X Y (f • Z) x = f x • leviCivita_rhs' I X Y Z x := by - simp only [leviCivita_rhs'] - simp [rhs_aux_smulX] + simp only [leviCivita_rhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] - beta_reduce set A := rhs_aux I X Y Z x set B := rhs_aux I Y Z X x set C := rhs_aux I Z X Y x -- Apply the product rule for the lie bracket. - have h1 : VectorField.mlieBracket I X (f • Z) x = - f x • VectorField.mlieBracket I X Z x + mfderiv% f x (X x) • Z x := by - rw [VectorField.mlieBracket_smul_right hf hZ, add_comm] - have h2 : VectorField.mlieBracket I (f • Z) Y x = - -(mfderiv% f x (Y x)) • Z x + f x • VectorField.mlieBracket I Z Y x := by - rw [VectorField.mlieBracket_smul_left hf hZ] - -- -- Again, we need to go into the product and back out again. - -- simp only [product_apply] - -- rw [h1, h2, inner_add_right, inner_smul_right_eq_smul] - -- simp only [← product_apply] - - -- Let's try to encapsulate more. - have h1' : ⟪Y, mlieBracket I X (f • Z)⟫ x = + -- Let's encapsulate the going into the product and back out again. + have h1 : ⟪Y, mlieBracket I X (f • Z)⟫ x = f x • ⟪Y, mlieBracket I X Z⟫ x + ⟪Y, mfderiv% f x (X x) • Z⟫ x := by - rw [product_apply, h1, inner_add_right, inner_smul_right] + rw [product_apply, VectorField.mlieBracket_smul_right hf hZ, inner_add_right, add_comm, + inner_smul_right] congr - rw [h1'] - set D := ⟪Y, mlieBracket I X Z⟫ x - - set X'' := ⟪Y, (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) • Z⟫ x - - - have aux : ⟪f • Z, mlieBracket I Y X⟫ x = f x • ⟪Z, mlieBracket I Y X⟫ x := by - rw [product_smul_left]; simp - - rw [product_smul_left] - --simp_rw [product_smul_left] + have h2 : letI dfY : ℝ := (mfderiv% f x) (Y x); + ⟪X, mlieBracket I (f • Z) Y⟫ x = - dfY • ⟪X, Z⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by + rw [product_apply, VectorField.mlieBracket_smul_left hf hZ, inner_add_right, inner_smul_right, + inner_smul_right] + congr + rw [h1, h2, product_smul_left, product_swap I X Z] + erw [product_smul_right] + simp - --simp only [product_add_right_apply] set D := ⟪Y, mlieBracket I X Z⟫ x - set E := ⟪Z, mlieBracket I Y X⟫ x + set E := ⟪Z, mlieBracket I Y X⟫ x with E_eq set F := ⟪X, mlieBracket I Z Y⟫ x - --rw [h1, h2]; beta_reduce - --simp only [smul_eq_mul, product_add_right_apply] - - -- continue here! - sorry - -- simp_rw [product_apply] - -- set D' := (mfderiv% f x) (X x) - -- set D := (fun x ↦ (mfderiv% f x) (X x)) • Z - - -- --rw [product_add_right, product_add_right] - -- -- These are all science fiction, and not fully true! - -- rw [product_smul_left, product_smul_right, product_smul_right] - -- set E := ⟪Z, VectorField.mlieBracket I X Y⟫ - -- set F := ⟪Y, VectorField.mlieBracket I X Z⟫ - -- set G := ⟪X, VectorField.mlieBracket I Z Y⟫ - -- -- apart from science fiction mistakes, this is "an easy computation" - -- simp; abel_nf - -- sorry + letI dfX : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) + set G := dfX * ⟪Y, Z⟫ x + letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + set H := dfY * ⟪X, Z⟫ x + ring lemma leviCivita_rhs'_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : @@ -524,38 +495,6 @@ lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by simp only [leviCivita_rhs] rw [smul_comm, leviCivita_rhs'_smulZ I hf hX hY hZ] -/- old proof attempt was: -lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hZ : MDiff (T% Z)) : - leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by - simp only [leviCivita_rhs, leviCivita_rhs'] - simp [rhs_aux_smulX]--, rhs_aux_smulY, rhs_aux_smulZ] - ext x - simp only [Pi.mul_apply, Pi.add_apply] - have h1 : VectorField.mlieBracket I X (f • Z) = - f • VectorField.mlieBracket I X Z + (fun x ↦ mfderiv% f x (X x)) • Z := by - ext x - rw [VectorField.mlieBracket_smul_right (hf x) (hZ x), add_comm] - simp - have h2 : VectorField.mlieBracket I (f • Z) Y = - -(fun x ↦ mfderiv% f x (Y x)) • Z + f • VectorField.mlieBracket I Z Y := by - ext x - rw [VectorField.mlieBracket_smul_left (hf x) (hZ x)] - simp - simp only [h1, Pi.smul_apply, Pi.sub_apply, Pi.add_apply, Pi.mul_apply, smul_eq_mul, h2] - set A := rhs_aux I X Y Z x - set B := rhs_aux I Y Z X x - set C := rhs_aux I Z X Y x - set D := (fun x ↦ (mfderiv% f x) (X x)) • Z - - rw [product_add_right, product_add_right] - -- These are all science fiction, and not fully true! - rw [product_smul_left, product_smul_right, product_smul_right] - set E := ⟪Z, VectorField.mlieBracket I X Y⟫ - set F := ⟪Y, VectorField.mlieBracket I X Z⟫ - set G := ⟪X, VectorField.mlieBracket I Z Y⟫ - -- apart from science fiction mistakes, this is "an easy computation" - simp; abel_nf - sorry -/ end leviCivita_rhs From c3a1d68e4948d7cdcf6c180a1c74d55516c9ac31 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 10:02:16 +0200 Subject: [PATCH 356/601] chore: rename definitions to follow the naming convention better --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index f82c80b2926cba..7b85831b7eea73 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -511,10 +511,10 @@ lemma isolate_aux {α : Type*} [AddCommGroup α] A + A = X + Y - Z - D - E + F := by rw [h]; abel -variable (X Y Z) in +variable (X Y Z) {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ -lemma isLeviCivitaConnection_uniqueness_aux (h : cov.IsLeviCivitaConnection) : +lemma IsLeviCivitaConnection.eq_leviCivita_rhs (h : cov.IsLeviCivitaConnection) : ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by set A := ⟪cov X Y, Z⟫ set B := ⟪cov Z X, Y⟫ @@ -581,7 +581,7 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ -- (probably not everywhere, as addition rules apply only for differentiable vector fields?) -theorem isLeviCivita_uniqueness [FiniteDimensional ℝ E] +theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] {cov cov' : CovariantDerivative I E (TangentSpace I : M → Type _)} (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) : -- almost, only agree on smooth functions @@ -590,8 +590,8 @@ theorem isLeviCivita_uniqueness [FiniteDimensional ℝ E] apply congrFun apply congr_of_forall_product fun Z ↦ ?_ trans leviCivita_rhs I X σ Z - · exact cov.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov - · exact (cov'.isLeviCivitaConnection_uniqueness_aux I X σ Z hcov').symm + · exact hcov.eq_leviCivita_rhs I X σ Z + · exact (hcov'.eq_leviCivita_rhs I X σ Z ).symm noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : From 13181554660f7a94d816d48b34ff69b854beb190 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 10:03:03 +0200 Subject: [PATCH 357/601] chore: make leviCivitaRhs(') follow the naming convention --- .../CovariantDerivative/LeviCivita.lean | 154 +++++++++--------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 7b85831b7eea73..08250d9a88e3a8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -278,8 +278,8 @@ variable {x : M} variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If ∇ is a Levi-Civita connection on `TM`, then -`2 ⟨∇ X Y, Z⟩ = leviCivita_rhs' I X Y Z` for all vector fields `Z`. -/ -noncomputable def leviCivita_rhs' : M → ℝ := +`2 ⟨∇ X Y, Z⟩ = leviCivitaRhs' I X Y Z` for all vector fields `Z`. -/ +noncomputable def leviCivitaRhs' : M → ℝ := rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y - ⟪Y ,(VectorField.mlieBracket I X Z)⟫ - ⟪Z, (VectorField.mlieBracket I Y X)⟫ @@ -288,24 +288,24 @@ noncomputable def leviCivita_rhs' : M → ℝ := variable (X Y Z) in /-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: If `∇` is a Levi-Civita connection on `TM`, then -`⟨∇ X Y, Z⟩ = leviCivita_rhs I X Y Z` for all smooth vector fields `X`, `Y` and `Z`. -/ -noncomputable def leviCivita_rhs : M → ℝ := (1 / 2 : ℝ) • leviCivita_rhs' I X Y Z +`⟨∇ X Y, Z⟩ = leviCivitaRhs I X Y Z` for all smooth vector fields `X`, `Y` and `Z`. -/ +noncomputable def leviCivitaRhs : M → ℝ := (1 / 2 : ℝ) • leviCivitaRhs' I X Y Z omit [IsManifold I ∞ M] in -lemma leviCivita_rhs_apply : leviCivita_rhs I X Y Z x = (1 / 2 : ℝ) • leviCivita_rhs' I X Y Z x := +lemma leviCivitaRhs_apply : leviCivitaRhs I X Y Z x = (1 / 2 : ℝ) • leviCivitaRhs' I X Y Z x := rfl -section leviCivita_rhs +section leviCivitaRhs variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] @[simp] -lemma leviCivita_rhs'_addX_apply [CompleteSpace E] +lemma leviCivitaRhs'_addX_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs' I (X + X') Y Z x = - leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X' Y Z x := by - simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] + leviCivitaRhs' I (X + X') Y Z x = + leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X' Y Z x := by + simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. -- Fortunately, the `product_congr_right₂` lemma abstracts this very well. @@ -314,32 +314,32 @@ lemma leviCivita_rhs'_addX_apply [CompleteSpace E] product_add_left_apply, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel -lemma leviCivita_rhs'_addX [CompleteSpace E] +lemma leviCivitaRhs'_addX [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - leviCivita_rhs' I (X + X') Y Z = - leviCivita_rhs' I X Y Z + leviCivita_rhs' I X' Y Z := by + leviCivitaRhs' I (X + X') Y Z = + leviCivitaRhs' I X Y Z + leviCivitaRhs' I X' Y Z := by ext x - simp [leviCivita_rhs'_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] + simp [leviCivitaRhs'_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] -lemma leviCivita_rhs_addX_apply [CompleteSpace E] +lemma leviCivitaRhs_addX_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs I (X + X') Y Z x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X' Y Z x := by - simp [leviCivita_rhs, leviCivita_rhs'_addX_apply I hX hX' hY hZ, left_distrib] + leviCivitaRhs I (X + X') Y Z x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X' Y Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_addX_apply I hX hX' hY hZ, left_distrib] -lemma leviCivita_rhs_addX [CompleteSpace E] +lemma leviCivitaRhs_addX [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - leviCivita_rhs I (X + X') Y Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X' Y Z := by + leviCivitaRhs I (X + X') Y Z = leviCivitaRhs I X Y Z + leviCivitaRhs I X' Y Z := by ext x - simp [leviCivita_rhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] + simp [leviCivitaRhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] open VectorField variable {I} in -lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} +lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs' I (f • X) Y Z x = f x • leviCivita_rhs' I X Y Z x := by - unfold leviCivita_rhs' + leviCivitaRhs' I (f • X) Y Z x = f x • leviCivitaRhs' I X Y Z x := by + unfold leviCivitaRhs' simp only [Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption -- TODO: add the right congr_right lemma to avoid the product_apply, ← product_apply dance! @@ -379,26 +379,26 @@ lemma leviCivita_rhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} congr variable {I} in -lemma leviCivita_rhs_smulX_apply [CompleteSpace E] {f : M → ℝ} +lemma leviCivitaRhs_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs I (f • X) Y Z x = f x • leviCivita_rhs I X Y Z x := by - simp only [leviCivita_rhs, one_div, Pi.smul_apply, smul_eq_mul] - simp_rw [leviCivita_rhs'_smulX_apply (I := I) hf hX hY hZ] + leviCivitaRhs I (f • X) Y Z x = f x • leviCivitaRhs I X Y Z x := by + simp only [leviCivitaRhs, one_div, Pi.smul_apply, smul_eq_mul] + simp_rw [leviCivitaRhs'_smulX_apply (I := I) hf hX hY hZ] rw [← mul_assoc, mul_comm (f x), smul_eq_mul] ring variable {I} in -lemma leviCivita_rhs_smulX [CompleteSpace E] {f : M → ℝ} +lemma leviCivitaRhs_smulX [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - leviCivita_rhs I (f • X) Y Z = f • leviCivita_rhs I X Y Z := by + leviCivitaRhs I (f • X) Y Z = f • leviCivitaRhs I X Y Z := by ext x - exact leviCivita_rhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) + exact leviCivitaRhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) -lemma leviCivita_rhs'_addY_apply [CompleteSpace E] +lemma leviCivitaRhs'_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs' I X (Y + Y') Z x = leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X Y' Z x := by - simp only [leviCivita_rhs', Pi.add_apply, Pi.sub_apply, product_add_left_apply] + leviCivitaRhs' I X (Y + Y') Z x = leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y' Z x := by + simp only [leviCivitaRhs', Pi.add_apply, Pi.sub_apply, product_add_left_apply] rw [rhs_aux_addX, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. @@ -407,52 +407,52 @@ lemma leviCivita_rhs'_addY_apply [CompleteSpace E] simp only [Pi.add_apply] abel -lemma leviCivita_rhs_addY_apply [CompleteSpace E] +lemma leviCivitaRhs_addY_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs I X (Y + Y') Z x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X Y' Z x := by - simp [leviCivita_rhs, leviCivita_rhs'_addY_apply I hX hY hY' hZ, left_distrib] + leviCivitaRhs I X (Y + Y') Z x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X Y' Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_addY_apply I hX hY hY' hZ, left_distrib] -lemma leviCivita_rhs_addY [CompleteSpace E] +lemma leviCivitaRhs_addY [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : - leviCivita_rhs I X (Y + Y') Z = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y' Z := by + leviCivitaRhs I X (Y + Y') Z = leviCivitaRhs I X Y Z + leviCivitaRhs I X Y' Z := by ext x - simp [leviCivita_rhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] + simp [leviCivitaRhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] -lemma leviCivita_rhs'_addZ_apply [CompleteSpace E] +lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : - leviCivita_rhs' I X Y (Z + Z') x = - leviCivita_rhs' I X Y Z x + leviCivita_rhs' I X Y Z' x := by - simp only [leviCivita_rhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] + leviCivitaRhs' I X Y (Z + Z') x = + leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y Z' x := by + simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := X) hZ hZ'), product_congr_right₂ I (VectorField.mlieBracket_add_left (W := Y) hZ hZ'), rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel -lemma leviCivita_rhs'_addZ [CompleteSpace E] +lemma leviCivitaRhs'_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - leviCivita_rhs' I X Y (Z + Z') = - leviCivita_rhs' I X Y Z + leviCivita_rhs' I X Y Z' := by + leviCivitaRhs' I X Y (Z + Z') = + leviCivitaRhs' I X Y Z + leviCivitaRhs' I X Y Z' := by ext x - exact leviCivita_rhs'_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + exact leviCivitaRhs'_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) -lemma leviCivita_rhs_addZ_apply [CompleteSpace E] +lemma leviCivitaRhs_addZ_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : - leviCivita_rhs I X Y (Z + Z') x = leviCivita_rhs I X Y Z x + leviCivita_rhs I X Y Z' x := by - simp [leviCivita_rhs, leviCivita_rhs'_addZ_apply I hX hY hZ hZ', left_distrib] + leviCivitaRhs I X Y (Z + Z') x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X Y Z' x := by + simp [leviCivitaRhs, leviCivitaRhs'_addZ_apply I hX hY hZ hZ', left_distrib] -lemma leviCivita_rhs_addZ [CompleteSpace E] +lemma leviCivitaRhs_addZ [CompleteSpace E] (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : - leviCivita_rhs I X Y (Z + Z') = leviCivita_rhs I X Y Z + leviCivita_rhs I X Y Z' := by + leviCivitaRhs I X Y (Z + Z') = leviCivitaRhs I X Y Z + leviCivitaRhs I X Y Z' := by ext x - exact leviCivita_rhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + exact leviCivitaRhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) -lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} +lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - leviCivita_rhs' I X Y (f • Z) x = f x • leviCivita_rhs' I X Y Z x := by - simp only [leviCivita_rhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] + leviCivitaRhs' I X Y (f • Z) x = f x • leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] set A := rhs_aux I X Y Z x @@ -484,19 +484,19 @@ lemma leviCivita_rhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} set H := dfY * ⟪X, Z⟫ x ring -lemma leviCivita_rhs'_smulZ [CompleteSpace E] {f : M → ℝ} +lemma leviCivitaRhs'_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - leviCivita_rhs' I X Y (f • Z) = f • leviCivita_rhs' I X Y Z := by + leviCivitaRhs' I X Y (f • Z) = f • leviCivitaRhs' I X Y Z := by ext x - exact leviCivita_rhs'_smulZ_apply I (hf x) (hX x) (hY x) (hZ x) + exact leviCivitaRhs'_smulZ_apply I (hf x) (hX x) (hY x) (hZ x) -lemma leviCivita_rhs_smulZ [CompleteSpace E] {f : M → ℝ} +lemma leviCivitaRhs_smulZ [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - leviCivita_rhs I X Y (f • Z) = f • leviCivita_rhs I X Y Z := by - simp only [leviCivita_rhs] - rw [smul_comm, leviCivita_rhs'_smulZ I hf hX hY hZ] + leviCivitaRhs I X Y (f • Z) = f • leviCivitaRhs I X Y Z := by + simp only [leviCivitaRhs] + rw [smul_comm, leviCivitaRhs'_smulZ I hf hX hY hZ] -end leviCivita_rhs +end leviCivitaRhs variable (X Y Z) in lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = @@ -514,8 +514,8 @@ lemma isolate_aux {α : Type*} [AddCommGroup α] variable (X Y Z) {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ -lemma IsLeviCivitaConnection.eq_leviCivita_rhs (h : cov.IsLeviCivitaConnection) : - ⟪cov X Y, Z⟫ = leviCivita_rhs I X Y Z := by +lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : + ⟪cov X Y, Z⟫ = leviCivitaRhs I X Y Z := by set A := ⟪cov X Y, Z⟫ set B := ⟪cov Z X, Y⟫ set C := ⟪cov Y Z, X⟫ @@ -534,8 +534,8 @@ lemma IsLeviCivitaConnection.eq_leviCivita_rhs (h : cov.IsLeviCivitaConnection) -- Solve for ⟪cov X Y, Z⟫ and obtain the claim. have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) (by simp [this]) - have almoster : A + A = leviCivita_rhs' I X Y Z := by simp only [leviCivita_rhs', *] - simp only [leviCivita_rhs, ← almoster, smul_add] + have almoster : A + A = leviCivitaRhs' I X Y Z := by simp only [leviCivitaRhs', *] + simp only [leviCivitaRhs, ← almoster, smul_add] ext; simp; ring section @@ -589,9 +589,9 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] ext X σ x apply congrFun apply congr_of_forall_product fun Z ↦ ?_ - trans leviCivita_rhs I X σ Z - · exact hcov.eq_leviCivita_rhs I X σ Z - · exact (hcov'.eq_leviCivita_rhs I X σ Z ).symm + trans leviCivitaRhs I X σ Z + · exact hcov.eq_leviCivitaRhs I X σ Z + · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : @@ -610,8 +610,8 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` - -- is given by `leviCivita_rhs X Y s i`. - ∑ i, ((leviCivita_rhs I X Y (frame i)) x) • (frame i x) + -- is given by `leviCivitaRhs X Y s i`. + ∑ i, ((leviCivitaRhs I X Y (frame i)) x) • (frame i x) variable (M) in -- TODO: make g part of the notation! @@ -647,7 +647,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i - rw [leviCivita_rhs_addX_apply] <;> try assumption + rw [leviCivitaRhs_addX_apply] <;> try assumption let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) @@ -662,7 +662,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have hg : MDiff g := sorry -- might need this (hopefully not!) rw [Finset.smul_sum] congr; ext i - rw [leviCivita_rhs_smulX] <;> try assumption + rw [leviCivitaRhs_smulX] <;> try assumption rotate_left · sorry -- missing hyp! · sorry -- missing hyp! @@ -671,7 +671,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] by_cases hE : Subsingleton E; · have : X x = 0 := sorry; simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i - -- want leviCivita_rhs_smulY (with a constant) + -- want leviCivitaRhs_smulY (with a constant) sorry addσ X σ σ' x hσ hσ' hx := by have hX : MDiffAt (T% X) x := sorry -- missing assumption! @@ -679,7 +679,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i - rw [leviCivita_rhs_addY_apply] <;> try assumption + rw [leviCivitaRhs_addY_apply] <;> try assumption let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := by sorry set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) From 054423a4b2f4c9ebe085ff6f58465e289d9eb4d8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 10:09:12 +0200 Subject: [PATCH 358/601] Progress on symmetry of Christoffel symbols... only "boring" sorries remain --- .../CovariantDerivative/LeviCivita.lean | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 08250d9a88e3a8..4d3084e3aa4c3e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -194,6 +194,7 @@ noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv% ⟪Y, Z⟫ x (X section rhs_aux +variable (Y Z) in omit [IsManifold I ∞ M] in lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by ext x @@ -765,7 +766,7 @@ lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] rw [hs.eq_iff_repr hx] exact fun k ↦ hfg i j k x hx intro X Y x hx - -- use linearity now, another separate lemma! + -- use linearity (=formula for f in terms of Christoffel symbols) now, another separate lemma! sorry /-- Two covariant derivatives on `U` are equal on `U` if and only if all of their @@ -867,7 +868,7 @@ lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional ℝ E] [IsManifol theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x : M) : letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t - ∀ {x'}, x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), + ∀ x', x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), ChristoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = ChristoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by by_cases hE : Subsingleton E @@ -883,8 +884,65 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t - have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k + --have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k sorry -- this should do it! + -- Note that hs is not necessarily an orthonormal frame, so we cannot simply rewrite + -- the Christoffel symbols as Γᵢⱼᵏ = ⟪∇ᵍ X Y, Z⟫`: however, the result we wants to prove boils + -- down to proving the same. + intro x' hx' i j + set t := trivializationAt E (TangentSpace I) x + set b := (Basis.ofVectorSpace ℝ E) + set s := b.localFrame t + set ι := ↑(Basis.ofVectorSpaceIndex ℝ E) + -- Same computation as above; extract as lemma! + let O : (x : M) → TangentSpace I x := fun x ↦ 0 + have need : ∀ i j, VectorField.mlieBracket I (s i) (s j) x' = O x' := sorry + have aux : ∀ k, ⟪LeviCivitaConnection I M (s i) (s j), (s k)⟫ x' + = ⟪LeviCivitaConnection I M (s j) (s i), (s k)⟫ x' := by + intro k + simp only [LeviCivitaConnection] + unfold lcCandidate + rw [product_apply, product_apply] + simp only [lcCandidate_aux, hE, ↓reduceDIte] + -- Choose a linear order on ι: which one really does not matter for our result. + have : LinearOrder ι := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot ι := by sorry + have : ∑ k', inner ℝ + (leviCivitaRhs I (s i) (s j) + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • + b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') + (s k x') = + ∑ k', inner ℝ ( + leviCivitaRhs I (s j) (s i) + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • + b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') + (s k x') := by + congr with k' + simp only [leviCivitaRhs] + set sij := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x' + rw [inner_smul_left, inner_smul_left] + congr + simp [leviCivitaRhs'] + set S := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' + have need' : ∀ i, VectorField.mlieBracket I (s i) S x' = O x' := by + -- expand the definition of Gram-Schmidt and use need and linearity + sorry + have need'' : ∀ i, VectorField.mlieBracket I S (s i) x' = O x' := by + sorry -- swap and use need', or so + rw [product_congr_right I (need i j), product_congr_right I (need j i), + product_congr_right I (need' i), product_congr_right I (need'' i), + product_congr_right I (need' j), product_congr_right I (need'' j), + rhs_aux_swap I (s i) (s j), rhs_aux_swap I (s j) S, rhs_aux_swap I S (s i)] + simp [O] + abel + -- now, just rewrite `inner` to take out a sum: same lemma twice + convert this + sorry + sorry + + -- deduce the goal from `aux` sorry lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by @@ -917,7 +975,7 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon rw [isTorsionFree_iff_christoffelSymbols' _ this] intro x' hx' i j k -- Now, compute christoffel symbols and be happy. - have := LeviCivitaConnection.christoffelSymbol_symm I x hx' i j k + have := LeviCivitaConnection.christoffelSymbol_symm I x x' hx' i j k sorry -- almost there, except x vs x' convert this end CovariantDerivative From 62f3653cb64408565d4e4199236b47ab4ab1f7ff Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 18:35:04 +0200 Subject: [PATCH 359/601] Small tweaks --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 4d3084e3aa4c3e..ab9ec20b2b161f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -556,15 +556,17 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) apply Subsingleton.allEq _ ext x - letI b := Basis.ofVectorSpace ℝ E - letI t := trivializationAt E (TangentSpace I : M → Type _) x + let b := Basis.ofVectorSpace ℝ E + let t := trivializationAt E (TangentSpace I : M → Type _) x have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + -- The linear ordering on the indexing set of `b` is only used in this proof, + -- so our choice does not matter. have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by choose r wo using exists_wellOrder _ exact r - haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g let real := b.orthonormalFrame t @@ -611,7 +613,7 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` - -- is given by `leviCivitaRhs X Y s i`. + -- is given by `leviCivitaRhs X Y (s i)`. ∑ i, ((leviCivitaRhs I X Y (frame i)) x) • (frame i x) variable (M) in From 33dcdb68b04142bbfd3664fd61a41e9698845ef5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 18:50:13 +0200 Subject: [PATCH 360/601] chore: fix to order sorries --- .../CovariantDerivative/LeviCivita.lean | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ab9ec20b2b161f..5b2f694d30ae85 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -604,13 +604,13 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] if hE : Subsingleton E then X x else -- Choose a trivialisation of `TM` near `x`. -- Since `E` is non-trivial, `b` is non-empty. - letI b := Basis.ofVectorSpace ℝ E + let b := Basis.ofVectorSpace ℝ E have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by choose r wo using exists_wellOrder _ exact r - haveI : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` -- is given by `leviCivitaRhs X Y (s i)`. @@ -652,10 +652,13 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] congr; ext i rw [leviCivitaRhs_addX_apply] <;> try assumption let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := sorry - set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + let b := Basis.ofVectorSpace ℝ E + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + set f := b.orthonormalFrame e i have : MDiffAt (T% f) x := -- missing API lemma! - (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) + (contMDiffAt_orthonormalFrame_of_mem b e i hx) |>.mdifferentiableAt le_rfl sorry -- convert this works, except for different local orders... smulX X σ g x hx := by @@ -683,11 +686,15 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivitaRhs_addY_apply] <;> try assumption + + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + let b := Basis.ofVectorSpace ℝ E + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := by sorry - set f := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + set f := b.orthonormalFrame e i have : MDiffAt (T% f) x := -- missing API lemma! - (contMDiffAt_orthonormalFrame_of_mem (Basis.ofVectorSpace ℝ E) e i hx) + (contMDiffAt_orthonormalFrame_of_mem b e i hx) |>.mdifferentiableAt le_rfl -- mismatch between different orders; the sorry above convert this <;> sorry From 7012476a815712e40648c08e6862d38c2cbe38df Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 18:55:46 +0200 Subject: [PATCH 361/601] My other attempt fails, though! --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 5b2f694d30ae85..3bea02eb487234 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -917,7 +917,16 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x have : LinearOrder ι := by choose r wo using exists_wellOrder _ exact r - have : LocallyFiniteOrderBot ι := by sorry + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + have : Nonempty ι := b.index_nonempty + -- The linear ordering on the indexing set of `b` is only used in this proof, + -- so our choice does not matter. + have : LinearOrder ι := by + choose r wo using exists_wellOrder _ + exact r + have : Fintype ι := sorry + -- why does this fail? are there two different orders in play? + have : LocallyFiniteOrderBot ι := sorry have : ∑ k', inner ℝ (leviCivitaRhs I (s i) (s j) (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • From f8cbbeaa1d7bb509b8265668a92545a2f6b5e8d3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 31 Aug 2025 19:45:31 +0200 Subject: [PATCH 362/601] chore: missing API for smul{Y,Z}_const --- .../CovariantDerivative/LeviCivita.lean | 98 ++++++++++++++++++- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 3bea02eb487234..a0943b4e93678f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -113,11 +113,23 @@ lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product ext x simp [product, real_inner_smul_left] +variable (X Y) in +@[simp] +lemma product_smul_const_left (a : ℝ) : product I (a • X) Y = a • product I X Y := by + ext x + simp [product, real_inner_smul_left] + variable (X Y) in lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by ext x simp [product, real_inner_smul_right] +variable (X Y) in +@[simp] +lemma product_smul_const_right (a : ℝ) : product I X (a • Y) = a • product I X Y := by + ext x + simp [product, real_inner_smul_right] + end product -- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) @@ -257,6 +269,20 @@ lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDi ext x simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] +variable (X) in +lemma rhs_aux_smulY_const_apply {a : ℝ} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X (a • Y) Z x = a • rhs_aux I X Y Z x := by + let f : M → ℝ := fun _ ↦ a + have h1 : rhs_aux I X (a • Y) Z x = rhs_aux I X (f • Y) Z x := by simp only [f]; congr + rw [h1, rhs_aux_smulY_apply I X mdifferentiableAt_const hY hZ] + simp [mfderiv_const] + +variable (X) in +lemma rhs_aux_smulY_const {a : ℝ} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + rhs_aux I X (a • Y) Z = a • rhs_aux I X Y Z := by + ext x + apply rhs_aux_smulY_const_apply I X (hY x) (hZ x) + variable (X) in lemma rhs_aux_smulZ_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : @@ -272,6 +298,20 @@ lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDi rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] +variable (X) in +lemma rhs_aux_smulZ_const_apply {a : ℝ} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X Y (a • Z) x = a • rhs_aux I X Y Z x := by + let f : M → ℝ := fun _ ↦ a + have h1 : rhs_aux I X Y (a • Z) x = rhs_aux I X Y (f • Z) x := by simp only [f]; congr + rw [h1, rhs_aux_smulZ_apply I X mdifferentiableAt_const hY hZ] + simp [mfderiv_const] + +variable (X) in +lemma rhs_aux_smulZ_const {a : ℝ} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + rhs_aux I X Y (a • Z) = a • rhs_aux I X Y Z := by + ext x + exact rhs_aux_smulZ_const_apply I X (hY x) (hZ x) + end rhs_aux variable {x : M} @@ -420,6 +460,46 @@ lemma leviCivitaRhs_addY [CompleteSpace E] ext x simp [leviCivitaRhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] +variable {I} in +lemma leviCivitaRhs'_smulY_const_apply [CompleteSpace E] {a : ℝ} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (a • Y) Z x = a • leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs'] + simp only [product_smul_const_left, Pi.add_apply, Pi.sub_apply, Pi.smul_apply] + rw [rhs_aux_smulY_const_apply I X hY hZ] + -- TODO: clean up this proof! + let f : M → ℝ := fun _ ↦ a + have : rhs_aux I (a • Y) Z X x = a • rhs_aux I Y Z X x := by + trans rhs_aux I (f • Y) Z X x + · rfl + rw [rhs_aux_smulX I Y (f := f) (Y := Z) (Z := X)] + rfl + rw [this, rhs_aux_smulZ_const_apply I _ hX hY] + -- is there a better abstraction for "Lie bracket conv mode"? + have : ⟪Z, mlieBracket I (a • Y) X⟫ x = a • ⟪Z, mlieBracket I Y X⟫ x := by + simp_rw [product_apply, mlieBracket_const_smul_left (W := X) hY, inner_smul_right_eq_smul] + rw [this] + have aux2 : ⟪X, mlieBracket I Z (a • Y)⟫ x = a • ⟪X, mlieBracket I Z Y⟫ x := by + simp_rw [product_apply, mlieBracket_const_smul_right (V := Z) hY, inner_smul_right_eq_smul] + rw [aux2] + simp + ring + +variable {I} in +lemma leviCivitaRhs_smulY_const_apply [CompleteSpace E] {a : ℝ} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (a • Y) Z x = a • leviCivitaRhs I X Y Z x := by + simp_rw [leviCivitaRhs, Pi.smul_apply]; rw [smul_comm] + congr + exact leviCivitaRhs'_smulY_const_apply hX hY hZ + +variable {I} in +lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X (a • Y) Z = a • leviCivitaRhs I X Y Z := by + ext x + exact leviCivitaRhs_smulY_const_apply (hX x) (hY x) (hZ x) + lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : @@ -674,11 +754,23 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] · sorry -- missing hyp! simp [← smul_assoc] smul_const_σ X σ a x hx := by - by_cases hE : Subsingleton E; · have : X x = 0 := sorry; simp [lcCandidate_aux, hE, this] + by_cases hE : Subsingleton E + · have : X x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero (X x) + simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i - -- want leviCivitaRhs_smulY (with a constant) - sorry + have hX : MDiffAt (T% X) x := sorry + have hσ : MDiffAt (T% σ) x := sorry + -- missing helper lemma + --have : MDiffAt (T% ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i)) x := sorry + rw [leviCivitaRhs_smulY_const_apply (I := I)] + rotate_left + · apply hX + · apply hσ + · sorry -- orthonormal frame is diff at x + rw [← smul_assoc] addσ X σ σ' x hσ hσ' hx := by have hX : MDiffAt (T% X) x := sorry -- missing assumption! by_cases hE : Subsingleton E; · have : X x = 0 := sorry; simp [lcCandidate_aux, hE, this] From 845024a5ac6ba619c3d4d60d12b1cf0277cef354 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 27 Sep 2025 16:38:28 +0200 Subject: [PATCH 363/601] refactor(CovariantDerivative): require the computational conditions only under appropriate smoothness hypotheses Otherwise, they do not hold for the Levi-Civita connection. Need to fix a couple more broken proofs (partially postponed for later). --- .../CovariantDerivative/Basic.lean | 220 ++++++++++-------- .../CovariantDerivative/LeviCivita.lean | 40 ++-- .../CovariantDerivative/Torsion.lean | 10 +- 3 files changed, 145 insertions(+), 125 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 284f6813b9e0c4..394a8730dff81c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -311,7 +311,7 @@ end extend section any_field variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -- [FiniteDimensional 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @@ -325,23 +325,27 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] --[VectorBundle 𝕜 F V] -- `V` vector bundle -structure IsCovariantDerivativeOn +structure IsCovariantDerivativeOn [IsManifold I 1 M] (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) (s : Set M := Set.univ) : Prop where -- All the same axioms as CovariantDerivative, but restricted to the set s. - addX (f) (X X' : Π x : M, TangentSpace I x) (σ : Π x : M, V x) {x : M} - (hx : x ∈ s := by trivial) : f (X + X') σ x = f X σ x + f X' σ x - smulX (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (g : M → 𝕜) {x : M} - (hx : x ∈ s := by trivial) : f (g • X) σ x = g x • f X σ x - addσ (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x} - (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) + addX (f) {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hσ : MDiffAt (T% σ) x) + (hx : x ∈ s := by trivial) : + f (X + X') σ x = f X σ x + f X' σ x + smulX {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {g : M → 𝕜} {x : M} + (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial) : + f (g • X) σ x = g x • f X σ x + addσ {X : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x} + (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : f X (σ + σ') x = f X σ x + f X σ' x leibniz (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {g : M → 𝕜} {x} (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x - smul_const_σ (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (a : 𝕜) {x} - (hx : x ∈ s := by trivial) : f X (a • σ) x = a • f X σ x + smul_const_σ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x} (a : 𝕜) + (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + f X (a • σ) x = a • f X σ x /-- A covariant derivative ∇ is called of class `C^k` iff, @@ -359,6 +363,8 @@ variable {F} namespace IsCovariantDerivativeOn +variable [IsManifold I 1 M] + section changing_set /-! Changing set @@ -368,30 +374,30 @@ In this changing we change `s` in `IsCovariantDerivativeOn F f s`. lemma mono {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s t : Set M} (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where - addX X X' σ _ hx := hf.addX X X' σ (hst hx) - smulX X σ f _ hx := hf.smulX X σ f (hst hx) - addσ X _ _ _ hσ hσ' hx := hf.addσ X hσ hσ' (hst hx) + addX {_X _X' _σ} _x hX hX' hσ hx := hf.addX hX hX' hσ (hst hx) + smulX {_X _σ _g} _x hX hσ hg hx := hf.smulX hX hσ hg (hst hx) + addσ {_X _σ _σ' _x} hX hσ hσ' hx := hf.addσ hX hσ hσ' (hst hx) leibniz X _ _ _ hσ hf' hx := hf.leibniz X hσ hf' (hst hx) - smul_const_σ X σ a _ hx := hf.smul_const_σ X σ a (hst hx) + smul_const_σ {_X _σ _x} a hX hσ hx := hf.smul_const_σ a hX hσ (hst hx) lemma iUnion {ι : Type*} {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : ι → Set M} (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) : IsCovariantDerivativeOn F f (⋃ i, s i) where - addX X X' σ x hx := by + addX {_X _X' _σ _x} hX hX' hσ hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addX .. - smulX X σ f x hx := by + exact (hf i).addX hX hX' hσ hxsi + smulX {_X _σ _g _x} hX hσ hg hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smulX .. - addσ X σ σ' x hσ hσ' hx := by + exact (hf i).smulX hX hσ hg hxsi + addσ {_X _σ _σ' _x} hX hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addσ _ hσ hσ' + exact (hf i).addσ hX hσ hσ' leibniz X σ f x hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).leibniz _ hσ hf' - smul_const_σ X σ a x hx := by + smul_const_σ {_X _σ _x} a hX hσ hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smul_const_σ .. + exact (hf i).smul_const_σ _ hX hσ end changing_set @@ -412,35 +418,47 @@ section computational_properties lemma smul_const_X {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} (h : IsCovariantDerivativeOn F f s) {x} (a : 𝕜) - (X : Π x, TangentSpace I x) (σ : Π x, V x) (hx : x ∈ s := by trivial) : + {X : Π x, TangentSpace I x} {σ : Π x, V x} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) + (hx : x ∈ s := by trivial) : f (a • X) σ x = a • f X σ x := - h.smulX .. + h.smulX hX hσ mdifferentiableAt_const variable {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} @[simp] lemma zeroX (hf : IsCovariantDerivativeOn F f s) {x : M} (hx : x ∈ s := by trivial) - (σ : Π x : M, V x) : f 0 σ x = 0 := by - simpa using IsCovariantDerivativeOn.addX f hf 0 0 σ hx + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : f 0 σ x = 0 := by + -- TODO: writing MDiffAt here yields an error! + have : MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (T% (fun x ↦ (0 : TangentSpace I x))) x := by + apply ContMDiff.mdifferentiableAt (n := 1) --(le_refl 1) + swap; simp_all + sorry -- zero section is smooth! + simpa using IsCovariantDerivativeOn.addX f hf (X := 0) this this hσ @[simp] lemma zeroσ [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) - (X : Π x : M, TangentSpace I x) - {x} (hx : x ∈ s := by trivial) : f X 0 x = 0 := by - simpa using (hf.addσ X (mdifferentiableAt_zeroSection ..) - (mdifferentiableAt_zeroSection ..) : f X (0+0) x = _) + {X : Π x : M, TangentSpace I x} {x} (hX : MDiffAt (T% X) x) (hx : x ∈ s := by trivial) : + f X 0 x = 0 := by + simpa using (hf.addσ hX (mdifferentiableAt_zeroSection ..) + (mdifferentiableAt_zeroSection ..) : f X (0 + 0) x = _) lemma sum_X (hf : IsCovariantDerivativeOn F f s) {ι : Type*} {u : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} - {x} (hx : x ∈ s) : + -- TODO: writing `(hX : MDifferentiableAt (T% X) x)` here yields an error + -- `Could not find universe of (x : M) → TangentSpace I x`, which is legitimate + -- (should use `X i` instead), but the error message is horrible... + {x} (hx : x ∈ s) (hX : ∀ i, MDiffAt (T% (X i)) x) (hσ : MDiffAt (T% σ) x) : f (∑ i ∈ u, X i) σ x = ∑ i ∈ u, f (X i) σ x := by classical - have := hf.zeroX hx σ + have := hf.zeroX hx hσ induction u using Finset.induction_on with - | empty => simp [hf.zeroX hx] + | empty => simp [hf.zeroX hx hσ] | insert a u ha h => - simp [Finset.sum_insert ha, ← h, hf.addX] + have : MDiffAt (T% (∑ i ∈ u, X i)) x := sorry + simp [Finset.sum_insert ha, ← h] -- hf.addX (hX a) this hσ hx] + have := hf.addX (hX a) this hσ hx + sorry -- simp only [hf.addX (hX a) this hσ hx] end computational_properties @@ -455,21 +473,21 @@ def convexCombination {f' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : IsCovariantDerivativeOn F (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where - addX X X' σ _ hx := by simp [hf.addX, hf'.addX]; module - smulX X σ φ _ hx := by simp [hf.smulX, hf'.smulX]; module - addσ X σ σ' x hx hσ hσ' := by - simp [hf.addσ X hx hσ hσ', hf'.addσ X hx hσ hσ'] - module - smul_const_σ X {σ a} x hx := by - simp [hf.smul_const_σ, hf'.smul_const_σ] - module + addX {_X _X' _σ} _ hx hX hX' hσ := by sorry -- simp [hf.addX, hf'.addX]; module + smulX {_X _σ _φ} _ hx hX hσ hφ := by sorry -- simp [hf.smulX, hf'.smulX]; module + addσ {_X _σ _σ' x} hX hσ hσ' hx := by + simp [hf.addσ hX hσ hσ', hf'.addσ hX hσ hσ'] + module + smul_const_σ {_X _σ _x} a hX hσ hx := by + simp [hf.smul_const_σ a hX hσ, hf'.smul_const_σ a hX hσ] + module leibniz X σ φ x hσ hφ hx := by - simp [hf.leibniz X hσ hφ, hf'.leibniz X hσ hφ] - module + simp [hf.leibniz X hσ hφ, hf'.leibniz X hσ hφ] + module /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination - [IsManifold I 1 M] [VectorBundle 𝕜 F V] + [VectorBundle 𝕜 F V] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) @@ -485,27 +503,27 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where - addX X X' σ x hx := by + addX {_X _X' _σ} x hx hX hX' hσ := by rw [← Finset.sum_add_distrib] congr ext i - simp [(h i).addX] - smulX X σ g x hx := by + simp [(h i).addX hx hX hX' hσ] + smulX {_X _σ _g} x hx hX hσ hg := by rw [Finset.smul_sum] congr ext i - simp [(h i).smulX] + simp [(h i).smulX hx hX hσ hg] module - addσ X σ σ' x hσ hσ' hx := by + addσ {_X _σ _σ' _x} hX hσ hσ' hx := by rw [← Finset.sum_add_distrib] congr ext i - rw [← smul_add, (h i).addσ X hσ hσ' hx] - smul_const_σ X {σ a} x hx := by + rw [← smul_add, (h i).addσ hX hσ hσ' hx] + smul_const_σ {_X _σ _x} a hX hσ hx := by rw [Finset.smul_sum] congr ext i - simp [(h i).smul_const_σ] + simp [(h i).smul_const_σ a hX hσ] module leibniz X σ g x hσ hg hx := by calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x @@ -531,7 +549,7 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] /-- A convex combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination' {n : ℕ∞} - [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} + [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) {f : ι → M → 𝕜} (hf : ∀ i ∈ s, CMDiff[u] n (f i)) : @@ -546,16 +564,15 @@ lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] (hf : IsCovariantDerivativeOn F f s) (A : Π x : M, TangentSpace I x →L[𝕜] V x →L[𝕜] V x) : IsCovariantDerivativeOn F (fun X σ x ↦ f X σ x + A x (X x) (σ x)) s where - addX X X' σ x hx := by - simp [hf.addX] + addX {_X _X' _σ} x hx hX hX' hσ := by + simp [hf.addX hx hX hX' hσ] abel - smulX X σ g x hx := by - simp [hf.smulX] - addσ X σ σ' x hσ hσ' hx := by - simp [hf.addσ X hσ hσ'] + smulX {_X _σ _g} x hx hX hσ hg := by + simp [hf.smulX hx hX hσ hg] + addσ {_X _σ _σ' _x} hX hσ hσ' hx := by + simp [hf.addσ hX hσ hσ'] abel - smul_const_σ X {σ a} x hx := by - simp [hf.smul_const_σ] + smul_const_σ {_X _σ _x} a hX hσ hx := by simp [hf.smul_const_σ a hX hσ] leibniz X σ g x hσ hg hx := by simp [hf.leibniz X hσ hg] module @@ -569,22 +586,21 @@ variable (I M F) in noncomputable def trivial [IsManifold I 1 M] : IsCovariantDerivativeOn F (V := Trivial M F) (fun X s x ↦ mfderiv I 𝓘(𝕜, F) s x (X x)) univ where - addX X X' σ x _ := by simp - smulX X σ c' x _ := by simp - addσ X σ σ' x hσ hσ' hx := by + addX {_X _X' _σ} x _ hX hX' hσ := by simp + smulX {_X _σ} c' x _ := by simp + addσ {_X σ σ' x} hX hσ hσ' hx := by rw [mdifferentiableAt_section] at hσ hσ' -- TODO: specialize mdifferentiableAt_section to trivial bundles? change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] rfl - smul_const_σ X σ a x hx := by - rw [mfderiv_const_smul] + smul_const_σ {_X _σ _x} a hX hσ hx := by rw [mfderiv_const_smul] leibniz X σ f x hσ hf hx := by rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) -lemma of_endomorphism [IsManifold I 1 M] (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : +lemma of_endomorphism (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : IsCovariantDerivativeOn F (fun (X : Π x : M, TangentSpace I x) (s : M → F) x ↦ letI d : F := mfderiv I 𝓘(𝕜, F) s x (X x) @@ -599,7 +615,7 @@ end IsCovariantDerivativeOn variable (I F V) in @[ext] -structure CovariantDerivative where +structure CovariantDerivative [IsManifold I 1 M] where toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) isCovariantDerivativeOn : IsCovariantDerivativeOn F toFun Set.univ @@ -607,6 +623,8 @@ namespace CovariantDerivative attribute [coe] toFun +variable [IsManifold I 1 M] + /-- Coercion of a `CovariantDerivative` to function -/ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := @@ -636,13 +654,11 @@ A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ -class ContMDiffCovariantDerivative [IsManifold I 1 M] - (cov : CovariantDerivative I F V) (k : ℕ∞) where +class ContMDiffCovariantDerivative (cov : CovariantDerivative I F V) (k : ℕ∞) where contMDiff : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ @[simp] -lemma contMDiffCovariantDerivativeOn_univ_iff [IsManifold I 1 M] - {cov : CovariantDerivative I F V} {k : ℕ∞} : +lemma contMDiffCovariantDerivativeOn_univ_iff {cov : CovariantDerivative I F V} {k : ℕ∞} : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ ↔ ContMDiffCovariantDerivative cov k := ⟨fun h ↦ ⟨h⟩, fun h ↦ h.contMDiff⟩ @@ -655,18 +671,20 @@ section computational_properties lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = 0 := by ext x apply cov.isCovariantDerivativeOn.zeroX + sorry @[simp] lemma zeroσ [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by ext x apply cov.isCovariantDerivativeOn.zeroσ + sorry -- misisng hypothesis! lemma sum_X (cov : CovariantDerivative I F V) {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by ext x - simpa using cov.isCovariantDerivativeOn.sum_X + sorry -- simpa using cov.isCovariantDerivativeOn.sum_X end computational_properties @@ -689,7 +707,7 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.convexCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.convexCombination [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : @@ -698,7 +716,7 @@ lemma ContMDiffCovariantDerivative.convexCombination [IsManifold I 1 M] [VectorB ContMDiffCovariantDerivativeOn.convexCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff /-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.convexCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.convexCombination' [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) @@ -720,17 +738,16 @@ variable (I M F) in noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where toFun X s x := mfderiv I 𝓘(𝕜, F) s x (X x) isCovariantDerivativeOn := -- TODO use previous work - { addX X X' σ x _ := by simp - smulX X σ c' x _ := by simp - addσ X σ σ' x hσ hσ' hx := by + { addX {_X _X' _σ} x _ hX hX' hσ := by simp + smulX {_X _σ} c' x _ := by simp + addσ {_X σ σ' x} hX hσ hσ' hx := by rw [mdifferentiableAt_section] at hσ hσ' -- TODO: specialize mdifferentiableAt_section to trivial bundles? change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] rfl - smul_const_σ X σ a x hx := by - rw [mfderiv_const_smul] + smul_const_σ {_X _σ _x} a hX hσ hx := by rw [mfderiv_const_smul] leibniz X σ f x hσ hf hx := by rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) } @@ -803,8 +820,10 @@ lemma congr_X_at [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [Vec apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' · intro f X rw [hcov.smulX] + repeat sorry -- TODO: need to assume X, σ, f are C^k at x · intro X X' rw [hcov.addX] + all_goals sorry -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x @@ -821,6 +840,8 @@ lemma differenceAux_apply (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) : differenceAux cov cov' X σ = cov X σ - cov' X σ := rfl +variable [IsManifold I 1 M] + lemma differenceAux_smul_eq {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) @@ -846,7 +867,8 @@ lemma differenceAux_smul_eq' (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) : differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by - simp [differenceAux, hcov.smulX, hcov'.smulX, smul_sub] + sorry -- TODO: need extra smoothness hypotheses! + -- simp [differenceAux, hcov.smulX, hcov'.smulX, smul_sub] /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial @@ -868,8 +890,8 @@ lemma differenceAux_tensorial apply hcov.differenceAux_smul_eq' hcov' · intro X X' unfold φ differenceAux - simp only [Pi.sub_apply, hcov.addX, hcov'.addX] - abel + sorry --simp only [Pi.sub_apply, hcov.addX, hcov'.addX] + --abel · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ differenceAux cov cov' X' σ change φ σ x₀ = φ σ' x₀ apply tensoriality_criterion (E := E) (I := I) F V F V hσ hσ' hσσ' @@ -880,6 +902,7 @@ lemma differenceAux_tensorial simp rw [hcov.addσ, hcov'.addσ] <;> try assumption abel + repeat sorry -- missing smoothness hypotheses lemma isBilinearMap_differenceAux [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] @@ -889,22 +912,25 @@ lemma isBilinearMap_differenceAux IsBilinearMap ℝ (fun (X₀ : TangentSpace I x) (σ₀ : V x) ↦ differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x) where add_left u v w := by - simp only [differenceAux, extend_add, Pi.sub_apply, hcov.addX, hcov'.addX] - abel + sorry --simp only [differenceAux, extend_add, Pi.sub_apply, hcov.addX, hcov'.addX] + --abel add_right u v w := by have hv := mdifferentiable_extend I F v x have hw := mdifferentiable_extend I F w x simp only [differenceAux, extend_add, Pi.sub_apply] rw [hcov.addσ _ hv hw, hcov'.addσ _ hv hw] abel + repeat sorry -- missing smoothness hypotheses smul_left a u v := by unfold differenceAux - simp only [extend_smul, Pi.sub_apply, hcov.smul_const_X, hcov'.smul_const_X] - module + -- need extra smoothness hypotheses! + -- simp only [extend_smul, Pi.sub_apply, hcov.smul_const_X, hcov'.smul_const_X] + sorry -- module smul_right a u v := by unfold differenceAux - simp only [extend_smul, Pi.sub_apply, hcov.smul_const_σ, hcov'.smul_const_σ] - module + -- need extra smoothness hypotheses! + sorry -- simp only [extend_smul, Pi.sub_apply, hcov.smul_const_σ, hcov'.smul_const_σ] + -- module variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -1051,7 +1077,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : replace huv : v = 0 := by simpa using huv subst huv use fun x ↦ f - simpa [hcov.zeroX, mdifferentiableAt_section] using mdifferentiableAt_const + sorry --simpa [hcov.zeroX, mdifferentiableAt_section] using mdifferentiableAt_const rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ use map_of_one_jet u w, ?_, h, h'' · rw [hcov.eq_one_form] @@ -1074,12 +1100,12 @@ noncomputable def Trivialization.covDeriv (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (x : M) : V x := e.symm x (mfderiv I 𝓘(ℝ, F) (fun x' ↦ (e (σ x')).2) x (X x)) -lemma Trivialization.covDeriv_isCovariantDerivativeOn : +lemma Trivialization.covDeriv_isCovariantDerivativeOn [IsManifold I 1 M] : IsCovariantDerivativeOn (I := I) F e.covDeriv e.baseSet where - addX X X' σ x hx := by sorry - smulX X σ c' x hx := by sorry - addσ X σ σ' x hσ hσ' hx := by sorry - smul_const_σ X σ a x hx := by sorry + addX {_X _X' _σ _x} hX hX' hσ hx := by sorry + smulX {_X _σ} c' x hX hσ hx := by sorry + addσ {_X _σ _σ' _x} hX hσ hσ' hx := by sorry + smul_const_σ {_X _σ _x} a hX hσ hx := by sorry leibniz X σ f x hσ hf hx := by sorry end from_trivialization @@ -1088,6 +1114,8 @@ end from_trivialization section horiz namespace CovariantDerivative +variable [IsManifold I 1 M] + def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := by sorry diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index a0943b4e93678f..9c1a3530d5da76 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -721,12 +721,8 @@ lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e) e.baseSet where - addX X X' σ x hx := by + addX {_X _X' _σ x} hX hX' hσ hx:= by by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] - -- these three sorries seem to be necessary! - have hX : MDiffAt (T% X) x := sorry - have hX' : MDiffAt (T% X') x := sorry - have hσ : MDiffAt (T% σ) x := sorry simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i @@ -741,19 +737,16 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (contMDiffAt_orthonormalFrame_of_mem b e i hx) |>.mdifferentiableAt le_rfl sorry -- convert this works, except for different local orders... - smulX X σ g x hx := by + smulX {_X _σ _g _x} hX hσ hg hx := by by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] simp only [lcCandidate_aux, hE, ↓reduceDIte] - have hX : MDiff (T% X) := sorry -- might need this (hopefully not!) - have hg : MDiff g := sorry -- might need this (hopefully not!) rw [Finset.smul_sum] congr; ext i - rw [leviCivitaRhs_smulX] <;> try assumption - rotate_left - · sorry -- missing hyp! - · sorry -- missing hyp! + rw [leviCivitaRhs_smulX_apply] <;> try assumption + swap + · sorry -- easy: orthonormal frame is C^n, given the basis (which is always C^n) simp [← smul_assoc] - smul_const_σ X σ a x hx := by + smul_const_σ {X _σ x} a hX hσ hx := by by_cases hE : Subsingleton E · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) @@ -761,19 +754,16 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i - have hX : MDiffAt (T% X) x := sorry - have hσ : MDiffAt (T% σ) x := sorry -- missing helper lemma --have : MDiffAt (T% ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i)) x := sorry - rw [leviCivitaRhs_smulY_const_apply (I := I)] - rotate_left - · apply hX - · apply hσ + rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] · sorry -- orthonormal frame is diff at x - rw [← smul_assoc] - addσ X σ σ' x hσ hσ' hx := by - have hX : MDiffAt (T% X) x := sorry -- missing assumption! - by_cases hE : Subsingleton E; · have : X x = 0 := sorry; simp [lcCandidate_aux, hE, this] + addσ {X σ σ' x} hX hσ hσ' hx := by + by_cases hE : Subsingleton E + · have : X x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero (X x) + simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i @@ -792,7 +782,9 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] convert this <;> sorry leibniz X σ g x hσ hg hx := by by_cases hE : Subsingleton E - · have : X x = 0 := sorry + · have : X x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero (X x) simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] sorry diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 07a743bf729ee5..f6308071c987ba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -60,9 +60,9 @@ lemma torsion_add_left_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by - simp [torsion, hf.addX X X' (x := x)] - rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] - module + sorry -- simp [torsion, hf.addX (x := x) (hx := sorry) hX hX'] + -- rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] + -- module lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) @@ -79,10 +79,10 @@ lemma torsion_smul_left_apply [CompleteSpace E] -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : torsion F (f • X) Y x = f x • torsion F X Y x := by - simp only [torsion, Pi.sub_apply, hF.smulX X Y f] + sorry /-simp only [torsion, Pi.sub_apply, hF.smulX (X := X) (σ := Y) (f := f)] rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] simp [bar, smul_sub] - abel + abel -/ variable (X) in lemma torsion_smul_right_apply [CompleteSpace E] From bec757f8c68495dcad47c0e9d0fdaefbb51fd9ab Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 27 Sep 2025 19:18:07 +0200 Subject: [PATCH 364/601] wip: start on the Leibniz rule --- .../CovariantDerivative/LeviCivita.lean | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 9c1a3530d5da76..78262758a3553f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -249,11 +249,16 @@ lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) ext x exact rhs_aux_addZ_apply I X (hY x) (hZ x) (hZ' x) +omit [IsManifold I ∞ M] in +variable (X Y Z) in +lemma rhs_aux_smulX_apply (f : M → ℝ) (x) : rhs_aux I (f • X) Y Z x = f x • rhs_aux I X Y Z x := by + simp [rhs_aux] + omit [IsManifold I ∞ M] in variable (X Y Z) in lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by ext x - simp [rhs_aux] + exact rhs_aux_smulX_apply .. variable (X) in lemma rhs_aux_smulY_apply {f : M → ℝ} @@ -500,6 +505,70 @@ lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} ext x exact leviCivitaRhs_smulY_const_apply (hX x) (hY x) (hZ x) +lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (f • Y) Z x = + f x • leviCivitaRhs' I X Y Z x + + (bar _ <| mfderiv% f x (X x)) • leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs'] + simp_rw [rhs_aux_smulX I Y Z X f] + simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul] + simp only [Pi.mul_apply] + rw [rhs_aux_smulY_apply I X hf hY hZ] + rw [rhs_aux_smulZ_apply I Z hf hX hY] + + + + have aux2 := mlieBracket_smul_right (V := Z) hf hY + have aux := mlieBracket_smul_left (W := X) hf hY + have h1 : ⟪Z, mlieBracket I (f • Y) X⟫ x = + - bar _ (((mfderiv I 𝓘(ℝ, ℝ) f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by + simp_rw [product_apply, aux, inner_add_right] + congr + · simp [bar]; rw [real_inner_smul_right] + · rw [inner_smul_right_eq_smul] + rw [h1] + + have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = + bar _ (((mfderiv I 𝓘(ℝ, ℝ) f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by + simp_rw [product_apply, aux2, inner_add_right] + congr + · simp [bar]; rw [real_inner_smul_right] + · rw [inner_smul_right_eq_smul] + rw [h2] + + set A := rhs_aux I X Y Z x + set B := rhs_aux I Y Z X x + set C := rhs_aux I Z X Y x + dsimp + set dfx := (mfderiv I 𝓘(ℝ, ℝ) f x) + set D := ⟪Y, mlieBracket I X Z⟫ x + set E := ⟪Z, mlieBracket I Y X⟫ x + set F := ⟪X, mlieBracket I Z Y⟫ x + + simp [bar] + -- obvious now? + sorry + + -- -- TODO: clean up this proof! + -- let f : M → ℝ := fun _ ↦ a + -- have : rhs_aux I (a • Y) Z X x = a • rhs_aux I Y Z X x := by + -- trans rhs_aux I (f • Y) Z X x + -- · rfl + -- rw [rhs_aux_smulX I Y (f := f) (Y := Z) (Z := X)] + -- rfl + -- rw [this, rhs_aux_smulZ_const_apply I _ hX hY] + -- -- is there a better abstraction for "Lie bracket conv mode"? + -- have : ⟪Z, mlieBracket I (a • Y) X⟫ x = a • ⟪Z, mlieBracket I Y X⟫ x := by + -- simp_rw [product_apply, mlieBracket_const_smul_left (W := X) hY, inner_smul_right_eq_smul] + -- rw [this] + -- have aux2 : ⟪X, mlieBracket I Z (a • Y)⟫ x = a • ⟪X, mlieBracket I Z Y⟫ x := by + -- simp_rw [product_apply, mlieBracket_const_smul_right (V := Z) hY, inner_smul_right_eq_smul] + -- rw [aux2] + -- simp + -- ring + +#exit lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : @@ -787,8 +856,10 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] exact Subsingleton.eq_zero (X x) simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] + -- missing lemma: simp_rw [leviCivitaRhs_smulY_apply] sorry +#exit -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : From e7fbcb417fe2ce2180397191108e6e8213eaf355 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 28 Sep 2025 11:19:40 +0200 Subject: [PATCH 365/601] Progress: last bit is figuring out the correct term, and then pushing things through! --- .../CovariantDerivative/LeviCivita.lean | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 78262758a3553f..0e02cc382ec0c6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -512,43 +512,52 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} + (bar _ <| mfderiv% f x (X x)) • leviCivitaRhs' I X Y Z x := by simp only [leviCivitaRhs'] simp_rw [rhs_aux_smulX I Y Z X f] - simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul] - simp only [Pi.mul_apply] - rw [rhs_aux_smulY_apply I X hf hY hZ] - rw [rhs_aux_smulZ_apply I Z hf hX hY] + simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] + rw [rhs_aux_smulY_apply I X hf hY hZ, rhs_aux_smulZ_apply I Z hf hX hY] - - - have aux2 := mlieBracket_smul_right (V := Z) hf hY - have aux := mlieBracket_smul_left (W := X) hf hY + -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? have h1 : ⟪Z, mlieBracket I (f • Y) X⟫ x = - bar _ (((mfderiv I 𝓘(ℝ, ℝ) f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by - simp_rw [product_apply, aux, inner_add_right] + simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] congr · simp [bar]; rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] - rw [h1] - have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = bar _ (((mfderiv I 𝓘(ℝ, ℝ) f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by - simp_rw [product_apply, aux2, inner_add_right] + simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] congr · simp [bar]; rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] - rw [h2] + rw [h1, h2, product_swap I Y Z] set A := rhs_aux I X Y Z x set B := rhs_aux I Y Z X x set C := rhs_aux I Z X Y x - dsimp - set dfx := (mfderiv I 𝓘(ℝ, ℝ) f x) set D := ⟪Y, mlieBracket I X Z⟫ x set E := ⟪Z, mlieBracket I Y X⟫ x set F := ⟪X, mlieBracket I Z Y⟫ x - - simp [bar] - -- obvious now? - sorry + set G1 := ⟪Y, Z⟫ x + set G2 := ⟪X, Y⟫ x + set dfx := (mfderiv I 𝓘(ℝ, ℝ) f x) + set H := (bar (f x)) (dfx (X x)) with H_eq + set K := (bar (f x)) (dfx (Z x)) with K_eq + change f x * A + bar _ (dfx (X x)) * G1 + f x * B - (f x * C + bar _ (dfx (Z x)) * G2) + - f x * D - (-H * G1 + f x * E) + (K * G2 + f x * F) = _ + rw [← H_eq, ← K_eq] + ring_nf + -- missing computation (if this is actually true...) + have pre : G1 + G1 = A + (B - C) + (-D - E) + F := by + simp only [G1, A, B, C, D, E, F, rhs_aux] + set A' := (mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x) + abel + sorry + have : H * G1 * 2 = A * H + (H * B - H * C) + (-(H * D) - H * E) + H * F := by + trans H * (G1 + G1) + · ring + rw [mul_comm A H, pre] + ring + rw [this] + ring -- -- TODO: clean up this proof! -- let f : M → ℝ := fun _ ↦ a From 0a4cca40711c398588a208d88c129e01df415844 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 28 Sep 2025 13:49:14 +0200 Subject: [PATCH 366/601] Complete helper computation --- .../CovariantDerivative/LeviCivita.lean | 44 +++++-------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0e02cc382ec0c6..ea499e50e27b48 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -508,8 +508,7 @@ lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs' I X (f • Y) Z x = - f x • leviCivitaRhs' I X Y Z x - + (bar _ <| mfderiv% f x (X x)) • leviCivitaRhs' I X Y Z x := by + f x • leviCivitaRhs' I X Y Z x + (bar _ <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by simp only [leviCivitaRhs'] simp_rw [rhs_aux_smulX I Y Z X f] simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] @@ -544,40 +543,19 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} change f x * A + bar _ (dfx (X x)) * G1 + f x * B - (f x * C + bar _ (dfx (Z x)) * G2) - f x * D - (-H * G1 + f x * E) + (K * G2 + f x * F) = _ rw [← H_eq, ← K_eq] - ring_nf - -- missing computation (if this is actually true...) - have pre : G1 + G1 = A + (B - C) + (-D - E) + F := by - simp only [G1, A, B, C, D, E, F, rhs_aux] - set A' := (mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x) - abel - sorry - have : H * G1 * 2 = A * H + (H * B - H * C) + (-(H * D) - H * E) + H * F := by - trans H * (G1 + G1) - · ring - rw [mul_comm A H, pre] - ring - rw [this] ring - -- -- TODO: clean up this proof! - -- let f : M → ℝ := fun _ ↦ a - -- have : rhs_aux I (a • Y) Z X x = a • rhs_aux I Y Z X x := by - -- trans rhs_aux I (f • Y) Z X x - -- · rfl - -- rw [rhs_aux_smulX I Y (f := f) (Y := Z) (Z := X)] - -- rfl - -- rw [this, rhs_aux_smulZ_const_apply I _ hX hY] - -- -- is there a better abstraction for "Lie bracket conv mode"? - -- have : ⟪Z, mlieBracket I (a • Y) X⟫ x = a • ⟪Z, mlieBracket I Y X⟫ x := by - -- simp_rw [product_apply, mlieBracket_const_smul_left (W := X) hY, inner_smul_right_eq_smul] - -- rw [this] - -- have aux2 : ⟪X, mlieBracket I Z (a • Y)⟫ x = a • ⟪X, mlieBracket I Z Y⟫ x := by - -- simp_rw [product_apply, mlieBracket_const_smul_right (V := Z) hY, inner_smul_right_eq_smul] - -- rw [aux2] - -- simp - -- ring +lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M → ℝ} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (f • Y) Z x = + f x • leviCivitaRhs I X Y Z x + (bar _ <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by + simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] + rw [smul_add, smul_comm] + congr 1 + rw [← smul_eq_mul] + match_scalars + field_simp -#exit lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : From d5caef0f56affcb9bddd94cf884f8595bffc8188 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 28 Sep 2025 14:18:13 +0200 Subject: [PATCH 367/601] Leibniz rule proven, except for sum/finsum issues --- .../CovariantDerivative/LeviCivita.lean | 41 +++++++++++++++++-- .../VectorBundle/OrthonormalFrame.lean | 9 ++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ea499e50e27b48..37413eb193c505 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -813,7 +813,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] -- missing helper lemma --have : MDiffAt (T% ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i)) x := sorry rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] - · sorry -- orthonormal frame is diff at x + · sorry -- orthonormal frame is differentiable at x addσ {X σ σ' x} hX hσ hσ' hx := by by_cases hE : Subsingleton E · have : X x = 0 := by @@ -843,10 +843,43 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] exact Subsingleton.eq_zero (X x) simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] - -- missing lemma: simp_rw [leviCivitaRhs_smulY_apply] - sorry -#exit + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + let b := Basis.ofVectorSpace ℝ E + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + + have hX : MDiffAt (T% X) x := sorry -- missing hypothesis? + let Z (i : (Basis.ofVectorSpaceIndex ℝ E)) := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) + have hZ : IsOrthonormalFrameOn I E 1 Z e.baseSet := + (Basis.ofVectorSpace ℝ E).orthonormalFrame_isOrthonormalFrameOn e + have hZ' : ∑ i, ⟪σ, Z i⟫ x • Z i x = σ x := by + calc _ + _ = ∑ i, hZ.repr i σ x • Z i x := by + congr; ext i + rw [hZ.repr_eq_inner' σ hx i, product_swap] + _ = σ x := (hZ.toIsLocalFrameOn.repr_sum_eq _ hx).symm + trans ∑ i, leviCivitaRhs I X (g • σ) (Z i) x • (Z i) x + · congr; ext i + simp [Z] + sorry -- mismatch of the chosen order, I suppose? + have (i : (Basis.ofVectorSpaceIndex ℝ E)) : MDiffAt (T% (Z i)) x := + mdifferentiableAt_orthonormalFrame_of_mem _ _ i hx + have aux (i) := leviCivitaRhs_smulY_apply I hg hX hσ (this i) + simp_rw [aux] + trans ∑ i, (g x • leviCivitaRhs I X σ (Z i) x • Z i x) + + ∑ i, ((_root_.bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x + · sorry + -- rw [Finset.sum_add_distrib] is not it, because we're not summing over a finset... + have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidate_aux I e X σ) x := by + sorry + rw [this] + congr + rw [← hZ'] + set A := _root_.bar (g x) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) + sorry -- sum over finset issue again + -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index d23ce21a1da667..0aa2b07a0b8fee 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -219,6 +219,15 @@ lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e. -- #check' contMDiffOn_orthonormalFrame_baseSet (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx +-- TODO: add more variants with mdifferentiable! +omit [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in +variable [ContMDiffVectorBundle 1 F E IB] [IsContMDiffRiemannianBundle IB 1 F E] in +variable (b e) in +lemma _root_.mdifferentiableAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e.baseSet) : + MDiffAt (T% b.orthonormalFrame e i) x := by + apply ContMDiffAt.mdifferentiableAt _ le_rfl + exact (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx + @[simp] lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : b.orthonormalFrame e i x = 0 := by From 91056752dc443ef0656a4deaa9fa5efc8a6197f2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 28 Sep 2025 14:48:31 +0200 Subject: [PATCH 368/601] Connection proof done, except for - product rule for manifold Lie bracket - ordering choice issues - finset vs std sum issues - threading one more assumption through the definition --- .../CovariantDerivative/LeviCivita.lean | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 37413eb193c505..69bf89d40db87c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -789,9 +789,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance set f := b.orthonormalFrame e i - have : MDiffAt (T% f) x := -- missing API lemma! - (contMDiffAt_orthonormalFrame_of_mem b e i hx) - |>.mdifferentiableAt le_rfl + have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx sorry -- convert this works, except for different local orders... smulX {_X _σ _g _x} hX hσ hg hx := by by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] @@ -799,9 +797,15 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] rw [Finset.smul_sum] congr; ext i rw [leviCivitaRhs_smulX_apply] <;> try assumption - swap - · sorry -- easy: orthonormal frame is C^n, given the basis (which is always C^n) - simp [← smul_assoc] + · simp [← smul_assoc] + -- side goal: orthonormal frame is differentiable + · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + let b := Basis.ofVectorSpace ℝ E + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + sorry -- works, except for different choice of order... + -- mdifferentiableAt_orthonormalFrame_of_mem _ _ i hx smul_const_σ {X _σ x} a hX hσ hx := by by_cases hE : Subsingleton E · have : X x = 0 := by @@ -810,10 +814,15 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp [lcCandidate_aux, hE, this] simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i - -- missing helper lemma - --have : MDiffAt (T% ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i)) x := sorry rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] - · sorry -- orthonormal frame is differentiable at x + · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + let b := Basis.ofVectorSpace ℝ E + have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance + set f := b.orthonormalFrame e i + have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx + sorry -- `this`, except for choice of ordering addσ {X σ σ' x} hX hσ hσ' hx := by by_cases hE : Subsingleton E · have : X x = 0 := by @@ -831,11 +840,8 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance set f := b.orthonormalFrame e i - have : MDiffAt (T% f) x := -- missing API lemma! - (contMDiffAt_orthonormalFrame_of_mem b e i hx) - |>.mdifferentiableAt le_rfl - -- mismatch between different orders; the sorry above - convert this <;> sorry + have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx + sorry -- `convert this`, except for mismatch between different orders leibniz X σ g x hσ hg hx := by by_cases hE : Subsingleton E · have : X x = 0 := by From 2d9c6c4e1abc2e492a3e00cca9c27542648b5ac5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 28 Sep 2025 14:55:27 +0200 Subject: [PATCH 369/601] refactor(CovariantDerivative): also require smoothness in the Leibniz rule This solves the last "change the definition" sorry for Levi-Civita, I believe! --- .../CovariantDerivative/Basic.lean | 45 ++++++++++--------- .../CovariantDerivative/LeviCivita.lean | 3 +- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 394a8730dff81c..66d554892c7a3c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -340,8 +340,8 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : f X (σ + σ') x = f X σ x + f X σ' x - leibniz (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {g : M → 𝕜} {x} - (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): + leibniz {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {g : M → 𝕜} {x} + (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x smul_const_σ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x} (a : 𝕜) (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : @@ -377,7 +377,7 @@ lemma mono addX {_X _X' _σ} _x hX hX' hσ hx := hf.addX hX hX' hσ (hst hx) smulX {_X _σ _g} _x hX hσ hg hx := hf.smulX hX hσ hg (hst hx) addσ {_X _σ _σ' _x} hX hσ hσ' hx := hf.addσ hX hσ hσ' (hst hx) - leibniz X _ _ _ hσ hf' hx := hf.leibniz X hσ hf' (hst hx) + leibniz {_X _σ _f _x} hX hσ hf' hx := hf.leibniz hX hσ hf' (hst hx) smul_const_σ {_X _σ _x} a hX hσ hx := hf.smul_const_σ a hX hσ (hst hx) lemma iUnion {ι : Type*} @@ -392,9 +392,9 @@ lemma iUnion {ι : Type*} addσ {_X _σ _σ' _x} hX hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).addσ hX hσ hσ' - leibniz X σ f x hσ hf' hx := by + leibniz {X σ f x} hX hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).leibniz _ hσ hf' + exact (hf i).leibniz hX hσ hf' smul_const_σ {_X _σ _x} a hX hσ hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).smul_const_σ _ hX hσ @@ -481,8 +481,8 @@ def convexCombination smul_const_σ {_X _σ _x} a hX hσ hx := by simp [hf.smul_const_σ a hX hσ, hf'.smul_const_σ a hX hσ] module - leibniz X σ φ x hσ hφ hx := by - simp [hf.leibniz X hσ hφ, hf'.leibniz X hσ hφ] + leibniz {X σ φ x} hX hσ hφ hx := by + simp [hf.leibniz hX hσ hφ, hf'.leibniz hX hσ hφ] module /-- A convex combination of two `C^k` connections is a `C^k` connection. -/ @@ -525,13 +525,13 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] ext i simp [(h i).smul_const_σ a hX hσ] module - leibniz X σ g x hσ hg hx := by + leibniz {X σ g x} hX hσ hg hx := by calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x) := by congr ext i - rw [(h i).leibniz _ hσ hg] + rw [(h i).leibniz hX hσ hg] simp_rw [Pi.smul_apply', smul_add, add_left_inj] rw [smul_comm] _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x) @@ -573,8 +573,8 @@ lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] simp [hf.addσ hX hσ hσ'] abel smul_const_σ {_X _σ _x} a hX hσ hx := by simp [hf.smul_const_σ a hX hσ] - leibniz X σ g x hσ hg hx := by - simp [hf.leibniz X hσ hg] + leibniz {X σ g x} hX hσ hg hx := by + simp [hf.leibniz hX hσ hg] module end operations @@ -596,7 +596,7 @@ noncomputable def trivial [IsManifold I 1 M] : rw [mfderiv_add hσ hσ'] rfl smul_const_σ {_X _σ _x} a hX hσ hx := by rw [mfderiv_const_smul] - leibniz X σ f x hσ hf hx := by + leibniz {X σ f x} hX hσ hf hx := by rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) @@ -748,9 +748,10 @@ noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial rw [mfderiv_add hσ hσ'] rfl smul_const_σ {_X _σ _x} a hX hσ hx := by rw [mfderiv_const_smul] - leibniz X σ f x hσ hf hx := by + leibniz {X σ f x} hX hσ hf hx := by rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) } + end trivial_bundle variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @@ -846,8 +847,9 @@ lemma differenceAux_smul_eq {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) (hcov' : IsCovariantDerivativeOn F cov' u) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) + {X : Π x : M, TangentSpace I x} (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) + (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hf : MDiffAt f x) : differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= @@ -855,7 +857,7 @@ lemma differenceAux_smul_eq _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl _ = (f x • cov X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) - (f x • cov' X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by - simp [hcov.leibniz X hσ hf, hcov'.leibniz X hσ hf] + simp [hcov.leibniz hX hσ hf, hcov'.leibniz hX hσ hf] _ = f x • cov X σ x - f x • cov' X σ x := by simp _ = f x • (cov X σ x - cov' X σ x) := by simp [smul_sub] _ = _ := rfl @@ -878,6 +880,7 @@ lemma differenceAux_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} + (hX' : MDiffAt (T% X') x₀) (hσ : MDiffAt (T% σ) x₀) (hσ' : MDiffAt (T% σ') x₀) (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) (hx : x₀ ∈ u := by trivial) : @@ -896,13 +899,12 @@ lemma differenceAux_tensorial change φ σ x₀ = φ σ' x₀ apply tensoriality_criterion (E := E) (I := I) F V F V hσ hσ' hσσ' · intro f σ x hf - exact hcov.differenceAux_smul_eq hcov' X' σ f hx hf x + exact hcov.differenceAux_smul_eq hcov' σ f hx hX' hf x · intro σ σ' hσ hσ' unfold φ differenceAux simp rw [hcov.addσ, hcov'.addσ] <;> try assumption abel - repeat sorry -- missing smoothness hypotheses lemma isBilinearMap_differenceAux [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] @@ -969,12 +971,12 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x {s : Set M} {x : M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) - (hx : x ∈ s := by trivial) (X : Π x, TangentSpace I x) {σ : Π x, V x} - (hσ : MDiffAt (T% σ) x) : + (hx : x ∈ s := by trivial) {X : Π x, TangentSpace I x} {σ : Π x, V x} + (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) : difference hcov hcov' x (X x) (σ x) = cov X σ x - cov' X σ x := by simp only [difference, hx, reduceDIte] - exact hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hσ (extend_apply_self _) + exact hcov.differenceAux_tensorial hcov' hX (mdifferentiable_extend ..) hσ (extend_apply_self _) (extend_apply_self _) hx -- The classification of real connections over a trivial bundle @@ -996,6 +998,7 @@ lemma exists_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M intro X σ x hx hσ rw [difference_apply] · module + · sorry -- TODO: missing smoothness hypothesis, right? · assumption noncomputable def one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} @@ -1106,7 +1109,7 @@ lemma Trivialization.covDeriv_isCovariantDerivativeOn [IsManifold I 1 M] : smulX {_X _σ} c' x hX hσ hx := by sorry addσ {_X _σ _σ' _x} hX hσ hσ' hx := by sorry smul_const_σ {_X _σ _x} a hX hσ hx := by sorry - leibniz X σ f x hσ hf hx := by sorry + leibniz {X σ f x} hX hσ hf hx := by sorry end from_trivialization diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 69bf89d40db87c..99ca0f0de14c70 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -842,7 +842,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] set f := b.orthonormalFrame e i have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx sorry -- `convert this`, except for mismatch between different orders - leibniz X σ g x hσ hg hx := by + leibniz {X σ g x} hX hσ hg hx := by by_cases hE : Subsingleton E · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) @@ -856,7 +856,6 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - have hX : MDiffAt (T% X) x := sorry -- missing hypothesis? let Z (i : (Basis.ofVectorSpaceIndex ℝ E)) := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have hZ : IsOrthonormalFrameOn I E 1 Z e.baseSet := (Basis.ofVectorSpace ℝ E).orthonormalFrame_isOrthonormalFrameOn e From 39baac4a68d421ea5c391c46c21b67ee8f8701b7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 28 Sep 2025 23:55:34 +0200 Subject: [PATCH 370/601] refactor: parametrise L-C connection candidate by a choice of linear order on the basis This fixes the ordering mismatch issues for proving we have a connection --- .../CovariantDerivative/LeviCivita.lean | 78 +++++++------------ 1 file changed, 29 insertions(+), 49 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 99ca0f0de14c70..3f74a00f83056f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -733,7 +733,8 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] + (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := open scoped Classical in fun X Y x ↦ @@ -743,9 +744,6 @@ noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] let b := Basis.ofVectorSpace ℝ E have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by - choose r wo using exists_wellOrder _ - exact r have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance letI frame := b.orthonormalFrame e -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` @@ -756,17 +754,19 @@ variable (M) in -- TODO: make g part of the notation! /-- Given two vector fields X and Y on TM, compute the candidate definition for the Levi-Civita connection on `TM`. -/ -noncomputable def lcCandidate [FiniteDimensional ℝ E] : +noncomputable def lcCandidate [FiniteDimensional ℝ E] + (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := -- Use the preferred trivialisation at `x` to write down a candidate for the existence. - fun X Y x ↦ lcCandidate_aux I (trivializationAt E (TangentSpace I : M → Type _) x) X Y x + fun X Y x ↦ lcCandidate_aux I (trivializationAt E (TangentSpace I : M → Type _) x) o X Y x variable (X Y) in -- The above definition behaves well: for each compatible trivialisation e, -- using e on e.baseSet yields the same result as above. lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) - [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) : - lcCandidate I M X Y x = lcCandidate_aux I e X Y x := by + [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} + {x : M} (hx : x ∈ e.baseSet) : + lcCandidate I M o X Y x = lcCandidate_aux I e o X Y x := by by_cases hE : Subsingleton E · simp [lcCandidate, lcCandidate_aux, hE] · simp only [lcCandidate, lcCandidate_aux, hE, ↓reduceDIte] @@ -775,73 +775,57 @@ lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e) e.baseSet where - addX {_X _X' _σ x} hX hX' hσ hx:= by + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] + {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : + IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e o) e.baseSet where + addX {_X _X' _σ x} hX hX' hσ hx := by by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivitaRhs_addX_apply] <;> try assumption - let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - set f := b.orthonormalFrame e i - have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx - sorry -- convert this works, except for different local orders... + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx smulX {_X _σ _g _x} hX hσ hg hx := by by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum] congr; ext i rw [leviCivitaRhs_smulX_apply] <;> try assumption · simp [← smul_assoc] - -- side goal: orthonormal frame is differentiable - · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - let b := Basis.ofVectorSpace ℝ E + · let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - sorry -- works, except for different choice of order... - -- mdifferentiableAt_orthonormalFrame_of_mem _ _ i hx + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx smul_const_σ {X _σ x} a hX hσ hx := by by_cases hE : Subsingleton E · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero (X x) simp [lcCandidate_aux, hE, this] + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidate_aux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] - · let : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := Classical.choose (exists_wellOrder _) - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - let b := Basis.ofVectorSpace ℝ E + · let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - set f := b.orthonormalFrame e i - have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx - sorry -- `this`, except for choice of ordering + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx addσ {X σ σ' x} hX hσ hσ' hx := by by_cases hE : Subsingleton E · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero (X x) simp [lcCandidate_aux, hE, this] + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidate_aux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivitaRhs_addY_apply] <;> try assumption - - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - set f := b.orthonormalFrame e i - have : MDiffAt (T% f) x := mdifferentiableAt_orthonormalFrame_of_mem b e i hx - sorry -- `convert this`, except for mismatch between different orders + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx leibniz {X σ g x} hX hσ hg hx := by by_cases hE : Subsingleton E · have : X x = 0 := by @@ -853,9 +837,6 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - let Z (i : (Basis.ofVectorSpaceIndex ℝ E)) := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) have hZ : IsOrthonormalFrameOn I E 1 Z e.baseSet := (Basis.ofVectorSpace ℝ E).orthonormalFrame_isOrthonormalFrameOn e @@ -866,9 +847,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] rw [hZ.repr_eq_inner' σ hx i, product_swap] _ = σ x := (hZ.toIsLocalFrameOn.repr_sum_eq _ hx).symm trans ∑ i, leviCivitaRhs I X (g • σ) (Z i) x • (Z i) x - · congr; ext i - simp [Z] - sorry -- mismatch of the chosen order, I suppose? + · congr have (i : (Basis.ofVectorSpaceIndex ℝ E)) : MDiffAt (T% (Z i)) x := mdifferentiableAt_orthonormalFrame_of_mem _ _ i hx have aux (i) := leviCivitaRhs_smulY_apply I hg hX hσ (this i) @@ -877,19 +856,20 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] + ∑ i, ((_root_.bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x · sorry -- rw [Finset.sum_add_distrib] is not it, because we're not summing over a finset... - have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidate_aux I e X σ) x := by + have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidate_aux I e o X σ) x := by sorry rw [this] congr rw [← hZ'] set A := _root_.bar (g x) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) - sorry -- sum over finset issue again + sorry -- sum over finset issue again -/ -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn E (lcCandidate I M) e.baseSet := by - apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidate_aux I e) + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] + {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : + IsCovariantDerivativeOn E (lcCandidate I M o) e.baseSet := by + apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidate_aux I e (o := o)) intro X σ x hx exact (bar I X σ e hx).symm From e91faa67ac2aeb8ba41c9c71b6f024918609ab48 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 00:11:19 +0200 Subject: [PATCH 371/601] TODO: need to choose an ordering once in the definition... --- .../CovariantDerivative/LeviCivita.lean | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 3f74a00f83056f..bf4faa44213fa7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -877,22 +877,33 @@ end variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] --- TODO: make g part of the notation! variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: this is unique up to the value on non-differentiable vector fields. If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ -noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : +private noncomputable def LeviCivitaConnection_aux [FiniteDimensional ℝ E] + (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : CovariantDerivative I E (TangentSpace I : M → Type _) where -- This is the existence part of the proof: take the formula derived above -- and prove it satisfies all the conditions. - toFun := lcCandidate I M + toFun := lcCandidate I M o isCovariantDerivativeOn := by rw [← iUnion_source_chartAt H M] let t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ exact isCovariantDerivativeOn_lcCandidate I _ +-- TODO: make g part of the notation! +variable (M) in +/-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: +this is unique up to the value on non-differentiable vector fields. +If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ +noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : + CovariantDerivative I E (TangentSpace I : M → Type _) := + -- TODO: somehow choose an ordering here, how to do this right? + -- let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) + LeviCivitaConnection_aux I M sorry + -- TODO: move this section to `Torsion.lean` section @@ -1047,7 +1058,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x have (X : Π y : M, TangentSpace I y) : X = 0 := sorry intro hx'' intro i j k - simp only [LeviCivitaConnection] + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate simp only [lcCandidate_aux, hE, ↓reduceDIte] @@ -1069,7 +1080,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x have aux : ∀ k, ⟪LeviCivitaConnection I M (s i) (s j), (s k)⟫ x' = ⟪LeviCivitaConnection I M (s j) (s i), (s k)⟫ x' := by intro k - simp only [LeviCivitaConnection] + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate rw [product_apply, product_apply] simp only [lcCandidate_aux, hE, ↓reduceDIte] @@ -1131,15 +1142,15 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon apply Subsingleton.eq_zero X refine ⟨?_, ?_⟩ · intro X Y Z x - simp only [LeviCivitaConnection] + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate simp [this] - · simp only [isTorsionFree_def, LeviCivitaConnection] + · simp only [isTorsionFree_def, LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate torsion ext; simp [this] refine ⟨?_, ?_⟩ · intro X Y Z x - unfold LeviCivitaConnection lcCandidate + unfold LeviCivitaConnection LeviCivitaConnection_aux lcCandidate simp only [lcCandidate_aux, hE, ↓reduceDIte] --simp [product_apply] sorry -- compatible From fb8229bbad4ee80b117036de70bad58358e95628 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 09:48:36 +0200 Subject: [PATCH 372/601] Fix last sorries in proof that nabla^g is a connection --- .../CovariantDerivative/LeviCivita.lean | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index bf4faa44213fa7..4f89b4ead7735b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -773,7 +773,8 @@ lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: Tang -- Now, start the real proof. sorry --- The candidate definition is a covariant derivative on each local frame's domain. +/-- The candidate definition `lcCandidate_aux` is a covariant derivative +on each local trivialisation's domain. -/ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : @@ -854,15 +855,12 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] simp_rw [aux] trans ∑ i, (g x • leviCivitaRhs I X σ (Z i) x • Z i x) + ∑ i, ((_root_.bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x - · sorry - -- rw [Finset.sum_add_distrib] is not it, because we're not summing over a finset... + · simp only [← Finset.sum_add_distrib, add_smul, smul_assoc] have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidate_aux I e o X σ) x := by - sorry + simp only [lcCandidate_aux, hE, ↓reduceDIte, Pi.smul_apply', Finset.smul_sum] + congr rw [this] - congr - rw [← hZ'] - set A := _root_.bar (g x) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) - sorry -- sum over finset issue again -/ + simp_rw [← hZ', smul_assoc, Finset.smul_sum] -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] From dd7d676673138075087f1c8134975560c6fa5984 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 09:49:50 +0200 Subject: [PATCH 373/601] Clean up: avoid a name clash --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 4f89b4ead7735b..0790e2fc447092 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -763,9 +763,9 @@ noncomputable def lcCandidate [FiniteDimensional ℝ E] variable (X Y) in -- The above definition behaves well: for each compatible trivialisation e, -- using e on e.baseSet yields the same result as above. -lemma bar [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) - [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} - {x : M} (hx : x ∈ e.baseSet) : +lemma lcCandidate_eq_lcCandidate_aux [FiniteDimensional ℝ E] + (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] + {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} {x : M} (hx : x ∈ e.baseSet) : lcCandidate I M o X Y x = lcCandidate_aux I e o X Y x := by by_cases hE : Subsingleton E · simp [lcCandidate, lcCandidate_aux, hE] @@ -854,7 +854,7 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have aux (i) := leviCivitaRhs_smulY_apply I hg hX hσ (this i) simp_rw [aux] trans ∑ i, (g x • leviCivitaRhs I X σ (Z i) x • Z i x) - + ∑ i, ((_root_.bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x + + ∑ i, ((bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x · simp only [← Finset.sum_add_distrib, add_smul, smul_assoc] have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidate_aux I e o X σ) x := by simp only [lcCandidate_aux, hE, ↓reduceDIte, Pi.smul_apply', Finset.smul_sum] @@ -869,7 +869,7 @@ lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] IsCovariantDerivativeOn E (lcCandidate I M o) e.baseSet := by apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidate_aux I e (o := o)) intro X σ x hx - exact (bar I X σ e hx).symm + exact (lcCandidate_eq_lcCandidate_aux I X σ e hx).symm end From e21a7cc357f60956c868e7948cb5221759f29f45 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 09:52:33 +0200 Subject: [PATCH 374/601] Choose a well-ordering in LeviCivitaConnection --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0790e2fc447092..58d9abb13908e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -898,9 +898,7 @@ this is unique up to the value on non-differentiable vector fields. If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : CovariantDerivative I E (TangentSpace I : M → Type _) := - -- TODO: somehow choose an ordering here, how to do this right? - -- let ⟨r, o⟩ := exists_wellOrder (↑(Basis.ofVectorSpaceIndex ℝ E)) - LeviCivitaConnection_aux I M sorry + LeviCivitaConnection_aux I M (Classical.choose (exists_wellOrder _)) -- TODO: move this section to `Torsion.lean` section From 9a7b338e92e475ecefd0aaf0a842730d762d37d5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 09:56:14 +0200 Subject: [PATCH 375/601] Rename lcCandidate_aux -> lcCandidateAux to better match the naming convention. And extend the docs somewhat --- .../CovariantDerivative/LeviCivita.lean | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 58d9abb13908e1..5bf16d5e818788 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -732,7 +732,11 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] · exact hcov.eq_leviCivitaRhs I X σ Z · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm -noncomputable def lcCandidate_aux [FiniteDimensional ℝ E] +/-- Auxiliary definition towards defining the Levi-Civita connection on `M`: +given a trivialisation `e` and a choice `o` of linear order on the standard basis of `E`, +we take the expression defined by the Koszul formula (using the orthonormal frame determined by `e` +and `o`). -/ +noncomputable def lcCandidateAux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := @@ -758,31 +762,31 @@ noncomputable def lcCandidate [FiniteDimensional ℝ E] (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := -- Use the preferred trivialisation at `x` to write down a candidate for the existence. - fun X Y x ↦ lcCandidate_aux I (trivializationAt E (TangentSpace I : M → Type _) x) o X Y x + fun X Y x ↦ lcCandidateAux I (trivializationAt E (TangentSpace I : M → Type _) x) o X Y x variable (X Y) in --- The above definition behaves well: for each compatible trivialisation e, --- using e on e.baseSet yields the same result as above. -lemma lcCandidate_eq_lcCandidate_aux [FiniteDimensional ℝ E] +/-- The definition `lcCandidate` behaves well: for each compatible trivialisation `e`, +the candidate definition using `e` agrees with `lcCandidate` on `e.baseSet`. -/ +lemma lcCandidate_eq_lcCandidateAux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} {x : M} (hx : x ∈ e.baseSet) : - lcCandidate I M o X Y x = lcCandidate_aux I e o X Y x := by + lcCandidate I M o X Y x = lcCandidateAux I e o X Y x := by by_cases hE : Subsingleton E - · simp [lcCandidate, lcCandidate_aux, hE] - · simp only [lcCandidate, lcCandidate_aux, hE, ↓reduceDIte] + · simp [lcCandidate, lcCandidateAux, hE] + · simp only [lcCandidate, lcCandidateAux, hE, ↓reduceDIte] -- Now, start the real proof. sorry -/-- The candidate definition `lcCandidate_aux` is a covariant derivative +/-- The candidate definition `lcCandidateAux` is a covariant derivative on each local trivialisation's domain. -/ -lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] +lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : - IsCovariantDerivativeOn E (lcCandidate_aux I (M := M) e o) e.baseSet where + IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet where addX {_X _X' _σ x} hX hX' hσ hx := by - by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] + by_cases hE : Subsingleton E; · simp [lcCandidateAux, hE] have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivitaRhs_addX_apply] <;> try assumption @@ -790,9 +794,9 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx smulX {_X _σ _g _x} hX hσ hg hx := by - by_cases hE : Subsingleton E; · simp [lcCandidate_aux, hE] + by_cases hE : Subsingleton E; · simp [lcCandidateAux, hE] have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] rw [Finset.smul_sum] congr; ext i rw [leviCivitaRhs_smulX_apply] <;> try assumption @@ -805,9 +809,9 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero (X x) - simp [lcCandidate_aux, hE, this] + simp [lcCandidateAux, hE, this] have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] · let b := Basis.ofVectorSpace ℝ E @@ -818,9 +822,9 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero (X x) - simp [lcCandidate_aux, hE, this] + simp [lcCandidateAux, hE, this] have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i rw [leviCivitaRhs_addY_apply] <;> try assumption @@ -832,8 +836,8 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] · have : X x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero (X x) - simp [lcCandidate_aux, hE, this] - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp [lcCandidateAux, hE, this] + simp only [lcCandidateAux, hE, ↓reduceDIte] have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE let b := Basis.ofVectorSpace ℝ E @@ -856,8 +860,8 @@ lemma isCovariantDerivativeOn_lcCandidate_aux [FiniteDimensional ℝ E] trans ∑ i, (g x • leviCivitaRhs I X σ (Z i) x • Z i x) + ∑ i, ((bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x · simp only [← Finset.sum_add_distrib, add_smul, smul_assoc] - have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidate_aux I e o X σ) x := by - simp only [lcCandidate_aux, hE, ↓reduceDIte, Pi.smul_apply', Finset.smul_sum] + have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidateAux I e o X σ) x := by + simp only [lcCandidateAux, hE, ↓reduceDIte, Pi.smul_apply', Finset.smul_sum] congr rw [this] simp_rw [← hZ', smul_assoc, Finset.smul_sum] @@ -867,9 +871,9 @@ lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : IsCovariantDerivativeOn E (lcCandidate I M o) e.baseSet := by - apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidate_aux I e (o := o)) + apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidateAux I e (o := o)) intro X σ x hx - exact (lcCandidate_eq_lcCandidate_aux I X σ e hx).symm + exact (lcCandidate_eq_lcCandidateAux I X σ e hx).symm end @@ -1056,7 +1060,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x intro i j k simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t @@ -1079,7 +1083,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate rw [product_apply, product_apply] - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] -- Choose a linear order on ι: which one really does not matter for our result. have : LinearOrder ι := by choose r wo using exists_wellOrder _ @@ -1147,7 +1151,7 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon refine ⟨?_, ?_⟩ · intro X Y Z x unfold LeviCivitaConnection LeviCivitaConnection_aux lcCandidate - simp only [lcCandidate_aux, hE, ↓reduceDIte] + simp only [lcCandidateAux, hE, ↓reduceDIte] --simp [product_apply] sorry -- compatible · let s : M → Set M := fun x ↦ (trivializationAt E (fun (x : M) ↦ TangentSpace I x) x).baseSet From 42173f48a2ae31f65320d5b51b98ff24529d0629 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 10:15:27 +0200 Subject: [PATCH 376/601] Wip: further in Christoffel symbols --- .../CovariantDerivative/LeviCivita.lean | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 5bf16d5e818788..a5276a2c9f02b0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -919,6 +919,15 @@ noncomputable def ChristoffelSymbol (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := hs.repr k (f (s i) (s j)) +-- special case of `foobar` below; needed? +lemma ChristoffelSymbol.sum_eq + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j : ι) (hx : x ∈ U) : + f (s i) (s j) x = ∑ k, (ChristoffelSymbol I f hs i j k x) • (s k) x := by + simp only [ChristoffelSymbol] + exact hs.repr_sum_eq _ hx + variable {U : Set M} {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} @@ -936,6 +945,33 @@ lemma eq_product_apply [Fintype ι] have : LocallyFiniteOrderBot ι := by sorry rw [ChristoffelSymbol, hs.repr_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] +-- Lemma 4.3 in Lee, Chapter 5: first term still missing +lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeOn E f U) + (hs : IsLocalFrameOn I E 1 s U) {x : M} (hx : x ∈ U) : + f X Y x = ∑ k, + letI S₁ := ∑ i, ∑ j, (hs.repr i X) * (hs.repr j Y) * (ChristoffelSymbol I f hs i j k) + letI S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! + S₁ x • s k x := by + have hY := hs.repr_sum_eq Y hx + -- should this be a separate lemma also? + have : ∀ x ∈ U, Y x = ∑ i, (hs.repr i) Y x • s i x := by + intro x hx + apply hs.repr_sum_eq Y hx + have : f X Y x = f X (fun x ↦ ∑ i, (hs.repr i) Y x • s i x) x := by + -- apply `congr_σ_of_eventuallyEq` from Basic.lean (after restoring it) + -- want U to be a neighbourhood of x to make this work + sorry + rw [this] + -- straightforward computation: use linearity and Leibniz rule + sorry + +/- TODO: prove some basic properties, such as +- the Christoffel symbols are linear in cov +- if (s_i) is a smooth local frame on U, then cov is smooth on U iff each Christoffel symbol is (?) +- prove a `spec` equality +- deduce: two covariant derivatives are equal iff their Christoffel symbols are equal +-/ + lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) (hs : IsLocalFrameOn I E n s U) @@ -978,22 +1014,6 @@ end variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} -lemma foobar (hf : IsCovariantDerivativeOn E f U) - (hs : IsLocalFrameOn I E 1 s U) (x : M) : - f X Y x = ∑ k, - let S₁ := ∑ i, ∑ j, (hs.repr i X) * (hs.repr j Y) * (ChristoffelSymbol I f hs i j k) - let S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! - S₁ x • s k x := - -- straightforward computation: write Y = ∑ i, hs.repr i Y and use linearity and Leibniz rule - sorry - -/- TODO: prove some basic properties, such as -- the Christoffel symbols are linear in cov -- if (s_i) is a smooth local frame on U, then cov is smooth on U iff each Christoffel symbol is (?) -- prove a `spec` equality -- deduce: two covariant derivatives are equal iff their Christoffel symbols are equal --/ - -- errors: omit [IsContMDiffRiemannianBundle I 1 E fun x ↦ TangentSpace I x] in /-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, From 512aac4b4f3d9656d05aa34255b8fe2d4fc253bb Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 29 Sep 2025 14:49:33 +0200 Subject: [PATCH 377/601] Prove a congruence lemma. --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 66d554892c7a3c..246223edaca4ab 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -409,7 +409,12 @@ lemma congr {f g : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : -- Is this too strong? Will see! (hfg : ∀ {X : Π x : M, TangentSpace I x}, ∀ {σ : Π x : M, V x}, ∀ {x}, x ∈ s → f X σ x = g X σ x) : - IsCovariantDerivativeOn F g s := sorry + IsCovariantDerivativeOn F g s where + addX hX hX' hσ hx := by simp [← hfg hx, hf.addX hX hX' hσ] + smulX hX hσ hg hx := by simp [← hfg hx, hf.smulX hX hσ hg] + addσ hX hσ hσ' hx := by simp [← hfg hx, hf.addσ hX hσ hσ'] + leibniz hX hσ hf' hx := by simp [← hfg hx, hf.leibniz hX hσ hf'] + smul_const_σ a hX hσ hx := by simp [← hfg hx, hf.smul_const_σ a hX hσ] end From b16216c0360ed1d1ea01fb6bcf91a53452e72674 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 10:34:45 +0200 Subject: [PATCH 378/601] More --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index a5276a2c9f02b0..6e6365bdfcc610 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -1076,16 +1076,16 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) apply Subsingleton.eq_zero X have (X : Π y : M, TangentSpace I y) : X = 0 := sorry - intro hx'' - intro i j k - simp only [LeviCivitaConnection, LeviCivitaConnection_aux] + intro x'' hx'' i j k + simp only [LeviCivitaConnection_aux] unfold lcCandidate simp only [lcCandidateAux, hE, ↓reduceDIte] letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t - --have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k - sorry -- this should do it! + have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k + -- now, use a congruence result and the first `have` + sorry -- Note that hs is not necessarily an orthonormal frame, so we cannot simply rewrite -- the Christoffel symbols as Γᵢⱼᵏ = ⟪∇ᵍ X Y, Z⟫`: however, the result we wants to prove boils -- down to proving the same. From 8dc2edd6233ca246019c68855ccf15d47df420ea Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 18:54:49 +0200 Subject: [PATCH 379/601] Fix the build --- .../Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean | 4 ++-- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean index bd4c9571557410..4e04abb735a264 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean @@ -240,7 +240,7 @@ noncomputable def mynorm (φ : G →L[ℝ] G →L[ℝ] ℝ) : Seminorm ℝ G whe noncomputable def aux (φ : G →L[ℝ] G →L[ℝ] ℝ) : SeminormFamily ℝ G (Fin 1) := fun _ ↦ mynorm φ -lemma bar (φ : G →L[ℝ] G →L[ℝ] ℝ) (hpos : ∀ v : G, v ≠ 0 → 0 < φ v v) : WithSeminorms (aux φ) := +lemma hoge (φ : G →L[ℝ] G →L[ℝ] ℝ) (hpos : ∀ v : G, v ≠ 0 → 0 < φ v v) : WithSeminorms (aux φ) := -- In finite dimension there is a single topological vector space structure... -- and mynorm defines a norm, hence a TVS structure. sorry @@ -263,7 +263,7 @@ lemma aux_tvs (G : Type*) [AddCommGroup G] [TopologicalSpace G] [Module ℝ G] -- (as in finite dimension there is a single topological vector space structure). -- The unit ball for the norm is von Neumann bounded wrt the topology defined by the norm -- (we have this in mathlib), so also for the initial topology. - rw [WithSeminorms.isVonNBounded_iff_finset_seminorm_bounded (p := aux φ) (bar φ hpos)] + rw [WithSeminorms.isVonNBounded_iff_finset_seminorm_bounded (p := aux φ) (hoge φ hpos)] intro I letI J : Finset (Fin 1) := {1} suffices ∃ r > 0, ∀ x ∈ {v | (φ v) v < 1}, (J.sup (aux φ)) x < r by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 6e6365bdfcc610..0dce5c84976387 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -1077,7 +1077,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x apply Subsingleton.eq_zero X have (X : Π y : M, TangentSpace I y) : X = 0 := sorry intro x'' hx'' i j k - simp only [LeviCivitaConnection_aux] + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate simp only [lcCandidateAux, hE, ↓reduceDIte] From 0c74fdf7fd1128a8c6a1c682b31b34a92ef2735f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 29 Sep 2025 20:19:27 +0200 Subject: [PATCH 380/601] chore: split big "is a connection" proof in two --- .../CovariantDerivative/Basic.lean | 20 ++++++++++ .../CovariantDerivative/LeviCivita.lean | 39 +++++++------------ 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 246223edaca4ab..478ccb77b04f77 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -365,6 +365,26 @@ namespace IsCovariantDerivativeOn variable [IsManifold I 1 M] +variable (E) in +/-- If `E` is the trivial vector space, the axioms of a covariant derivative are vacuous. -/ +lemma of_subsingleton [hE : Subsingleton E] + (f : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → + ((x : M) → TangentSpace I x)) : + IsCovariantDerivativeOn E f Set.univ := by + have (X) (Y) (x) : f X Y x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero _ + exact { + addX {_X _X' _σ x} hX hX' hσ hx := by simp [this] + smulX {_X _σ _g _x} hX hσ hg hx := by simp [this] + smul_const_σ {X _σ x} a hX hσ hx := by simp [this] + addσ {X σ σ' x} hX hσ hσ' hx := by simp [this] + leibniz {X σ g x} hX hσ hg hx := by + have hσ : σ x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero _ + simp [this, hσ] } + section changing_set /-! Changing set diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0dce5c84976387..3488d697ac7025 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -777,15 +777,12 @@ lemma lcCandidate_eq_lcCandidateAux [FiniteDimensional ℝ E] -- Now, start the real proof. sorry -/-- The candidate definition `lcCandidateAux` is a covariant derivative -on each local trivialisation's domain. -/ -lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] +lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ E] + (hE : ¬(Subsingleton E)) [Nontrivial E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet where addX {_X _X' _σ x} hX hX' hσ hx := by - by_cases hE : Subsingleton E; · simp [lcCandidateAux, hE] - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidateAux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i @@ -794,8 +791,6 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx smulX {_X _σ _g _x} hX hσ hg hx := by - by_cases hE : Subsingleton E; · simp [lcCandidateAux, hE] - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidateAux, hE, ↓reduceDIte] rw [Finset.smul_sum] congr; ext i @@ -805,12 +800,6 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx smul_const_σ {X _σ x} a hX hσ hx := by - by_cases hE : Subsingleton E - · have : X x = 0 := by - have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - exact Subsingleton.eq_zero (X x) - simp [lcCandidateAux, hE, this] - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidateAux, hE, ↓reduceDIte] rw [Finset.smul_sum]; congr; ext i rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] @@ -818,12 +807,6 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx addσ {X σ σ' x} hX hσ hσ' hx := by - by_cases hE : Subsingleton E - · have : X x = 0 := by - have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - exact Subsingleton.eq_zero (X x) - simp [lcCandidateAux, hE, this] - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE simp only [lcCandidateAux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i @@ -832,14 +815,7 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx leibniz {X σ g x} hX hσ hg hx := by - by_cases hE : Subsingleton E - · have : X x = 0 := by - have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - exact Subsingleton.eq_zero (X x) - simp [lcCandidateAux, hE, this] simp only [lcCandidateAux, hE, ↓reduceDIte] - - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty let Z (i : (Basis.ofVectorSpaceIndex ℝ E)) := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) @@ -866,6 +842,17 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] rw [this] simp_rw [← hZ', smul_assoc, Finset.smul_sum] +/-- The candidate definition `lcCandidateAux` is a covariant derivative +on each local trivialisation's domain. -/ +lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] + {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : + IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet := by + by_cases hE : Subsingleton E + · exact (IsCovariantDerivativeOn.of_subsingleton E _).mono (Set.subset_univ _) + · have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + exact isCovariantDerivativeOn_lcCandidateAux_of_nonempty I hE e + -- The candidate definition is a covariant derivative on each local frame's domain. lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] From cc0d145b13ca9eb6a900f0dc612cccec8d75ad5c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 30 Sep 2025 19:14:40 +0200 Subject: [PATCH 381/601] chore(Elaborators): synchronise with upstream PR's changes --- Mathlib/Geometry/Manifold/Elaborators.lean | 270 ++++++++++----------- 1 file changed, 135 insertions(+), 135 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index d318b09a86f5ae..c5cb4eb20255ab 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -3,9 +3,8 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.Tangent -import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.ContMDiff.Defs +import Mathlib.Geometry.Manifold.MFDeriv.Defs import Mathlib.Geometry.Manifold.Traces /-! @@ -14,23 +13,28 @@ import Mathlib.Geometry.Manifold.Traces This file defines custom elaborators for differential geometry, to allow for more compact notation. There are two classes of elaborators. The first provides more compact notation for differentiability and continuous differentiability on manifolds, including inference of the model with corners. -They allow writing +All these elaborators are scoped to the `Manifold` namespace. They allow writing - `MDiff f` for `MDifferentiable I J f` - `MDiffAt f x` for `MDifferentiableAt I J f x` - `MDiff[u] f` for `MDifferentiableOn I J f u` -- `MDiffAt[u] f` for `DifferentiableWithinAt I J f u x` +- `MDiffAt[u] f x` for `MDifferentiableWithinAt I J f u x` - `CMDiff n f` for `ContMDiff I J n f` - `CMDiffAt n f x` for `ContMDiffAt I J n f x` - `CMDiff[u] n f` for `ContMDiffOn I J n f u` -- `CMDiffAt[u] n f` for `ContMDiffWithinAt I J n f u x`, -- `mfderiv[u] f x` for `mfderivWithin I J f s x`, +- `CMDiffAt[u] n f x` for `ContMDiffWithinAt I J n f u x`, +- `mfderiv[u] f x` for `mfderivWithin I J f u x`, - `mfderiv% f x` for `mfderiv I J f x`. In each of these cases, the models with corners are inferred from the domain and codomain of `f`. The search for models with corners uses the local context and is (almost) only syntactic, hence hopefully fast enough to always run. -Secondly, this space adds an elaborator to ease working with sections in a fibre bundle, +This has no dedicated support for product manifolds (or product vector spaces) yet; +adding this is left for future changes. (It would need to make a choice between e.g. the +trivial model with corners on a product `E × F` and the product of the trivial models on `E` and +`F`). In these settings, the elaborators should be avoided (for now). + +Secondly, this file adds an elaborator to ease working with sections in a fibre bundle, converting a section `s : Π x : M, Π V x` to a non-dependent function into the total space of the bundle. ```lean @@ -55,21 +59,23 @@ prototype. Don't rewrite all of mathlib to use it just yet. Notable bugs and lim the following. ## TODO -- extend the feature to infer e.g. models with corners on product manifolds +- extend the elaborators to guess models with corners on product manifolds (this has to make a guess, hence cannot always be correct: but it could make the guess that is correct 90% of the time) + For products of vector spaces `E × F`, this could print a warning about making a choice between + the model in `E × F` and the product of the models on `E` and `F`. +- extend the elaborators to support `PartialHomeomorph`s and `PartialEquiv`s + - fix pretty-printing: currently, the `commandStart` linter expects some different formatting -- better error messages: forgetting e.g. the `T%` elaborator yields cryptic errors -- make all these elaborators scoped to the `Manifold` namespace +- better error messages (as needed) - further testing and fixing of edge cases -- add test for the difference between `CMDiff` and `ContMDiff%` (and decide on one behaviour) -- added tests for all of the above +- add tests for all of the above +- add delaborators for these elaborators -/ open scoped Bundle Manifold ContDiff -section open Lean Meta Elab Tactic open Mathlib.Tactic @@ -84,6 +90,8 @@ def _root_.Lean.Expr.getUniverse (e : Expr) : TermElabM (Level) := do @[match_pattern] def mkApp12 (f a b c d e g e₁ e₂ e₃ e₄ e₅ e₆ : Expr) := mkApp6 (mkApp6 f a b c d e g) e₁ e₂ e₃ e₄ e₅ e₆ +namespace Manifold + /-- Elaborator for sections in a fibre bundle: converts a section as a dependent function to a non-dependent function into the total space. This handles the cases of - sections of a trivial bundle @@ -95,17 +103,17 @@ This elaborator operates purely syntactically, by analysing the local contexts f hypothesis for the above cases. Therefore, it is (hopefully) fast enough to always run. -/ -- TODO: document how this elaborator works, any gotchas, etc. -elab "T% " t:term : term => do +elab:max "T% " t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars match etype with - | .forallE x base (mkApp3 (.const `Bundle.Trivial _) E E' _) _ => + | .forallE x base (mkApp3 (.const ``Bundle.Trivial _) E E' _) _ => trace[TotalSpaceMk] "Section of a trivial bundle" - if E == base then + if ← withReducible (isDefEq E base) then return ← withLocalDecl x BinderInfo.default base fun x ↦ do let body ← mkAppM ``Bundle.TotalSpace.mk' #[E', x, .app e x] mkLambdaFVars #[x] body - | .forallE x base (mkApp12 (.const `TangentSpace _) _k _ E _ _ _H _ _I _M _ _ _x) _ => + | .forallE x base (mkApp12 (.const ``TangentSpace _) _k _ E _ _ _H _ _I _M _ _ _x) _ => trace[TotalSpaceMk] "Vector field" return ← withLocalDecl x BinderInfo.default base fun x ↦ do let body ← mkAppM ``Bundle.TotalSpace.mk' #[E, x, .app e x] @@ -116,7 +124,7 @@ elab "T% " t:term : term => do let decltype ← inferType decl >>= instantiateMVars match decltype with | mkApp7 (.const `FiberBundle _) _ F _ _ E _ _ => - if E == V then + if ← withReducible (isDefEq E V) then return ← withLocalDecl x BinderInfo.default base fun x ↦ do let body ← mkAppM ``Bundle.TotalSpace.mk' #[F, x, .app e x] mkLambdaFVars #[x] body @@ -125,16 +133,22 @@ elab "T% " t:term : term => do trace[TotalSpaceMk] "Section of a trivial bundle as a non-dependent function" let us ← src.getUniverse let ut ← tgt.getUniverse - let triv_bundle := mkAppN (.const `Bundle.Trivial [us, ut]) #[src, tgt] + -- TODO: can `tgt` depend on `x` in a way that is not a function application? + -- Check that `x` is not a bound variable in `tgt`! + -- xxx: is this check fine or overzealous? + if Lean.Expr.hasLooseBVars tgt then + throwError m!"Term {tgt} has loose bound variables¬ + Hint: applying the 'T%' elaborator twice makes no sense." + let trivBundle := mkAppN (.const `Bundle.Trivial [us, ut]) #[src, tgt] return ← withLocalDecl x BinderInfo.default src fun x ↦ do let body := mkAppN (.const ``Bundle.TotalSpace.mk' [us, ut, ut]) - #[src, triv_bundle, tgt, x, .app e x] + #[src, trivBundle, tgt, x, .app e x] mkLambdaFVars #[x] body | _ => pure () return e -/-- Try to find a `ModelWithCorners` instance on an expression `e`, using the local context -to infer the expected type. This supports the following cases: +/-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), +using the local context to infer the expected type. This supports the following cases: - the model with corners on the total space of a vector bundle - a model with corners on a manifold - the trivial model `𝓘(𝕜, E)` on a normed space @@ -142,16 +156,24 @@ to infer the expected type. This supports the following cases: and if successful, return `𝓘(𝕜)`. Further cases can be added as necessary. -This implementation is not maximally robust yet, but already useful. + +Return an expression describing the found model with corners. + +`baseInfo` is only used for the first case, a model with corners on the total space of the vector +bundle. In this case, it contains a pair of expressions `(e, i)` describing the type of the base +and the model with corners on the base: these are required to construct the right model with +corners. + +This implementation is not maximally robust yet. -/ -- FIXME: better failure when trying to find a `NormedField` instance def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do trace[MDiffElab] m!"Searching a model for: {e}" - if let mkApp3 (.const `Bundle.TotalSpace _) _ F V := e then - if let mkApp12 (.const `TangentSpace _) _k _ _E _ _ _H _ I M _ _ _x := V then + if let mkApp3 (.const ``Bundle.TotalSpace _) _ F V := e then + if let mkApp12 (.const ``TangentSpace _) _k _ _E _ _ _H _ I M _ _ _x := V then trace[MDiffElab] m!"This is the total space of the tangent bundle of {M}" let srcIT : Term ← PrettyPrinter.delab I - let resTerm : Term ← `(ModelWithCorners.prod $srcIT ModelWithCorners.tangent $srcIT) + let resTerm : Term ← ``(ModelWithCorners.prod $srcIT ModelWithCorners.tangent $srcIT) let res ← Term.elabTerm resTerm none trace[MDiffElab] m!"Found model: {res}" return res @@ -164,7 +186,7 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM for decl in ← getLocalHyps do let decltype ← inferType decl >>= instantiateMVars match decltype with - | mkApp4 (.const `NormedSpace _) K' E _ _ => + | mkApp4 (.const ``NormedSpace _) K' E _ _ => if E == F then K := K' trace[MDiffElab] m!"{F} is a normed field over {K}" @@ -177,11 +199,10 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM let kT : Term ← PrettyPrinter.delab K let srcIT : Term ← PrettyPrinter.delab srcI let FT : Term ← PrettyPrinter.delab F - let iTerm : Term ← `(ModelWithCorners.prod $srcIT 𝓘($kT, $FT)) + let iTerm : Term ← ``(ModelWithCorners.prod $srcIT 𝓘($kT, $FT)) let I ← Term.elabTerm iTerm none trace[MDiffElab] m!"Found model: {I}" return I - else throwError "Having a TotalSpace as source is not yet supported" let mut H : Expr := default @@ -192,12 +213,12 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM for decl in ← getLocalHyps do let decltype ← inferType decl >>= instantiateMVars match decltype with - | mkApp4 (.const `ChartedSpace _) H' _ M _ => + | mkApp4 (.const ``ChartedSpace _) H' _ M _ => if M == e then H := H' trace[MDiffElab] m!"H is: {H}" Hok := true - | mkApp4 (.const `NormedSpace _) K' E _ _ => + | mkApp4 (.const ``NormedSpace _) K' E _ _ => if E == e then K := K' trace[MDiffElab] m!"Field is: {K}" @@ -208,15 +229,15 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM if Kok then let eT : Term ← PrettyPrinter.delab e let eK : Term ← PrettyPrinter.delab K - let iTerm : Term ← `(𝓘($eK, $eT)) + let iTerm : Term ← ``(𝓘($eK, $eT)) let I ← Term.elabTerm iTerm none trace[MDiffElab] m!"Found model: {I}" return I -- let uK ← K.getUniverse - -- let normedFieldK ← synthInstance (.app (.const `NontriviallyNormedField [uK]) K) + -- let normedFieldK ← synthInstance (.app (.const ``NontriviallyNormedField [uK]) K) -- trace[MDiffElab] m!"NontriviallyNormedField instance is: {normedFieldK}" -- let ue ← e.getUniverse - -- let normedGroupE ← synthInstance (.app (.const `NormedAddCommGroup [ue]) e) + -- let normedGroupE ← synthInstance (.app (.const ``NormedAddCommGroup [ue]) e) -- trace[MDiffElab] m!"NormedAddCommGroup instance is: {normedGroupE}" -- return mkAppN (.const `modelWithCornersSelf [uK, ue]) -- #[K, normedFieldK, e, normedGroupE, normedSpaceInst] @@ -224,12 +245,11 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM for decl in ← getLocalHyps do let decltype ← inferType decl >>= instantiateMVars match decltype with - | mkApp7 (.const `ModelWithCorners _) _ _ _ _ _ H' _ => + | mkApp7 (.const ``ModelWithCorners _) _ _ _ _ _ H' _ => if H' == H then trace[MDiffElab] m!"Found model: {decl}" return decl | _ => pure () - -- throwError m!"Couldn’t find models with corners with H = {H}" else trace[MDiffElab] m!"Hoping {e} is a normed field" let eT : Term ← PrettyPrinter.delab e @@ -237,10 +257,26 @@ def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM let I ← Term.elabTerm iTerm none trace[MDiffElab] m!"Found model: {I}" return I - throwError "Couldn’t find models with corners" --- TODO: scope all these elaborators to the `Manifold` namespace +/-- If `etype` is a non-dependent function between spaces `src` and `tgt`, try to find a model with +corners on both `src` and `tgt`. If successful, return both models. + +`ef` is the term having type `etype`: this is used only for better diagnostics. +If `estype` is `some`, we verify that `src` and `estype` are def-eq. (TODO: implement this!) -/ +-- TODO: pass in an additional type, to be checked equivalent to `src`, and validate this! +def _find_models (etype eterm : Expr) (_estype : Option Expr) : + TermElabM (Option (Expr × Expr)) := do + match etype with + | .forallE _ src tgt _ => + let srcI ← find_model src + if Lean.Expr.hasLooseBVars tgt then + throwError m!"Term {eterm} is a dependent function, of type {etype}\n\ + Hint: you can use the 'T%' elaborator to convert a dependent function to a non-dependent one" + let tgtI ← find_model tgt (src, srcI) + -- TODO: check that `estype` and src are defeq! + return some (srcI, tgtI) + | _ => return none /-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, trying to determine `I` and `J` from the local context. @@ -250,13 +286,9 @@ elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do let ef ← Term.elabTerm f none let etype ← inferType ef >>= instantiateMVars let _estype ← inferType ef >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - -- TODO: check that `estype` and src are compatible/the same! - return ← mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] - | _ => throwError m!"Term {ef} is not a function." + match ← _find_models etype ef _estype with + | some (srcI, tgtI) => return ← mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] + | none => throwError m!"Term {ef} is not a function." /-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, trying to determine `I` and `J` from the local context. @@ -264,154 +296,122 @@ The argument `x` can be omitted. -/ elab:max "MDiffAt" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] - | _ => throwError m!"Term {e} is not a function." + match ← _find_models etype e none with + | some (srcI, tgtI) => return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] + | none => throwError m!"Term {e} is not a function." --- FIXME: remove in favour of MDiffAt (once that one is scoped) -elab:max "MDifferentiableAt%" t:term:arg : term => do +-- This implement is more robust (in theory), but currently fails tests. +-- TODO: investigate why, fix this and replace `MDiffAt` by this one! +/-- `MDiffAt2 f x` elaborates to `MDifferentiableAt I J f x`, +trying to determine `I` and `J` from the local context. +The argument `x` can be omitted. -/ +elab:max "MDiffAt2" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] - | _ => throwError m!"Term {e} is not a function." + forallBoundedTelescope etype (some 1) fun src tgt ↦ do + if let some src := src[0]? then + let srcI ← find_model src + if Lean.Expr.occurs src tgt then + throwError m!"Term {e} is a dependent function, of type {etype}\n\ + Hint: you can use the 'T%' elaborator to convert a dependent function \ + to a non-dependent one" + let tgtI ← find_model tgt (src, srcI) + return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] + else + throwError m!"Term {e} is not a function." -/-- `MDiff[s] f` elaborates to `MDifferentiableOn I J f`, +/-- `MDiff[s] f` elaborates to `MDifferentiableOn I J f s`, trying to determine `I` and `J` from the local context. -/ elab:max "MDiff[" s:term:arg "]" t:term:arg : term => do let es ← Term.elabTerm s none let et ← Term.elabTerm t none let _estype ← inferType es >>= instantiateMVars let etype ← inferType et >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - -- TODO: check that `estype` and src are compatible/the same! - return ← mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] - | _ => throwError m!"Term {et} is not a function." + match ← _find_models etype et _estype with + | some (srcI, tgtI) => return ← mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] + | none => throwError m!"Term {et} is not a function." /-- `MDiff f` elaborates to `MDifferentiable I J f`, trying to determine `I` and `J` from the local context. -/ elab:max "MDiff" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] - | _ => throwError m!"Term {e} is not a function." + match ← _find_models etype e none with + | some (srcI, tgtI) => return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] + | none => throwError m!"Term {e} is not a function." --- TODO: say something about the expected type of `n` being in ℕ or WithTop ℕ∞! /-- `CMDiffAt[s] n f x` elaborates to `ContMDiffWithinAt I J n f s x`, trying to determine `I` and `J` from the local context. +`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTerm nt wtn + let ne ← Term.elabTermEnsuringType nt wtn let _estype ← inferType es >>= instantiateMVars let eftype ← inferType ef >>= instantiateMVars - match eftype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - -- TODO: check `estype` and src are compatible - return ← mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] - | _ => throwError m!"Term {ef} is not a function." + match ← _find_models eftype ef _estype with + | some (srcI, tgtI) => return ← mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] + | none => throwError m!"Term {ef} is not a function." /-- `CMDiffAt n f x` elaborates to `ContMDiffAt I J n f x` trying to determine `I` and `J` from the local context. +`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do let e ← Term.elabTerm t none - let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let wtn ← Term.elabTerm (← ``(WithTop ℕ∞)) none let ne ← Term.elabTermEnsuringType nt wtn let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] - | _ => throwError m!"Term {e} is not a function." + match ← _find_models etype e none with + | some (srcI, tgtI) => return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] + | none => throwError m!"Term {e} is not a function." /-- `CMDiff[s] n f` elaborates to `ContMDiffOn I J n f s`, -trying to determine `I` and `J` from the local context. -/ +trying to determine `I` and `J` from the local context. +`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none - let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none + let wtn ← Term.elabTerm (← ``(WithTop ℕ∞)) none let ne ← Term.elabTermEnsuringType nt wtn let _estype ← inferType es >>= instantiateMVars let eftype ← inferType ef >>= instantiateMVars - match eftype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - -- TODO: check `estype` and src are compatible - return ← mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] - | _ => throwError m!"Term {ef} is not a function." + match ← _find_models eftype ef _estype with + | some (srcI, tgtI) => return ← mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] + | none => throwError m!"Term {ef} is not a function." /-- `CMDiff n f` elaborates to `ContMDiff I J n f`, -trying to determine `I` and `J` from the local context. -/ +trying to determine `I` and `J` from the local context. +`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ elab:max "CMDiff" nt:term:arg f:term:arg : term => do - let e ← Term.elabTerm f none - let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTerm nt wtn - let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] - | _ => throwError m!"Term {e} is not a function." - --- TODO: remove in favour of CMDiff (after aligning their behaviour and adding a test for it!) -elab:max "ContMDiff%" nt:term:arg f:term:arg : term => do let e ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none let ne ← Term.elabTermEnsuringType nt wtn let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] - | _ => throwError m!"Term {e} is not a function." + match ← _find_models etype e none with + | some (srcI, tgtI) => return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] + | none => throwError m!"Term {e} is not a function." -/-- `mfderiv[u] f x` elaborates to `mfderivWithin I J f x`, +/-- `mfderiv[u] f x` elaborates to `mfderivWithin I J f u x`, trying to determine `I` and `J` from the local context. -/ elab:max "mfderiv[" s:term:arg "]" t:term:arg : term => do let es ← Term.elabTerm s none let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars let _estype ← inferType es >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - -- TODO: check `estype` and src are compatible - return ← mkAppM ``mfderivWithin #[srcI, tgtI, e, es] - | _ => throwError m!"Term {e} is not a function." + match ← _find_models etype e _estype with + | some (srcI, tgtI) => return ← mkAppM ``mfderivWithin #[srcI, tgtI, e, es] + | none => throwError m!"Term {e} is not a function." -/-- `mfderiv f x` elaborates to `mfderiv I J f x`, +/-- `mfderiv% f x` elaborates to `mfderiv I J f x`, trying to determine `I` and `J` from the local context. -/ elab:max "mfderiv%" t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM `mfderiv #[srcI, tgtI, e] - | _ => throwError m!"Term {e} is not a function." + match ← _find_models etype e none with + | some (srcI, tgtI) => return ← mkAppM ``mfderiv #[srcI, tgtI, e] + | none => throwError m!"Term {e} is not a function." -end +end Manifold From b68452953023ed686facbbac82f372ed98da0d09 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 30 Sep 2025 19:19:21 +0200 Subject: [PATCH 382/601] Fix the build --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 6 +++--- .../Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean | 1 + Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 6 +++--- .../Geometry/Manifold/VectorBundle/OrthonormalFrame.lean | 6 +++--- Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 478ccb77b04f77..4d8157ff2ab384 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -171,7 +171,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by - by_cases hs : MDifferentiableAt% s x + by_cases hs : MDiffAt s x · have hs' := hs.const_smul a suffices (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = @@ -282,7 +282,7 @@ variable (I F) lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% extend I F σ₀) := by + ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% (extend I F σ₀)) := by letI t := trivializationAt F V x letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x @@ -294,7 +294,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDiff (T% extend I F σ₀) := + MDiff (T% (extend I F σ₀)) := contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) theorem contDiff_extend diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index 0220ae4a687cec..f01f3535bcac5f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho +import Mathlib.Analysis.SpecialFunctions.Sqrt import Mathlib.Geometry.Manifold.VectorBundle.Riemannian import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection import Mathlib.Geometry.Manifold.Elaborators diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 1f9fa8d67e604d..5c9f9d2a17ff3c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -125,7 +125,7 @@ lemma mono (hs : IsLocalFrameOn I F n s u) (hu'u : u' ⊆ u) : IsLocalFrameOn I contMDiffOn i := (hs.contMDiffOn i).mono hu'u lemma contMDiffAt (hs : IsLocalFrameOn I F n s u) (hu : IsOpen u) (hx : x ∈ u) (i : ι) : - CMDiffAt n (T% s i) x := + CMDiffAt n (T% (s i)) x := (hs.contMDiffOn i).contMDiffAt <| hu.mem_nhds hx /-- Given a local frame `{s i}` on `U ∋ x`, returns the basis `{s i}` of `V x` -/ @@ -329,7 +329,7 @@ is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_localFrame_baseSet (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : - CMDiff[e.baseSet] n (T% b.localFrame e i) := by + CMDiff[e.baseSet] n (T% (b.localFrame e i)) := by rw [contMDiffOn_section_of_mem_baseSet₀] apply (contMDiffOn_const (c := b i)).congr intro y hy @@ -356,7 +356,7 @@ omit [IsManifold I 0 M] in lemma _root_.contMDiffAt_localFrame_of_mem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) {x : M} (hx : x ∈ e.baseSet) : - CMDiffAt n (T% b.localFrame e i) x := + CMDiffAt n (T% (b.localFrame e i)) x := (b.localFrame_isLocalFrameOn_baseSet I n e).contMDiffAt e.open_baseSet hx _ @[simp] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 0aa2b07a0b8fee..3f3506c887e2a4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -207,14 +207,14 @@ variable (b e) in /-- Each orthonormal frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ lemma contMDiffOn_orthonormalFrame_baseSet (i : ι) : - CMDiff[e.baseSet] n (T% b.orthonormalFrame e i) := by + CMDiff[e.baseSet] n (T% (b.orthonormalFrame e i)) := by apply IsLocalFrameOn.contMDiffOn exact (b.orthonormalFrame_isOrthonormalFrameOn e).toIsLocalFrameOn omit [IsManifold IB n B] in variable (b e) in lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e.baseSet) : - CMDiffAt n (T% b.orthonormalFrame e i) x := + CMDiffAt n (T% (b.orthonormalFrame e i)) x := -- bug: if I change this to a by apply, and put #check after the `by`, it works, but #check' fails -- #check' contMDiffOn_orthonormalFrame_baseSet (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx @@ -224,7 +224,7 @@ omit [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in variable [ContMDiffVectorBundle 1 F E IB] [IsContMDiffRiemannianBundle IB 1 F E] in variable (b e) in lemma _root_.mdifferentiableAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e.baseSet) : - MDiffAt (T% b.orthonormalFrame e i) x := by + MDiffAt (T% (b.orthonormalFrame e i)) x := by apply ContMDiffAt.mdifferentiableAt _ le_rfl exact (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 325cb41c8e6916..11b3cf251e492a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -66,7 +66,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F classical have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) - (hσ : ∀ i, MDiffAt (T% σ i) x): + (hσ : ∀ i, MDiffAt (T% (σ i)) x): φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by induction s using Finset.induction_on with | empty => @@ -87,7 +87,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) let c := Basis.localFrame_repr I t b - have hs (i) : MDiffAt (T% s i) x:= + have hs (i) : MDiffAt (T% (s i)) x:= (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : MDiffAt ((c i) σ) x := From bdda85bb6ffc5d3ebe2f65b237e97141788d731b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 30 Sep 2025 20:07:46 +0200 Subject: [PATCH 383/601] Fix the build for the merge: most changes are fine, but the one to bar I don't understand. Is this a regression/should this be reported? The changes to the proofs are not nice, in any case. --- .../CovariantDerivative/Basic.lean | 9 +++-- .../CovariantDerivative/LeviCivita.lean | 40 ++++++++++--------- .../Manifold/VectorBundle/LocalFrame.lean | 10 ++--- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 4d8157ff2ab384..512b518481d59f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -342,7 +342,7 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] f X (σ + σ') x = f X σ x + f X σ' x leibniz {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {g : M → 𝕜} {x} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): - f X (g • σ) x = (g • f X σ) x + (bar _ <| mfderiv I 𝓘(𝕜) g x (X x)) • σ x + f X (g • σ) x = (g • f X σ) x + ((bar _).toFun (mfderiv I 𝓘(𝕜) g x (X x))) • σ x smul_const_σ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x} (a : 𝕜) (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : f X (a • σ) x = a • f X σ x @@ -557,7 +557,8 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] congr ext i rw [(h i).leibniz hX hσ hg] - simp_rw [Pi.smul_apply', smul_add, add_left_inj] + simp_rw [Pi.smul_apply', smul_add] + dsimp rw [smul_comm] _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x) + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by @@ -880,8 +881,8 @@ lemma differenceAux_smul_eq differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= calc _ _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl - _ = (f x • cov X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) - - (f x • cov' X σ x + (bar _ <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by + _ = (f x • cov X σ x + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) + - (f x • cov' X σ x + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by simp [hcov.leibniz hX hσ hf, hcov'.leibniz hX hσ hf] _ = f x • cov X σ x - f x • cov' X σ x := by simp _ = f x • (cov X σ x - cov' X σ x) := by simp [smul_sub] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 3488d697ac7025..0848206437cf81 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -211,7 +211,7 @@ omit [IsManifold I ∞ M] in lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by ext x simp only [rhs_aux] - congr + congr 2 exact product_swap I Z Y omit [IsManifold I ∞ M] in @@ -508,7 +508,7 @@ lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs' I X (f • Y) Z x = - f x • leviCivitaRhs' I X Y Z x + (bar _ <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by + f x • leviCivitaRhs' I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by simp only [leviCivitaRhs'] simp_rw [rhs_aux_smulX I Y Z X f] simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] @@ -516,13 +516,13 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? have h1 : ⟪Z, mlieBracket I (f • Y) X⟫ x = - - bar _ (((mfderiv I 𝓘(ℝ, ℝ) f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by + - (bar _).toFun (((mfderiv% f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] congr · simp [bar]; rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = - bar _ (((mfderiv I 𝓘(ℝ, ℝ) f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by + (bar _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] congr · simp [bar]; rw [real_inner_smul_right] @@ -540,20 +540,22 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} set dfx := (mfderiv I 𝓘(ℝ, ℝ) f x) set H := (bar (f x)) (dfx (X x)) with H_eq set K := (bar (f x)) (dfx (Z x)) with K_eq - change f x * A + bar _ (dfx (X x)) * G1 + f x * B - (f x * C + bar _ (dfx (Z x)) * G2) + change f x * A + (bar _).toFun (dfx (X x)) * G1 + f x * B + - (f x * C + (bar _).toFun (dfx (Z x)) * G2) - f x * D - (-H * G1 + f x * E) + (K * G2 + f x * F) = _ + dsimp rw [← H_eq, ← K_eq] ring lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs I X (f • Y) Z x = - f x • leviCivitaRhs I X Y Z x + (bar _ <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by + f x • leviCivitaRhs I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] rw [smul_add, smul_comm] congr 1 rw [← smul_eq_mul] - match_scalars + dsimp field_simp lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] @@ -592,10 +594,6 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} simp only [leviCivitaRhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] - set A := rhs_aux I X Y Z x - set B := rhs_aux I Y Z X x - set C := rhs_aux I Z X Y x - -- Apply the product rule for the lie bracket. -- Let's encapsulate the going into the product and back out again. have h1 : ⟪Y, mlieBracket I X (f • Z)⟫ x = @@ -611,14 +609,16 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} rw [h1, h2, product_smul_left, product_swap I X Z] erw [product_smul_right] simp - - set D := ⟪Y, mlieBracket I X Z⟫ x - set E := ⟪Z, mlieBracket I Y X⟫ x with E_eq - set F := ⟪X, mlieBracket I Z Y⟫ x - letI dfX : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) - set G := dfX * ⟪Y, Z⟫ x - letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - set H := dfY * ⟪X, Z⟫ x + -- set A := rhs_aux I X Y Z x + -- set B := rhs_aux I Y Z X x + -- set C := rhs_aux I Z X Y x + -- set D := ⟪Y, mlieBracket I X Z⟫ x + -- set E := ⟪Z, mlieBracket I Y X⟫ x with E_eq + -- set F := ⟪X, mlieBracket I Z Y⟫ x + -- letI dfX : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (X x) + -- set G := dfX * ⟪Y, Z⟫ x + -- letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + -- set H := dfY * ⟪X, Z⟫ x ring lemma leviCivitaRhs'_smulZ [CompleteSpace E] {f : M → ℝ} @@ -836,11 +836,13 @@ lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ trans ∑ i, (g x • leviCivitaRhs I X σ (Z i) x • Z i x) + ∑ i, ((bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x · simp only [← Finset.sum_add_distrib, add_smul, smul_assoc] + dsimp have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidateAux I e o X σ) x := by simp only [lcCandidateAux, hE, ↓reduceDIte, Pi.smul_apply', Finset.smul_sum] congr rw [this] simp_rw [← hZ', smul_assoc, Finset.smul_sum] + dsimp /-- The candidate definition `lcCandidateAux` is a covariant derivative on each local trivialisation's domain. -/ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 5c9f9d2a17ff3c..6d6b72dd547839 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -14,9 +14,9 @@ import Mathlib.Geometry.Manifold.Elaborators Let `V → M` be a finite rank smooth vector bundle with standard fiber `F`. Given a basis `b` for `F` and a local trivialisation `e` for `V`, we construct a **smooth local frame** on `V` w.r.t. `e` and `b`, -i.e. a collection of sections `s_i` of `V` which is smooth on `e.baseSet` such that `{s_i x}` is a +i.e. a collection of sections `sᵢ` of `V` which is smooth on `e.baseSet` such that `{sᵢ x}` is a basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquely written as -`s = ∑ i, f^i s_i` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. +`s = ∑ i, f^i sᵢ` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. The latter statement holds in many cases, but not for every vector bundle. In this file, we prove it for local frames induced by a trivialisation, for finite rank bundles over a complete field. @@ -330,7 +330,7 @@ lemma contMDiffOn_localFrame_baseSet (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : CMDiff[e.baseSet] n (T% (b.localFrame e i)) := by - rw [contMDiffOn_section_of_mem_baseSet₀] + rw [e.contMDiffOn_section_baseSet_iff] apply (contMDiffOn_const (c := b i)).congr intro y hy simp [localFrame, hy, localFrame_toBasis_at] @@ -500,8 +500,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 simp only [aux] -- step 2: `s` read in trivialization `e` is `C^k` - have h₁ : CMDiffAt k (fun x ↦ (e (s x)).2) x := by - exact contMDiffAt_section_of_mem_baseSet hxe |>.1 hs + have h₁ : CMDiffAt k (fun x ↦ (e (s x)).2) x := e.contMDiffAt_section_iff hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth let bas := fun v ↦ b.repr v i let basl : F →ₗ[𝕜] 𝕜 := { @@ -706,7 +705,6 @@ variable (b e) in lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : ((localExtensionOn b e x v) x) = v := by simp [localExtensionOn, hx] - nth_rw 2 [← (b.localFrame_toBasis_at e hx).sum_repr v] omit [IsManifold I 0 M] in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ From 2022f1bf68e2cb0ffbe80c8ba661bd9d80044566 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 30 Sep 2025 20:34:34 +0200 Subject: [PATCH 384/601] fix(Elaborators): pretty-print the new elaborated notation correctly --- Mathlib/Geometry/Manifold/Elaborators.lean | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean index c5cb4eb20255ab..f309aae40bba7e 100644 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ b/Mathlib/Geometry/Manifold/Elaborators.lean @@ -66,7 +66,6 @@ the following. the model in `E × F` and the product of the models on `E` and `F`. - extend the elaborators to support `PartialHomeomorph`s and `PartialEquiv`s -- fix pretty-printing: currently, the `commandStart` linter expects some different formatting - better error messages (as needed) - further testing and fixing of edge cases - add tests for all of the above @@ -281,7 +280,7 @@ def _find_models (etype eterm : Expr) (_estype : Option Expr) : /-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, trying to determine `I` and `J` from the local context. The argument x can be omitted. -/ -elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do +elab:max "MDiffAt[" s:term:arg "]" ppSpace f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none let etype ← inferType ef >>= instantiateMVars @@ -293,7 +292,7 @@ elab:max "MDiffAt[" s:term:arg "]" f:term:arg : term => do /-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, trying to determine `I` and `J` from the local context. The argument `x` can be omitted. -/ -elab:max "MDiffAt" t:term:arg : term => do +elab:max "MDiffAt" ppSpace t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars match ← _find_models etype e none with @@ -305,7 +304,7 @@ elab:max "MDiffAt" t:term:arg : term => do /-- `MDiffAt2 f x` elaborates to `MDifferentiableAt I J f x`, trying to determine `I` and `J` from the local context. The argument `x` can be omitted. -/ -elab:max "MDiffAt2" t:term:arg : term => do +elab:max "MDiffAt2" ppSpace t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars forallBoundedTelescope etype (some 1) fun src tgt ↦ do @@ -322,7 +321,7 @@ elab:max "MDiffAt2" t:term:arg : term => do /-- `MDiff[s] f` elaborates to `MDifferentiableOn I J f s`, trying to determine `I` and `J` from the local context. -/ -elab:max "MDiff[" s:term:arg "]" t:term:arg : term => do +elab:max "MDiff[" s:term:arg "]" ppSpace t:term:arg : term => do let es ← Term.elabTerm s none let et ← Term.elabTerm t none let _estype ← inferType es >>= instantiateMVars @@ -333,7 +332,7 @@ elab:max "MDiff[" s:term:arg "]" t:term:arg : term => do /-- `MDiff f` elaborates to `MDifferentiable I J f`, trying to determine `I` and `J` from the local context. -/ -elab:max "MDiff" t:term:arg : term => do +elab:max "MDiff" ppSpace t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars match ← _find_models etype e none with @@ -344,7 +343,7 @@ elab:max "MDiff" t:term:arg : term => do trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ -elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do +elab:max "CMDiffAt[" s:term:arg "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none @@ -359,7 +358,7 @@ elab:max "CMDiffAt[" s:term:arg "]" nt:term:arg f:term:arg : term => do trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ -elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do +elab:max "CMDiffAt" ppSpace nt:term:arg ppSpace t:term:arg : term => do let e ← Term.elabTerm t none let wtn ← Term.elabTerm (← ``(WithTop ℕ∞)) none let ne ← Term.elabTermEnsuringType nt wtn @@ -371,7 +370,7 @@ elab:max "CMDiffAt" nt:term:arg t:term:arg : term => do /-- `CMDiff[s] n f` elaborates to `ContMDiffOn I J n f s`, trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ -elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do +elab:max "CMDiff[" s:term:arg "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do let es ← Term.elabTerm s none let ef ← Term.elabTerm f none let wtn ← Term.elabTerm (← ``(WithTop ℕ∞)) none @@ -385,7 +384,7 @@ elab:max "CMDiff[" s:term:arg "]" nt:term:arg f:term:arg : term => do /-- `CMDiff n f` elaborates to `ContMDiff I J n f`, trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ -elab:max "CMDiff" nt:term:arg f:term:arg : term => do +elab:max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do let e ← Term.elabTerm f none let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none let ne ← Term.elabTermEnsuringType nt wtn @@ -396,7 +395,7 @@ elab:max "CMDiff" nt:term:arg f:term:arg : term => do /-- `mfderiv[u] f x` elaborates to `mfderivWithin I J f u x`, trying to determine `I` and `J` from the local context. -/ -elab:max "mfderiv[" s:term:arg "]" t:term:arg : term => do +elab:max "mfderiv[" s:term:arg "]" ppSpace t:term:arg : term => do let es ← Term.elabTerm s none let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars @@ -407,7 +406,7 @@ elab:max "mfderiv[" s:term:arg "]" t:term:arg : term => do /-- `mfderiv% f x` elaborates to `mfderiv I J f x`, trying to determine `I` and `J` from the local context. -/ -elab:max "mfderiv%" t:term:arg : term => do +elab:max "mfderiv%" ppSpace t:term:arg : term => do let e ← Term.elabTerm t none let etype ← inferType e >>= instantiateMVars match ← _find_models etype e none with From 433fccb1b40da13dc97522a6b83727916cfb2dde Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 30 Sep 2025 20:36:16 +0200 Subject: [PATCH 385/601] Re-enable the commandStart linter --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 2 -- .../Manifold/VectorBundle/CovariantDerivative/Torsion.lean | 2 -- Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean | 3 --- Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean | 2 -- Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean | 2 -- 5 files changed, 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0848206437cf81..819216c4ccd1ff 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -151,8 +151,6 @@ lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : product I X Y x = product I X Y' x + product I X Y'' x := by rw [product_apply, h, inner_add_right, ← product_apply] -set_option linter.style.commandStart false -- custom elaborators not handled well yet - /- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` yields an error synthesized type class instance is not definitionally equal to expression inferred by typing rules, diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index f6308071c987ba..5de5bc510ad785 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -48,8 +48,6 @@ lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by rw [VectorField.mlieBracket_swap] module -set_option linter.style.commandStart false -- new delaborators confuse the pretty-printer - namespace IsCovariantDerivativeOn variable [h : IsManifold I ∞ M] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index f01f3535bcac5f..eb106cfe70beab 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -293,9 +293,6 @@ end VectorBundle variable {n : WithTop ℕ∞} --- TODO: fix pretty-printing of my new elaborators! -set_option linter.style.commandStart false - variable [IsContMDiffRiemannianBundle IB n F E] section helper diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 6d6b72dd547839..e7c56bd1a1db60 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -207,8 +207,6 @@ lemma repr_apply_zero_at (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} (ht variable (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} [VectorBundle 𝕜 F V] -set_option linter.style.commandStart false - /-- Given a local frame `s i ` on `u`, if a section `t` has `C^k` coefficients on `u` w.r.t. `s i`, then `t` is `C^n` on `u`. -/ lemma contMDiffOn_of_repr [Fintype ι] (h : ∀ i, CMDiff[u] n (hs.repr i t)) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 3f3506c887e2a4..8a7b07098f86eb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -106,8 +106,6 @@ variable [Fintype ι] variable (hs : IsOrthonormalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} -set_option linter.style.commandStart false - omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in variable (t) in From 80c26762da5bd2a48eac7f993c0ce2c088da9f57 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 7 Oct 2025 07:34:03 -0700 Subject: [PATCH 386/601] Minor golf --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 819216c4ccd1ff..65b931682ff524 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -685,7 +685,7 @@ vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ -- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! lemma congr_of_forall_product [FiniteDimensional ℝ E] (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by - by_cases hE : Subsingleton E + obtain (_hE | hE) := subsingleton_or_nontrivial E · ext x have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) apply Subsingleton.allEq _ @@ -693,7 +693,6 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] let b := Basis.ofVectorSpace ℝ E let t := trivializationAt E (TangentSpace I : M → Type _) x have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty -- The linear ordering on the indexing set of `b` is only used in this proof, -- so our choice does not matter. From ef928c6f9a3619df570f0c856cd1f441c7d4d1d4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 11:42:35 -0700 Subject: [PATCH 387/601] Fix build for the merge --- .../CovariantDerivative/Basic.lean | 2 +- .../Manifold/VectorField/LieBracket.lean | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 512b518481d59f..b7d3c584f90f2d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -215,7 +215,7 @@ lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := ModelWithCorners.uniqueDiffWithinAt_image I erw [fderivWithin_smul uniq hs' hf'] - simp [PartialHomeomorph.left_inv φ (ChartedSpace.mem_chart_source x)] + simp [φ.left_inv (ChartedSpace.mem_chart_source x)] rfl end general_lemmas diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index e0793f75018248..87449322f1c7ee 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -339,13 +339,13 @@ lemma aux_computation2' : have : MDifferentiableWithinAt 𝓘(𝕜, E) I φ.symm φ.target (φ x) := by have := mdifferentiableWithinAt_extChartAt_symm (I := I) (mem_extChartAt_target x) exact this.mono (extChartAt_target_subset_range x) - simp only [this, if_true] - simp only [writtenInExtChartAt, extChartAt, PartialHomeomorph.extend, - PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, PartialHomeomorph.toFun_eq_coe, - PartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, - PartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, - PartialEquiv.trans_refl, PartialEquiv.refl_symm, PartialEquiv.refl_coe, CompTriple.comp_eq, - preimage_id_eq, id_eq, modelWithCornersSelf_coe, range_id, inter_univ] + simp only [this, ↓reduceIte, writtenInExtChartAt, extChartAt, OpenPartialHomeomorph.extend, + PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, + OpenPartialHomeomorph.toFun_eq_coe, OpenPartialHomeomorph.refl_partialEquiv, + PartialEquiv.refl_source, OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, + modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, PartialEquiv.refl_symm, + PartialEquiv.refl_coe, CompTriple.comp_eq, preimage_id_eq, id_eq, modelWithCornersSelf_coe, + range_id, inter_univ] rw [extChartAt_to_inv x, ← extChartAt_coe] -- debug why this line is needed! change fderivWithin 𝕜 (↑(extChartAt I x) ∘ ↑φ.symm) (extChartAt I x).target (φ x) = _ @@ -369,13 +369,13 @@ lemma aux_computation2 : rw [mfderivWithin] have : MDifferentiableWithinAt 𝓘(𝕜, E) I (↑φ.symm) (range ↑I) (φ x) := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) - simp? [this] says - simp only [this, ↓reduceIte, writtenInExtChartAt, extChartAt, PartialHomeomorph.extend, - PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, PartialHomeomorph.toFun_eq_coe, - PartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, - PartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, - PartialEquiv.trans_refl, PartialEquiv.refl_symm, PartialEquiv.refl_coe, CompTriple.comp_eq, - preimage_id_eq, id_eq, modelWithCornersSelf_coe, range_id, inter_univ] + simp only [this, ↓reduceIte, writtenInExtChartAt, extChartAt, OpenPartialHomeomorph.extend, + PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, + OpenPartialHomeomorph.toFun_eq_coe, OpenPartialHomeomorph.refl_partialEquiv, + PartialEquiv.refl_source, OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, + modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, PartialEquiv.refl_symm, + PartialEquiv.refl_coe, CompTriple.comp_eq, preimage_id_eq, id_eq, modelWithCornersSelf_coe, + range_id, inter_univ] rw [extChartAt_to_inv x, ← extChartAt_coe] have : fderivWithin 𝕜 (φ ∘ φ.symm) (range I) (φ x) = fderivWithin 𝕜 id (range I) (φ x) := by refine fderivWithin_congr' ?_ ?_ From 7e5e3be419330d6cdb128f175a5cb3ff0ddf2491 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 11:32:27 -0700 Subject: [PATCH 388/601] Switch out the elaborators --- Mathlib.lean | 1 - Mathlib/Geometry/Manifold/Elaborators.lean | 416 ----------------- .../CovariantDerivative/Basic.lean | 2 +- .../VectorBundle/GramSchmidtOrtho.lean | 2 +- .../Manifold/VectorBundle/LocalFrame.lean | 2 +- .../Geometry/Manifold/VectorBundle/Misc.lean | 2 +- .../Manifold/VectorBundle/Tensoriality.lean | 2 +- .../DifferentialGeometry/Elaborators.lean | 441 ------------------ 8 files changed, 5 insertions(+), 863 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/Elaborators.lean delete mode 100644 MathlibTest/DifferentialGeometry/Elaborators.lean diff --git a/Mathlib.lean b/Mathlib.lean index d1c538e5fc601c..2ed4afbca8524a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3913,7 +3913,6 @@ import Mathlib.Geometry.Manifold.ContMDiffMFDeriv import Mathlib.Geometry.Manifold.ContMDiffMap import Mathlib.Geometry.Manifold.DerivationBundle import Mathlib.Geometry.Manifold.Diffeomorph -import Mathlib.Geometry.Manifold.Elaborators import Mathlib.Geometry.Manifold.GroupLieAlgebra import Mathlib.Geometry.Manifold.Instances.Icc import Mathlib.Geometry.Manifold.Instances.Real diff --git a/Mathlib/Geometry/Manifold/Elaborators.lean b/Mathlib/Geometry/Manifold/Elaborators.lean deleted file mode 100644 index f309aae40bba7e..00000000000000 --- a/Mathlib/Geometry/Manifold/Elaborators.lean +++ /dev/null @@ -1,416 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ -import Mathlib.Geometry.Manifold.ContMDiff.Defs -import Mathlib.Geometry.Manifold.MFDeriv.Defs -import Mathlib.Geometry.Manifold.Traces - -/-! -# Elaborators for differential geometry - -This file defines custom elaborators for differential geometry, to allow for more compact notation. -There are two classes of elaborators. The first provides more compact notation for differentiability -and continuous differentiability on manifolds, including inference of the model with corners. -All these elaborators are scoped to the `Manifold` namespace. They allow writing -- `MDiff f` for `MDifferentiable I J f` -- `MDiffAt f x` for `MDifferentiableAt I J f x` -- `MDiff[u] f` for `MDifferentiableOn I J f u` -- `MDiffAt[u] f x` for `MDifferentiableWithinAt I J f u x` -- `CMDiff n f` for `ContMDiff I J n f` -- `CMDiffAt n f x` for `ContMDiffAt I J n f x` -- `CMDiff[u] n f` for `ContMDiffOn I J n f u` -- `CMDiffAt[u] n f x` for `ContMDiffWithinAt I J n f u x`, -- `mfderiv[u] f x` for `mfderivWithin I J f u x`, -- `mfderiv% f x` for `mfderiv I J f x`. - -In each of these cases, the models with corners are inferred from the domain and codomain of `f`. -The search for models with corners uses the local context and is (almost) only syntactic, hence -hopefully fast enough to always run. - -This has no dedicated support for product manifolds (or product vector spaces) yet; -adding this is left for future changes. (It would need to make a choice between e.g. the -trivial model with corners on a product `E × F` and the product of the trivial models on `E` and -`F`). In these settings, the elaborators should be avoided (for now). - -Secondly, this file adds an elaborator to ease working with sections in a fibre bundle, -converting a section `s : Π x : M, Π V x` to a non-dependent function into the total space of the -bundle. -```lean --- omitted: let `V` be a fibre bundle over `M` -variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} - --- outputs `fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V` -#check T% σ - --- outputs `fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E')` --- Note how the name of the bound variable `x` is preserved. -#check T% σ' - --- outputs `fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E')` -#check T% s -``` - -These elaborators can be combined: `CMDiffAt[u] n (T% s) x` - -**Warning.** These elaborators are a proof of concept; the implementation should be considered a -prototype. Don't rewrite all of mathlib to use it just yet. Notable bugs and limitations include -the following. - -## TODO -- extend the elaborators to guess models with corners on product manifolds - (this has to make a guess, hence cannot always be correct: but it could make the guess that - is correct 90% of the time) - For products of vector spaces `E × F`, this could print a warning about making a choice between - the model in `E × F` and the product of the models on `E` and `F`. -- extend the elaborators to support `PartialHomeomorph`s and `PartialEquiv`s - -- better error messages (as needed) -- further testing and fixing of edge cases -- add tests for all of the above -- add delaborators for these elaborators - --/ - -open scoped Bundle Manifold ContDiff - -open Lean Meta Elab Tactic -open Mathlib.Tactic - -/-- Try to infer the universe of an expression `e` -/ -def _root_.Lean.Expr.getUniverse (e : Expr) : TermElabM (Level) := do - if let .sort (.succ u) ← inferType e >>= instantiateMVars then - return u - else - throwError m!"Could not find universe of {e}." - -/-- Call `mkApp` recursively with 12 arguments -/ -@[match_pattern] def mkApp12 (f a b c d e g e₁ e₂ e₃ e₄ e₅ e₆ : Expr) := - mkApp6 (mkApp6 f a b c d e g) e₁ e₂ e₃ e₄ e₅ e₆ - -namespace Manifold - -/-- Elaborator for sections in a fibre bundle: converts a section as a dependent function -to a non-dependent function into the total space. This handles the cases of -- sections of a trivial bundle -- vector fields on a manifold (i.e., sections of the tangent bundle) -- sections of an explicit fibre bundle -- turning a bare function `E → E'` into a section of the trivial bundle `Bundle.Trivial E E'` - -This elaborator operates purely syntactically, by analysing the local contexts for suitable -hypothesis for the above cases. Therefore, it is (hopefully) fast enough to always run. --/ --- TODO: document how this elaborator works, any gotchas, etc. -elab:max "T% " t:term:arg : term => do - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - match etype with - | .forallE x base (mkApp3 (.const ``Bundle.Trivial _) E E' _) _ => - trace[TotalSpaceMk] "Section of a trivial bundle" - if ← withReducible (isDefEq E base) then - return ← withLocalDecl x BinderInfo.default base fun x ↦ do - let body ← mkAppM ``Bundle.TotalSpace.mk' #[E', x, .app e x] - mkLambdaFVars #[x] body - | .forallE x base (mkApp12 (.const ``TangentSpace _) _k _ E _ _ _H _ _I _M _ _ _x) _ => - trace[TotalSpaceMk] "Vector field" - return ← withLocalDecl x BinderInfo.default base fun x ↦ do - let body ← mkAppM ``Bundle.TotalSpace.mk' #[E, x, .app e x] - mkLambdaFVars #[x] body - | .forallE x base (.app V _) _ => - trace[TotalSpaceMk] "Section of a bundle as a dependent function" - for decl in ← getLocalHyps do - let decltype ← inferType decl >>= instantiateMVars - match decltype with - | mkApp7 (.const `FiberBundle _) _ F _ _ E _ _ => - if ← withReducible (isDefEq E V) then - return ← withLocalDecl x BinderInfo.default base fun x ↦ do - let body ← mkAppM ``Bundle.TotalSpace.mk' #[F, x, .app e x] - mkLambdaFVars #[x] body - | _ => pure () - | .forallE x src tgt _ => - trace[TotalSpaceMk] "Section of a trivial bundle as a non-dependent function" - let us ← src.getUniverse - let ut ← tgt.getUniverse - -- TODO: can `tgt` depend on `x` in a way that is not a function application? - -- Check that `x` is not a bound variable in `tgt`! - -- xxx: is this check fine or overzealous? - if Lean.Expr.hasLooseBVars tgt then - throwError m!"Term {tgt} has loose bound variables¬ - Hint: applying the 'T%' elaborator twice makes no sense." - let trivBundle := mkAppN (.const `Bundle.Trivial [us, ut]) #[src, tgt] - return ← withLocalDecl x BinderInfo.default src fun x ↦ do - let body := mkAppN (.const ``Bundle.TotalSpace.mk' [us, ut, ut]) - #[src, trivBundle, tgt, x, .app e x] - mkLambdaFVars #[x] body - | _ => pure () - return e - -/-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), -using the local context to infer the expected type. This supports the following cases: -- the model with corners on the total space of a vector bundle -- a model with corners on a manifold -- the trivial model `𝓘(𝕜, E)` on a normed space -- if the above are not found, try to find a `NontriviallyNormedField` instance on the type of `e`, - and if successful, return `𝓘(𝕜)`. - -Further cases can be added as necessary. - -Return an expression describing the found model with corners. - -`baseInfo` is only used for the first case, a model with corners on the total space of the vector -bundle. In this case, it contains a pair of expressions `(e, i)` describing the type of the base -and the model with corners on the base: these are required to construct the right model with -corners. - -This implementation is not maximally robust yet. --/ --- FIXME: better failure when trying to find a `NormedField` instance -def find_model (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do - trace[MDiffElab] m!"Searching a model for: {e}" - if let mkApp3 (.const ``Bundle.TotalSpace _) _ F V := e then - if let mkApp12 (.const ``TangentSpace _) _k _ _E _ _ _H _ I M _ _ _x := V then - trace[MDiffElab] m!"This is the total space of the tangent bundle of {M}" - let srcIT : Term ← PrettyPrinter.delab I - let resTerm : Term ← ``(ModelWithCorners.prod $srcIT ModelWithCorners.tangent $srcIT) - let res ← Term.elabTerm resTerm none - trace[MDiffElab] m!"Found model: {res}" - return res - - trace[MDiffElab] m!"This is a total space with fiber {F}" - if let some (_src, srcI) := baseInfo then - let mut K : Expr := default - let mut normedSpaceInst : Expr := default - let mut Kok : Bool := false - for decl in ← getLocalHyps do - let decltype ← inferType decl >>= instantiateMVars - match decltype with - | mkApp4 (.const ``NormedSpace _) K' E _ _ => - if E == F then - K := K' - trace[MDiffElab] m!"{F} is a normed field over {K}" - normedSpaceInst := decl - Kok := true - | _ => pure () - if Kok then break - unless Kok do throwError - m!"Couldn’t find a normed space structure on {F} in local context" - let kT : Term ← PrettyPrinter.delab K - let srcIT : Term ← PrettyPrinter.delab srcI - let FT : Term ← PrettyPrinter.delab F - let iTerm : Term ← ``(ModelWithCorners.prod $srcIT 𝓘($kT, $FT)) - let I ← Term.elabTerm iTerm none - trace[MDiffElab] m!"Found model: {I}" - return I - else - throwError "Having a TotalSpace as source is not yet supported" - let mut H : Expr := default - let mut Hok : Bool := false - let mut K : Expr := default - let mut normedSpaceInst : Expr := default - let mut Kok : Bool := false - for decl in ← getLocalHyps do - let decltype ← inferType decl >>= instantiateMVars - match decltype with - | mkApp4 (.const ``ChartedSpace _) H' _ M _ => - if M == e then - H := H' - trace[MDiffElab] m!"H is: {H}" - Hok := true - | mkApp4 (.const ``NormedSpace _) K' E _ _ => - if E == e then - K := K' - trace[MDiffElab] m!"Field is: {K}" - normedSpaceInst := decl - Kok := true - | _ => pure () - if Hok || Kok then break - if Kok then - let eT : Term ← PrettyPrinter.delab e - let eK : Term ← PrettyPrinter.delab K - let iTerm : Term ← ``(𝓘($eK, $eT)) - let I ← Term.elabTerm iTerm none - trace[MDiffElab] m!"Found model: {I}" - return I - -- let uK ← K.getUniverse - -- let normedFieldK ← synthInstance (.app (.const ``NontriviallyNormedField [uK]) K) - -- trace[MDiffElab] m!"NontriviallyNormedField instance is: {normedFieldK}" - -- let ue ← e.getUniverse - -- let normedGroupE ← synthInstance (.app (.const ``NormedAddCommGroup [ue]) e) - -- trace[MDiffElab] m!"NormedAddCommGroup instance is: {normedGroupE}" - -- return mkAppN (.const `modelWithCornersSelf [uK, ue]) - -- #[K, normedFieldK, e, normedGroupE, normedSpaceInst] - else if Hok then - for decl in ← getLocalHyps do - let decltype ← inferType decl >>= instantiateMVars - match decltype with - | mkApp7 (.const ``ModelWithCorners _) _ _ _ _ _ H' _ => - if H' == H then - trace[MDiffElab] m!"Found model: {decl}" - return decl - | _ => pure () - else - trace[MDiffElab] m!"Hoping {e} is a normed field" - let eT : Term ← PrettyPrinter.delab e - let iTerm : Term ← `(𝓘($eT, $eT)) - let I ← Term.elabTerm iTerm none - trace[MDiffElab] m!"Found model: {I}" - return I - throwError "Couldn’t find models with corners" - -/-- If `etype` is a non-dependent function between spaces `src` and `tgt`, try to find a model with -corners on both `src` and `tgt`. If successful, return both models. - -`ef` is the term having type `etype`: this is used only for better diagnostics. -If `estype` is `some`, we verify that `src` and `estype` are def-eq. (TODO: implement this!) -/ --- TODO: pass in an additional type, to be checked equivalent to `src`, and validate this! -def _find_models (etype eterm : Expr) (_estype : Option Expr) : - TermElabM (Option (Expr × Expr)) := do - match etype with - | .forallE _ src tgt _ => - let srcI ← find_model src - if Lean.Expr.hasLooseBVars tgt then - throwError m!"Term {eterm} is a dependent function, of type {etype}\n\ - Hint: you can use the 'T%' elaborator to convert a dependent function to a non-dependent one" - let tgtI ← find_model tgt (src, srcI) - -- TODO: check that `estype` and src are defeq! - return some (srcI, tgtI) - | _ => return none - -/-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, -trying to determine `I` and `J` from the local context. -The argument x can be omitted. -/ -elab:max "MDiffAt[" s:term:arg "]" ppSpace f:term:arg : term => do - let es ← Term.elabTerm s none - let ef ← Term.elabTerm f none - let etype ← inferType ef >>= instantiateMVars - let _estype ← inferType ef >>= instantiateMVars - match ← _find_models etype ef _estype with - | some (srcI, tgtI) => return ← mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] - | none => throwError m!"Term {ef} is not a function." - -/-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`, -trying to determine `I` and `J` from the local context. -The argument `x` can be omitted. -/ -elab:max "MDiffAt" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - match ← _find_models etype e none with - | some (srcI, tgtI) => return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] - | none => throwError m!"Term {e} is not a function." - --- This implement is more robust (in theory), but currently fails tests. --- TODO: investigate why, fix this and replace `MDiffAt` by this one! -/-- `MDiffAt2 f x` elaborates to `MDifferentiableAt I J f x`, -trying to determine `I` and `J` from the local context. -The argument `x` can be omitted. -/ -elab:max "MDiffAt2" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - forallBoundedTelescope etype (some 1) fun src tgt ↦ do - if let some src := src[0]? then - let srcI ← find_model src - if Lean.Expr.occurs src tgt then - throwError m!"Term {e} is a dependent function, of type {etype}\n\ - Hint: you can use the 'T%' elaborator to convert a dependent function \ - to a non-dependent one" - let tgtI ← find_model tgt (src, srcI) - return ← mkAppM ``MDifferentiableAt #[srcI, tgtI, e] - else - throwError m!"Term {e} is not a function." - -/-- `MDiff[s] f` elaborates to `MDifferentiableOn I J f s`, -trying to determine `I` and `J` from the local context. -/ -elab:max "MDiff[" s:term:arg "]" ppSpace t:term:arg : term => do - let es ← Term.elabTerm s none - let et ← Term.elabTerm t none - let _estype ← inferType es >>= instantiateMVars - let etype ← inferType et >>= instantiateMVars - match ← _find_models etype et _estype with - | some (srcI, tgtI) => return ← mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] - | none => throwError m!"Term {et} is not a function." - -/-- `MDiff f` elaborates to `MDifferentiable I J f`, -trying to determine `I` and `J` from the local context. -/ -elab:max "MDiff" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - match ← _find_models etype e none with - | some (srcI, tgtI) => return ← mkAppM ``MDifferentiable #[srcI, tgtI, e] - | none => throwError m!"Term {e} is not a function." - -/-- `CMDiffAt[s] n f x` elaborates to `ContMDiffWithinAt I J n f s x`, -trying to determine `I` and `J` from the local context. -`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -The argument `x` can be omitted. -/ -elab:max "CMDiffAt[" s:term:arg "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do - let es ← Term.elabTerm s none - let ef ← Term.elabTerm f none - let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTermEnsuringType nt wtn - let _estype ← inferType es >>= instantiateMVars - let eftype ← inferType ef >>= instantiateMVars - match ← _find_models eftype ef _estype with - | some (srcI, tgtI) => return ← mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] - | none => throwError m!"Term {ef} is not a function." - -/-- `CMDiffAt n f x` elaborates to `ContMDiffAt I J n f x` -trying to determine `I` and `J` from the local context. -`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -The argument `x` can be omitted. -/ -elab:max "CMDiffAt" ppSpace nt:term:arg ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none - let wtn ← Term.elabTerm (← ``(WithTop ℕ∞)) none - let ne ← Term.elabTermEnsuringType nt wtn - let etype ← inferType e >>= instantiateMVars - match ← _find_models etype e none with - | some (srcI, tgtI) => return ← mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] - | none => throwError m!"Term {e} is not a function." - -/-- `CMDiff[s] n f` elaborates to `ContMDiffOn I J n f s`, -trying to determine `I` and `J` from the local context. -`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ -elab:max "CMDiff[" s:term:arg "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do - let es ← Term.elabTerm s none - let ef ← Term.elabTerm f none - let wtn ← Term.elabTerm (← ``(WithTop ℕ∞)) none - let ne ← Term.elabTermEnsuringType nt wtn - let _estype ← inferType es >>= instantiateMVars - let eftype ← inferType ef >>= instantiateMVars - match ← _find_models eftype ef _estype with - | some (srcI, tgtI) => return ← mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] - | none => throwError m!"Term {ef} is not a function." - -/-- `CMDiff n f` elaborates to `ContMDiff I J n f`, -trying to determine `I` and `J` from the local context. -`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ -elab:max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do - let e ← Term.elabTerm f none - let wtn ← Term.elabTerm (← `(WithTop ℕ∞)) none - let ne ← Term.elabTermEnsuringType nt wtn - let etype ← inferType e >>= instantiateMVars - match ← _find_models etype e none with - | some (srcI, tgtI) => return ← mkAppM ``ContMDiff #[srcI, tgtI, ne, e] - | none => throwError m!"Term {e} is not a function." - -/-- `mfderiv[u] f x` elaborates to `mfderivWithin I J f u x`, -trying to determine `I` and `J` from the local context. -/ -elab:max "mfderiv[" s:term:arg "]" ppSpace t:term:arg : term => do - let es ← Term.elabTerm s none - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - let _estype ← inferType es >>= instantiateMVars - match ← _find_models etype e _estype with - | some (srcI, tgtI) => return ← mkAppM ``mfderivWithin #[srcI, tgtI, e, es] - | none => throwError m!"Term {e} is not a function." - -/-- `mfderiv% f x` elaborates to `mfderiv I J f x`, -trying to determine `I` and `J` from the local context. -/ -elab:max "mfderiv%" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none - let etype ← inferType e >>= instantiateMVars - match ← _find_models etype e none with - | some (srcI, tgtI) => return ← mkAppM ``mfderiv #[srcI, tgtI, e] - | none => throwError m!"Term {e} is not a function." - -end Manifold diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index b7d3c584f90f2d..fff75b1221b3b0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -8,11 +8,11 @@ import Mathlib.Geometry.Manifold.VectorBundle.Tangent import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.Misc import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality import Mathlib.Geometry.Manifold.VectorField.LieBracket import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary -import Mathlib.Geometry.Manifold.Elaborators /-! # Covariant derivatives diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index eb106cfe70beab..cf1ce96a26d39c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -7,7 +7,7 @@ import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho import Mathlib.Analysis.SpecialFunctions.Sqrt import Mathlib.Geometry.Manifold.VectorBundle.Riemannian import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -import Mathlib.Geometry.Manifold.Elaborators +import Mathlib.Geometry.Manifold.Notation /-! # Gram-Schmidt orthonormalisation on sections of Riemannian vector bundles diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index e7c56bd1a1db60..7405aabd845e99 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.Algebra.Monoid +import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -import Mathlib.Geometry.Manifold.Elaborators /-! # Local frames in a vector bundle diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean index 5510769c0c0389..c5622ace701f72 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -3,7 +3,7 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.Elaborators +import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 11b3cf251e492a..f717970a4825b2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -5,9 +5,9 @@ Authors: Patrick Massot, Michael Rothgang -/ import Mathlib.Geometry.Manifold.BumpFunction import Mathlib.Geometry.Manifold.MFDeriv.Basic +import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -import Mathlib.Geometry.Manifold.Elaborators /-! # The tensoriality criterion diff --git a/MathlibTest/DifferentialGeometry/Elaborators.lean b/MathlibTest/DifferentialGeometry/Elaborators.lean deleted file mode 100644 index 1e3244a773bf48..00000000000000 --- a/MathlibTest/DifferentialGeometry/Elaborators.lean +++ /dev/null @@ -1,441 +0,0 @@ -import Mathlib.Geometry.Manifold.Elaborators - -import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -import Mathlib.Geometry.Manifold.VectorBundle.Tangent -import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -import Mathlib.Geometry.Manifold.VectorField.LieBracket - -set_option pp.unicode.fun true - -open Bundle Filter Function Topology - -open scoped Bundle Manifold ContDiff - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - -section - -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -- `F` model fiber - (n : WithTop ℕ∞) - (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul 𝕜 (V x)] - [FiberBundle F V] [VectorBundle 𝕜 F V] - -- `V` vector bundle - --- Tests for the T% elaborator, inserting calls to TotalSpace.mk' automatically. -section TotalSpace - -variable {σ : Π x : M, V x} - {σ' : (x : E) → Trivial E E' x} {σ'' : (y : E) → Trivial E E' y} {s : E → E'} - -/-- info: fun x ↦ TotalSpace.mk' F x (σ x) : M → TotalSpace F V -/ -#guard_msgs in -#check T% σ - -set_option linter.style.commandStart true - --- TODO: investigate this! -/-- -error: Application type mismatch: In the application - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) Set.univ -the argument - Set.univ -has type - Set.{?u.13540} ?m.13541 : Type ?u.13540 -but is expected to have type - Set.{u_4} M : Type u_4 --/ -#guard_msgs in -example {x : M} : MDiffAt[Set.univ] (T% σ) x := sorry - --- Interaction with auto-implicits. -/-- -error: Application type mismatch: In the application - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) Set.univ -the argument - Set.univ -has type - Set.{?u.17364} ?m.17365 : Type ?u.17364 -but is expected to have type - Set.{u_4} M : Type u_4 --/ -#guard_msgs in -set_option autoImplicit true in -example : MDiffAt[Set.univ] (T% σ) x := sorry - -/-- warning: declaration uses 'sorry' -/ -#guard_msgs in -example {x : M} : MDiffAt[(Set.univ : Set M)] (T% σ) x := sorry - -/-- warning: declaration uses 'sorry' -/ -#guard_msgs in -example {u : Set M} {x : M} : CMDiffAt[u] 2 (T% σ) x := sorry - --- Note how the name of the bound variable `x` resp. `y` is preserved. -/-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ -#guard_msgs in -#check T% σ' - -/-- info: fun y ↦ TotalSpace.mk' E' y (σ'' y) : E → TotalSpace E' (Trivial E E') -/ -#guard_msgs in -#check T% σ'' - -/-- info: fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E') -/ -#guard_msgs in -#check T% s - -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] - -/-- info: fun m ↦ TotalSpace.mk' E m (X m) : M → TotalSpace E (TangentSpace I) -/ -#guard_msgs in -#check T% X - -example : (fun m ↦ (X m : TangentBundle I M)) = (fun m ↦ TotalSpace.mk' E m (X m)) := rfl - -end TotalSpace - --- Elaborators for MDifferentiable{WithinAt,At,On}. -section differentiability - --- Start with some basic tests: a simple function, both in applied and unapplied form. -variable {EM' : Type*} [NormedAddCommGroup EM'] - [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - --- General case: a function between two manifolds. -variable {f : M → M'} {s : Set M} {m : M} - -/-- info: MDifferentiableWithinAt I I' f s : M → Prop -/ -#guard_msgs in -#check MDiffAt[s] f - -/-- info: MDifferentiableWithinAt I I' f s m : Prop -/ -#guard_msgs in -#check MDiffAt[s] f m - -/-- info: MDifferentiableAt I I' f : M → Prop -/ -#guard_msgs in -#check MDiffAt f - -/-- info: MDifferentiableAt I I' f m : Prop -/ -#guard_msgs in -#check MDiffAt f m - -/-- info: MDifferentiableOn I I' f s : Prop -/ -#guard_msgs in -#check MDiff[s] f - --- XXX: is this expected behaviour or should it be a bug? -/-- -error: Function expected at - MDifferentiableOn I I' f s -but this term has type - Prop - -Note: Expected a function because this term is being applied to the argument - m --/ -#guard_msgs in -#check MDiff[s] f m - -/-- info: MDifferentiable I I' f : Prop -/ -#guard_msgs in -#check MDiff f - -/-- -error: Function expected at - MDifferentiable I I' f -but this term has type - Prop - -Note: Expected a function because this term is being applied to the argument - m --/ -#guard_msgs in -#check MDiff f m - --- Function from a manifold into a normed space. -variable {g : M → E} - -/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) g s : M → Prop -/ -#guard_msgs in -#check MDiffAt[s] g -/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) g s m : Prop -/ -#guard_msgs in -#check MDiffAt[s] g m -/-- info: MDifferentiableAt I 𝓘(𝕜, E) g : M → Prop -/ -#guard_msgs in -#check MDiffAt g -/-- info: MDifferentiableAt I 𝓘(𝕜, E) g m : Prop -/ -#guard_msgs in -#check MDiffAt g m -/-- info: MDifferentiableOn I 𝓘(𝕜, E) g s : Prop -/ -#guard_msgs in -#check MDiff[s] g --- TODO: fix and enable! #check MDiff[s] g m -/-- info: MDifferentiable I 𝓘(𝕜, E) g : Prop -/ -#guard_msgs in -#check MDiff g --- TODO: fix and enable! #check MDiff g m - --- From a manifold into a field. -variable {h : M → 𝕜} - -/-- info: MDifferentiableWithinAt I 𝓘(𝕜, 𝕜) h s : M → Prop -/ -#guard_msgs in -#check MDiffAt[s] h -/-- info: MDifferentiableWithinAt I 𝓘(𝕜, 𝕜) h s m : Prop -/ -#guard_msgs in -#check MDiffAt[s] h m -/-- info: MDifferentiableAt I 𝓘(𝕜, 𝕜) h : M → Prop -/ -#guard_msgs in -#check MDiffAt h -/-- info: MDifferentiableAt I 𝓘(𝕜, 𝕜) h m : Prop -/ -#guard_msgs in -#check MDiffAt h m -/-- info: MDifferentiableOn I 𝓘(𝕜, 𝕜) h s : Prop -/ -#guard_msgs in -#check MDiff[s] h --- TODO: fix and enable! #check MDiff[s] h m -/-- info: MDifferentiable I 𝓘(𝕜, 𝕜) h : Prop -/ -#guard_msgs in -#check MDiff h --- TODO: fix and enable! #check MDiff h m - --- The following tests are more spotty, as most code paths are already covered above. --- Add further details as necessary. - --- From a normed space into a manifold. -variable {f : E → M'} {s : Set E} {x : E} -/-- info: MDifferentiableWithinAt 𝓘(𝕜, E) I' f s : E → Prop -/ -#guard_msgs in -#check MDiffAt[s] f -/-- info: MDifferentiableAt 𝓘(𝕜, E) I' f x : Prop -/ -#guard_msgs in -#check MDiffAt f x --- TODO: fix and enable! #check MDiff[s] f x -/-- info: MDifferentiable 𝓘(𝕜, E) I' f : Prop -/ -#guard_msgs in -#check MDiff f --- TODO: should this error? if not, fix and enable! #check MDiff f x --- same! #check MDifferentiable% f x - --- Between normed spaces. -variable {f : E → E'} {s : Set E} {x : E} - -/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') f x : Prop -/ -#guard_msgs in -#check MDiffAt f x -/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, E') f : E → Prop -/ -#guard_msgs in -#check MDiffAt f --- should this error or not? #check MDiff[s] f x -/-- info: MDifferentiableWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E') f s : E → Prop -/ -#guard_msgs in -#check MDiffAt[s] f -/-- info: MDifferentiableOn 𝓘(𝕜, E) 𝓘(𝕜, E') f s : Prop -/ -#guard_msgs in -#check MDiff[s] f - - --- Normed space to a field. -variable {f : E → 𝕜} {s : Set E} {x : E} - -/-- info: MDifferentiableAt 𝓘(𝕜, E) 𝓘(𝕜, 𝕜) f x : Prop -/ -#guard_msgs in -#check MDiffAt f x - --- Field into a manifold. -variable {f : 𝕜 → M'} {u : Set 𝕜} {a : 𝕜} -/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) I' f a : Prop -/ -#guard_msgs in -#check MDiffAt f a -/-- info: MDifferentiableOn 𝓘(𝕜, 𝕜) I' f u : Prop -/ -#guard_msgs in -#check MDiff[u] f - --- Field into a normed space. -variable {f : 𝕜 → E'} {u : Set 𝕜} {a : 𝕜} -/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) 𝓘(𝕜, E') f a : Prop -/ -#guard_msgs in -#check MDiffAt f a -/-- info: MDifferentiableOn 𝓘(𝕜, 𝕜) 𝓘(𝕜, E') f u : Prop -/ -#guard_msgs in -#check MDiff[u] f - --- On a field. -variable {f : 𝕜 → 𝕜} {u : Set 𝕜} {a : 𝕜} -/-- info: MDifferentiableAt 𝓘(𝕜, 𝕜) 𝓘(𝕜, 𝕜) f a : Prop -/ -#guard_msgs in -#check MDiffAt f a -/-- info: MDifferentiableOn 𝓘(𝕜, 𝕜) 𝓘(𝕜, 𝕜) f u : Prop -/ -#guard_msgs in -#check MDiff[u] f - --- This elaborator can be combined with the total space elaborator. --- XXX: these tests might be incomplete; extend as needed! - -variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ -#guard_msgs in -#check MDiffAt (T% X) - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ -#guard_msgs in -#check MDiffAt (T% σ) - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop --/ -#guard_msgs in -#check MDiffAt (T% σ') - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a ↦ TotalSpace.mk' E' a (s a) : E → Prop --/ -#guard_msgs in -#check MDifferentiableAt% (T% s) -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% X) m - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% X) - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) m : Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% X) m - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ -#guard_msgs in -#check MDifferentiableAt% (T% σ) - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop --/ -#guard_msgs in -#check MDifferentiableAt% (T% σ') - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun a ↦ TotalSpace.mk' E' a (s a) : E → Prop --/ -#guard_msgs in -#check MDifferentiableAt% (T% s) - -end differentiability - -section mfderiv - -variable {EM' : Type*} [NormedAddCommGroup EM'] - [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - -variable {f : M → M'} {s : Set M} {m : M} - -/-- info: mfderiv I I' f : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ -#guard_msgs in -#check mfderiv% f - -/-- info: mfderiv I I' f m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ -#guard_msgs in -#check mfderiv% f m - -/-- info: mfderivWithin I I' f s : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ -#guard_msgs in -#check mfderiv[s] f - -/-- info: mfderivWithin I I' f s m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ -#guard_msgs in -#check mfderiv[s] f m - -variable {f : E → EM'} {s : Set E} {m : E} - -/-- -info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) --/ -#guard_msgs in -#check mfderiv% f - -/-- -info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) --/ -#guard_msgs in -#check mfderiv% f m - -/-- -info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) --/ -#guard_msgs in -#check mfderiv[s] f - -/-- -info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) --/ -#guard_msgs in -#check mfderiv[s] f m - -section errors - --- Test an error message, about mismatched types. -variable {s' : Set M} {m' : M} - -/-- -error: Application type mismatch: In the application - mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m' -the argument - m' -has type - M : Type u_4 -but is expected to have type - E : Type u_2 ---- -info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f sorry : TangentSpace 𝓘(𝕜, E) sorry →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f sorry) --/ -#guard_msgs in -#check mfderiv% f m' - --- Error messages: argument s has mismatched type. -/-- -error: Application type mismatch: In the application - mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s' -the argument - s' -has type - Set.{u_4} M : Type u_4 -but is expected to have type - Set.{u_2} E : Type u_2 --/ -#guard_msgs in -#check mfderiv[s'] f - -/-- -error: Application type mismatch: In the application - mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s' -the argument - s' -has type - Set.{u_4} M : Type u_4 -but is expected to have type - Set.{u_2} E : Type u_2 --/ -#guard_msgs in -#check mfderiv[s'] f m - -end errors - -end mfderiv From 431805e3ff41b1366e9be4297f3f24e3b15243f8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 11:52:27 -0700 Subject: [PATCH 389/601] Remove one now-unnecessary workaround, and the obsolete file Traces.lean --- Mathlib.lean | 1 - Mathlib/Geometry/Manifold/Traces.lean | 16 ---------------- .../Manifold/VectorBundle/GramSchmidtOrtho.lean | 4 +--- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/Traces.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2ed4afbca8524a..b91f2185f68e27 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3945,7 +3945,6 @@ import Mathlib.Geometry.Manifold.Riemannian.PathELength import Mathlib.Geometry.Manifold.Sheaf.Basic import Mathlib.Geometry.Manifold.Sheaf.LocallyRingedSpace import Mathlib.Geometry.Manifold.Sheaf.Smooth -import Mathlib.Geometry.Manifold.Traces import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita diff --git a/Mathlib/Geometry/Manifold/Traces.lean b/Mathlib/Geometry/Manifold/Traces.lean deleted file mode 100644 index fd93658d1c0db3..00000000000000 --- a/Mathlib/Geometry/Manifold/Traces.lean +++ /dev/null @@ -1,16 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ - -import Lean -/-! -# Traces for differential geometry elaborators - -TODO: add a more complete doc-string - --/ -open Lean -initialize registerTraceClass `TotalSpaceMk -initialize registerTraceClass `MDiffElab diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index cf1ce96a26d39c..be451ad2a11407 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -318,9 +318,7 @@ lemma contMDiffAt_aux (hs : CMDiffAt n (T% s) x) (ht : CMDiffAt n (T% t) x) (hs' def ContMDiffWithinAt.orthogonalProjection (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x ≠ 0) : - -- TODO: leaving out the type ascription yields a horrible error message, add test and fix! - letI S : (x : B) → E x := fun x ↦ (Submodule.span ℝ {s x}).starProjection (t x); - CMDiffAt[u] n (T% S) x := by + CMDiffAt[u] n (T% (fun x ↦ (Submodule.span ℝ {s x}).starProjection (t x))) x := by simp_rw [Submodule.starProjection_singleton] exact (contMDiffWithinAt_aux hs ht hs').smul_section hs From 71521998b8b4e58d2ba264e33defabf98ac51e1b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 12:55:32 -0700 Subject: [PATCH 390/601] chore: remove TODO comments #28032 adds a test for this; no need to track it here --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index fff75b1221b3b0..f0ad2253d772ba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -470,9 +470,6 @@ lemma zeroσ [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) lemma sum_X (hf : IsCovariantDerivativeOn F f s) {ι : Type*} {u : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} - -- TODO: writing `(hX : MDifferentiableAt (T% X) x)` here yields an error - -- `Could not find universe of (x : M) → TangentSpace I x`, which is legitimate - -- (should use `X i` instead), but the error message is horrible... {x} (hx : x ∈ s) (hX : ∀ i, MDiffAt (T% (X i)) x) (hσ : MDiffAt (T% σ) x) : f (∑ i ∈ u, X i) σ x = ∑ i ∈ u, f (X i) σ x := by classical From bf8dcd085baffbea9b536c9c9816ffdc1ea6f024 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 13:25:19 -0700 Subject: [PATCH 391/601] chore: forward-port changes from #30307 and #28032 --- Mathlib/Geometry/Manifold/Notation.lean | 51 +++++++++++-------- Mathlib/Lean/Meta/Basic.lean | 7 +++ .../DifferentialGeometry/Notation.lean | 13 +++-- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 52b60ff0e38028..6b408c0e2521f0 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -67,7 +67,7 @@ variable {s : E → E'} in These elaborators can be combined: `CMDiffAt[u] n (T% s) x` **Warning.** These elaborators are a proof of concept; the implementation should be considered a -prototype. Don't rewrite all of mathlib to use it just yet. Notable bugs and limitations include +prototype. Don't rewrite all of mathlib to use it just yet. Notable limitations include the following. ## TODO @@ -76,10 +76,8 @@ the following. is correct 90% of the time). For products of vector spaces `E × F`, this could print a warning about making a choice between the model in `E × F` and the product of the models on `E` and `F`. -- extend the elaborators to support `OpenPartialHomeomorph`s and `PartialEquiv`s -- better error messages (as needed) -- further testing and fixing of edge cases -- add tests for all of the above +- better error messages (as needed), with tests +- further testing and fixing of edge cases (with tests) - add delaborators for these elaborators -/ @@ -235,10 +233,11 @@ This implementation is not maximally robust yet. -- TODO: consider lowering monad to `MetaM` def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do trace[Elab.DiffGeo.MDiff] "Finding a model for: {e}" - if let some m ← tryStrategy m!"TotalSpace" fromTotalSpace then return m - if let some m ← tryStrategy m!"NormedSpace" fromNormedSpace then return m - if let some m ← tryStrategy m!"ChartedSpace" fromChartedSpace then return m - if let some m ← tryStrategy m!"NormedField" fromNormedField then return m + if let some m ← tryStrategy m!"TotalSpace" fromTotalSpace then return m + if let some m ← tryStrategy m!"TangentBundle" fromTangentBundle then return m + if let some m ← tryStrategy m!"NormedSpace" fromNormedSpace then return m + if let some m ← tryStrategy m!"ChartedSpace" fromChartedSpace then return m + if let some m ← tryStrategy m!"NormedField" fromNormedField then return m throwError "Could not find models with corners for {e}" where /- Note that errors thrown in the following are caught by `tryStrategy` and converted to trace @@ -252,6 +251,15 @@ where if let some m ← tryStrategy m!"TangentSpace" (fromTotalSpace.tangentSpace V) then return m throwError "Having a TotalSpace as source is not yet supported" | _ => throwError "{e} is not a `Bundle.TotalSpace`." + /-- Attempt to find a model on a `TangentBundle` -/ + fromTangentBundle : TermElabM Expr := do + match_expr e with + | TangentBundle _k _ _E _ _ _H _ I M _ _ => do + trace[Elab.DiffGeo.MDiff] "{e} is a TangentBundle over model {I} on {M}" + let srcIT : Term ← Term.exprToSyntax I + let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT) + Term.elabTerm resTerm none + | _ => throwError "{e} is not a `TangentBundle`" /-- Attempt to use the provided `baseInfo` to find a model. -/ fromTotalSpace.fromBaseInfo (F : Expr) : TermElabM Expr := do if let some (src, srcI) := baseInfo then @@ -341,14 +349,14 @@ def findModels (e : Expr) (es : Option Expr) : TermElabM (Expr × Expr) := do end Elab -open Elab +open Elab Lean.Meta /-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, trying to determine `I` and `J` from the local context. The argument `x` can be omitted. -/ scoped elab:max "MDiffAt[" s:term "]" ppSpace f:term:arg : term => do let es ← Term.elabTerm s none - let ef ← Term.elabTerm f none + let ef ← ensureIsFunction <|← Term.elabTerm f none let (srcI, tgtI) ← findModels ef es mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] @@ -356,7 +364,7 @@ scoped elab:max "MDiffAt[" s:term "]" ppSpace f:term:arg : term => do trying to determine `I` and `J` from the local context. The argument `x` can be omitted. -/ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none + let e ← ensureIsFunction <|← Term.elabTerm t none let (srcI, tgtI) ← findModels e none mkAppM ``MDifferentiableAt #[srcI, tgtI, e] @@ -383,25 +391,28 @@ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do trying to determine `I` and `J` from the local context. -/ scoped elab:max "MDiff[" s:term "]" ppSpace t:term:arg : term => do let es ← Term.elabTerm s none - let et ← Term.elabTerm t none + let et ← ensureIsFunction <|← Term.elabTerm t none let (srcI, tgtI) ← findModels et es mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] /-- `MDiff f` elaborates to `MDifferentiable I J f`, trying to determine `I` and `J` from the local context. -/ scoped elab:max "MDiff" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none + let e ← ensureIsFunction <|← Term.elabTerm t none let (srcI, tgtI) ← findModels e none mkAppM ``MDifferentiable #[srcI, tgtI, e] +-- We ensure the type of `n` before checking `f` is a function to provide better error messages +-- in case e.g. just `n` was forgotten. + /-- `CMDiffAt[s] n f x` elaborates to `ContMDiffWithinAt I J n f s x`, trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ scoped elab:max "CMDiffAt[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do let es ← Term.elabTerm s none - let ef ← Term.elabTerm f none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) + let ef ← ensureIsFunction <|← Term.elabTerm f none let (srcI, tgtI) ← findModels ef es mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] @@ -410,7 +421,7 @@ trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ scoped elab:max "CMDiffAt" ppSpace nt:term:arg ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none + let e ← ensureIsFunction <|← Term.elabTerm t none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) let (srcI, tgtI) ← findModels e none mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] @@ -420,8 +431,8 @@ trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ scoped elab:max "CMDiff[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do let es ← Term.elabTerm s none - let ef ← Term.elabTerm f none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) + let ef ← ensureIsFunction <|← Term.elabTerm f none let (srcI, tgtI) ← findModels ef es mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] @@ -429,8 +440,8 @@ scoped elab:max "CMDiff[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : te trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ scoped elab:max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do - let e ← Term.elabTerm f none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) + let e ← ensureIsFunction <|← Term.elabTerm f none let (srcI, tgtI) ← findModels e none mkAppM ``ContMDiff #[srcI, tgtI, ne, e] @@ -438,14 +449,14 @@ scoped elab:max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do trying to determine `I` and `J` from the local context. -/ scoped elab:max "mfderiv[" s:term "]" ppSpace t:term:arg : term => do let es ← Term.elabTerm s none - let e ← Term.elabTerm t none + let e ← ensureIsFunction <|← Term.elabTerm t none let (srcI, tgtI) ← findModels e es mkAppM ``mfderivWithin #[srcI, tgtI, e, es] /-- `mfderiv% f x` elaborates to `mfderiv I J f x`, trying to determine `I` and `J` from the local context. -/ scoped elab:max "mfderiv%" ppSpace t:term:arg : term => do - let e ← Term.elabTerm t none + let e ← ensureIsFunction <|← Term.elabTerm t none let (srcI, tgtI) ← findModels e none mkAppM ``mfderiv #[srcI, tgtI, e] diff --git a/Mathlib/Lean/Meta/Basic.lean b/Mathlib/Lean/Meta/Basic.lean index c8bbf5bdb7d714..1895dafff6aa9f 100644 --- a/Mathlib/Lean/Meta/Basic.lean +++ b/Mathlib/Lean/Meta/Basic.lean @@ -94,3 +94,10 @@ def Lean.Meta.withEnsuringLocalInstance {α : Type} (inst : MVarId) (k : MetaM ( let (e, v) ← k let e' := (← e.abstractM #[inst']).instantiate1 instE return (e', v) + +/-- Ensures that `e` is a function. Attempts to coerce `e` to a function if necessary. -/ +def Lean.Meta.ensureIsFunction (e : Expr) : MetaM Expr := do + let ty ← whnf <|← instantiateMVars <|← inferType e + if ty.isForall then return e else (← coerceToFunction? e).getDM <| + throwError "Expected{indentD e}\nof type{indentD ty}\nto be a function, or to be coercible to \ + a function" diff --git a/MathlibTest/DifferentialGeometry/Notation.lean b/MathlibTest/DifferentialGeometry/Notation.lean index 1620190e4fb9a9..dc3fa5bb945e8c 100644 --- a/MathlibTest/DifferentialGeometry/Notation.lean +++ b/MathlibTest/DifferentialGeometry/Notation.lean @@ -354,6 +354,9 @@ trace: [Elab.DiffGeo.MDiff] Finding a model for: TotalSpace F (TangentSpace I) [Elab.DiffGeo.MDiff] ❌️ TotalSpace [Elab.DiffGeo.MDiff] Failed with error: F is not a `Bundle.TotalSpace`. +[Elab.DiffGeo.MDiff] ❌️ TangentBundle + [Elab.DiffGeo.MDiff] Failed with error: + F is not a `TangentBundle` [Elab.DiffGeo.MDiff] ✅️ NormedSpace [Elab.DiffGeo.MDiff] Field is: 𝕜 [Elab.DiffGeo.MDiff] Found model: 𝓘(𝕜, F) @@ -386,8 +389,7 @@ Hint: Additional diagnostic information may be available using the `set_option d #guard_msgs in #check MDifferentiable (I.prod (𝓘(𝕜, E))) 𝓘(𝕜, F) h' --- TODO: implement special handling for the tangent bundle -/-- error: Could not find models with corners for TangentBundle I M -/ +/-- info: MDifferentiable I.tangent 𝓘(𝕜, F) h' : Prop -/ #guard_msgs in #check MDiff h' @@ -498,7 +500,7 @@ error: Expected m of type M -to be a function +to be a function, or to be coercible to a function -/ #guard_msgs in #check CMDiffAt[s] f m @@ -516,7 +518,7 @@ error: Expected m of type M -to be a function +to be a function, or to be coercible to a function -/ #guard_msgs in #check CMDiffAt[s] f m @@ -994,6 +996,9 @@ trace: [Elab.DiffGeo.MDiff] Finding a model for: Unit [Elab.DiffGeo.MDiff] ❌️ TotalSpace [Elab.DiffGeo.MDiff] Failed with error: Unit is not a `Bundle.TotalSpace`. +[Elab.DiffGeo.MDiff] ❌️ TangentBundle + [Elab.DiffGeo.MDiff] Failed with error: + Unit is not a `TangentBundle` [Elab.DiffGeo.MDiff] ❌️ NormedSpace [Elab.DiffGeo.MDiff] Failed with error: Couldn't find a `NormedSpace` structure on Unit among local instances. From 1292624f0413e0b4509409ff6c8276c9c7de2edb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 13:30:49 -0700 Subject: [PATCH 392/601] chore(VectorBundle/MDifferentiable): use new elaborators more Not exhaustive yet --- .../VectorBundle/MDifferentiable.lean | 228 +++++++----------- 1 file changed, 90 insertions(+), 138 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index a222ff0f56eeee..252c2f9ac6ead5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -7,6 +7,7 @@ import Mathlib.Geometry.Manifold.VectorBundle.Basic import Mathlib.Geometry.Manifold.Algebra.Monoid import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.Notation /-! # Differentiability of functions in vector bundles @@ -60,15 +61,14 @@ theorem mdifferentiableWithinAt_totalSpace (f : M → TotalSpace F E) {s : Set M Version at a point -/ theorem mdifferentiableAt_totalSpace (f : M → TotalSpace F E) {x₀ : M} : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ - MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ - MDifferentiableAt IM 𝓘(𝕜, F) - (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by + MDiffAt (fun x => (f x).proj) x₀ ∧ + MDiffAt (fun x ↦ (trivializationAt F E (f x₀).proj (f x)).2) x₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f /-- Characterization of differentiable sections of a vector bundle at a point within a set in terms of the preferred trivialization at that point. -/ theorem mdifferentiableWithinAt_section (s : Π b, E b) {u : Set B} {b₀ : B} : - MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) u b₀ ↔ + MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (T% s) u b₀ ↔ MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) u b₀ := by rw [mdifferentiableWithinAt_totalSpace] change MDifferentiableWithinAt _ _ id _ _ ∧ _ ↔ _ @@ -77,8 +77,7 @@ theorem mdifferentiableWithinAt_section (s : Π b, E b) {u : Set B} {b₀ : B} : /-- Characterization of differentiable sections of a vector bundle at a point within a set in terms of the preferred trivialization at that point. -/ theorem mdifferentiableAt_section (s : Π b, E b) {b₀ : B} : - MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) b₀ ↔ - MDifferentiableAt IB 𝓘(𝕜, F) (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by + MDiffAt (T% s) b₀ ↔ MDiffAt (fun b ↦ (trivializationAt F E b₀ (s b)).2) b₀ := by simpa [← mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ namespace Bundle @@ -105,7 +104,7 @@ theorem mdifferentiableWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace variable (𝕜) [∀ x, AddCommMonoid (E x)] variable [∀ x, Module 𝕜 (E x)] [VectorBundle 𝕜 F E] -theorem mdifferentiable_zeroSection : MDifferentiable IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) := by +theorem mdifferentiable_zeroSection : MDiff (zeroSection F E) := by intro x unfold zeroSection rw [mdifferentiableAt_section] @@ -114,16 +113,14 @@ theorem mdifferentiable_zeroSection : MDifferentiable IB (IB.prod 𝓘(𝕜, F)) (mem_baseSet_trivializationAt F E x)] with y hy using congr_arg Prod.snd <| (trivializationAt F E x).zeroSection 𝕜 hy -theorem mdifferentiableOn_zeroSection {t : Set B} : - MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) t := +theorem mdifferentiableOn_zeroSection {t : Set B} : MDiff[t] (zeroSection F E) := (mdifferentiable_zeroSection _ _).mdifferentiableOn -theorem mdifferentiableAt_zeroSection {x : B} : - MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) x := +theorem mdifferentiableAt_zeroSection {x : B} : MDiffAt (zeroSection F E) x := (mdifferentiable_zeroSection _ _).mdifferentiableAt theorem mdifferentiableWithinAt_zeroSection {t : Set B} {x : B} : - MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (zeroSection F E) t x := + MDiffAt[t] (zeroSection F E) x := (mdifferentiable_zeroSection _ _ x).mdifferentiableWithinAt end Bundle @@ -154,14 +151,14 @@ theorem mdifferentiableAt_coordChangeL {x : B} variable {s : Set M} {f : M → B} {g : M → F} {x : M} -protected theorem MDifferentiableWithinAt.coordChangeL (hf : MDifferentiableWithinAt IM IB f s x) +protected theorem MDifferentiableWithinAt.coordChangeL (hf : MDiffAt[s] f x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : MDifferentiableWithinAt IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) s x := (mdifferentiableAt_coordChangeL he he').comp_mdifferentiableWithinAt _ hf protected theorem MDifferentiableAt.coordChangeL - (hf : MDifferentiableAt IM IB f x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : + (hf : MDiffAt f x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : MDifferentiableAt IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) x := MDifferentiableWithinAt.coordChangeL hf he he' @@ -171,14 +168,14 @@ protected theorem MDifferentiableOn.coordChangeL fun x hx ↦ (hf x hx).coordChangeL (he hx) (he' hx) protected theorem MDifferentiable.coordChangeL - (hf : MDifferentiable IM IB f) (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : + (hf : MDiff f) (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : MDifferentiable IM 𝓘(𝕜, F →L[𝕜] F) (fun y ↦ (e.coordChangeL 𝕜 e' (f y) : F →L[𝕜] F)) := fun x ↦ (hf x).coordChangeL (he x) (he' x) protected theorem MDifferentiableWithinAt.coordChange - (hf : MDifferentiableWithinAt IM IB f s x) (hg : MDifferentiableWithinAt IM 𝓘(𝕜, F) g s x) + (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : - MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) s x := by + MDiffAt[s] (fun y ↦ e.coordChange e' (f y) (g y)) x := by refine ((hf.coordChangeL he he').clm_apply hg).congr_of_eventuallyEq ?_ ?_ · have : e.baseSet ∩ e'.baseSet ∈ 𝓝 (f x) := (e.open_baseSet.inter e'.open_baseSet).mem_nhds ⟨he, he'⟩ @@ -187,21 +184,20 @@ protected theorem MDifferentiableWithinAt.coordChange · exact (Trivialization.coordChangeL_apply' e e' ⟨he, he'⟩ (g x)).symm protected theorem MDifferentiableAt.coordChange - (hf : MDifferentiableAt IM IB f x) (hg : MDifferentiableAt IM 𝓘(𝕜, F) g x) + (hf : MDiffAt f x) (hg : MDiffAt g x) (he : f x ∈ e.baseSet) (he' : f x ∈ e'.baseSet) : - MDifferentiableAt IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) x := + MDiffAt (fun y ↦ e.coordChange e' (f y) (g y)) x := MDifferentiableWithinAt.coordChange hf hg he he' protected theorem MDifferentiableOn.coordChange - (hf : MDifferentiableOn IM IB f s) (hg : MDifferentiableOn IM 𝓘(𝕜, F) g s) + (hf : MDiff[s] f) (hg : MDiff[s] g) (he : MapsTo f s e.baseSet) (he' : MapsTo f s e'.baseSet) : - MDifferentiableOn IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) s := fun x hx ↦ + MDiff[s] (fun y ↦ e.coordChange e' (f y) (g y)) := fun x hx ↦ (hf x hx).coordChange (hg x hx) (he hx) (he' hx) protected theorem MDifferentiable.coordChange - (hf : MDifferentiable IM IB f) (hg : MDifferentiable IM 𝓘(𝕜, F) g) - (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : - MDifferentiable IM 𝓘(𝕜, F) (fun y ↦ e.coordChange e' (f y) (g y)) := fun x ↦ + (hf : MDiff f) (hg : MDiff g) (he : ∀ x, f x ∈ e.baseSet) (he' : ∀ x, f x ∈ e'.baseSet) : + MDiff (fun y ↦ e.coordChange e' (f y) (g y)) := fun x ↦ (hf x).coordChange (hg x) (he x) (he' x) end coordChange @@ -213,10 +209,9 @@ lemma MDifferentiableWithinAt.change_section_trivialization {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] {e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} - (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) - (he'f : MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀) + (hf : MDiffAt[s] (π F E ∘ f) x₀) (he'f : MDiffAt[s] (fun x ↦ (e (f x)).2) x₀) (he : f x₀ ∈ e.source) (he' : f x₀ ∈ e'.source) : - MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := by + MDiffAt[s] (fun x ↦ (e' (f x)).2) x₀ := by rw [Trivialization.mem_source] at he he' refine (hf.coordChange he'f he he').congr_of_eventuallyEq ?_ ?_ · filter_upwards [hf.continuousWithinAt (e.open_baseSet.mem_nhds he)] with y hy @@ -227,9 +222,8 @@ theorem Trivialization.mdifferentiableWithinAt_snd_comp_iff₂ {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {s : Set M} {x₀ : M} (hex₀ : f x₀ ∈ e.source) (he'x₀ : f x₀ ∈ e'.source) - (hf : MDifferentiableWithinAt IM IB (π F E ∘ f) s x₀) : - MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) s x₀ ↔ - MDifferentiableWithinAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) s x₀ := + (hf : MDiffAt[s] (π F E ∘ f) x₀) : + MDiffAt[s] (fun x ↦ (e (f x)).2) x₀ ↔ MDiffAt[s] (fun x ↦ (e' (f x)).2) x₀ := ⟨(hf.change_section_trivialization IB · hex₀ he'x₀), (hf.change_section_trivialization IB · he'x₀ hex₀)⟩ @@ -239,9 +233,8 @@ theorem Trivialization.mdifferentiableAt_snd_comp_iff₂ {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M → TotalSpace F E} {x₀ : M} (he : f x₀ ∈ e.source) (he' : f x₀ ∈ e'.source) - (hf : MDifferentiableAt IM IB (fun x ↦ (f x).proj) x₀) : - MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e (f x)).2) x₀ ↔ - MDifferentiableAt IM 𝓘(𝕜, F) (fun x ↦ (e' (f x)).2) x₀ := by + (hf : MDiffAt (fun x ↦ (f x).proj) x₀) : + MDiffAt (fun x ↦ (e (f x)).2) x₀ ↔ MDiffAt (fun x ↦ (e' (f x)).2) x₀ := by simpa [← mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_snd_comp_iff₂ IB he he' hf @@ -252,9 +245,7 @@ theorem Trivialization.mdifferentiableWithinAt_totalSpace_iff (f : M → TotalSpace F E) {s : Set M} {x₀ : M} (he : f x₀ ∈ e.source) : MDifferentiableWithinAt IM (IB.prod 𝓘(𝕜, F)) f s x₀ ↔ - MDifferentiableWithinAt IM IB (fun x => (f x).proj) s x₀ ∧ - MDifferentiableWithinAt IM 𝓘(𝕜, F) - (fun x ↦ (e (f x)).2) s x₀ := by + MDiffAt[s] (fun x => (f x).proj) x₀ ∧ MDiffAt[s] (fun x ↦ (e (f x)).2) x₀ := by rw [mdifferentiableWithinAt_totalSpace] apply and_congr_right intro hf @@ -268,9 +259,7 @@ theorem Trivialization.mdifferentiableAt_totalSpace_iff (f : M → TotalSpace F E) {x₀ : M} (he : f x₀ ∈ e.source) : MDifferentiableAt IM (IB.prod 𝓘(𝕜, F)) f x₀ ↔ - MDifferentiableAt IM IB (fun x => (f x).proj) x₀ ∧ - MDifferentiableAt IM 𝓘(𝕜, F) - (fun x ↦ (e (f x)).2) x₀ := by + MDiffAt (fun x => (f x).proj) x₀ ∧ MDiffAt (fun x ↦ (e (f x)).2) x₀ := by rw [mdifferentiableAt_totalSpace] apply and_congr_right intro hf @@ -283,8 +272,7 @@ theorem Trivialization.mdifferentiableWithinAt_section_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (s : Π b : B, E b) {u : Set B} {b₀ : B} (hex₀ : b₀ ∈ e.baseSet) : - MDifferentiableWithinAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) u b₀ ↔ - MDifferentiableWithinAt IB 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) u b₀ := by + MDiffAt[u] (T% s) b₀ ↔ MDiffAt[u] (fun x ↦ (e (s x)).2) b₀ := by rw [e.mdifferentiableWithinAt_totalSpace_iff IB] · change MDifferentiableWithinAt IB IB id u b₀ ∧ _ ↔ _ simp [mdifferentiableWithinAt_id] @@ -296,8 +284,7 @@ theorem Trivialization.mdifferentiableAt_section_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E → B)) [MemTrivializationAtlas e] (s : Π b : B, E b) {b₀ : B} (hex₀ : b₀ ∈ e.baseSet) : - MDifferentiableAt IB (IB.prod 𝓘(𝕜, F)) (fun b ↦ TotalSpace.mk' F b (s b)) b₀ ↔ - MDifferentiableAt IB 𝓘(𝕜, F) (fun x ↦ (e (s x)).2) b₀ := by + MDiffAt (T% s) b₀ ↔ MDiffAt (fun x ↦ (e (s x)).2) b₀ := by simpa [← mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_section_iff IB s hex₀ variable {IB} in @@ -306,7 +293,7 @@ using any trivialisation whose `baseSet` contains `s`. -/ theorem Trivialization.mdifferentiableOn_section_iff {s : ∀ x, E x} {a : Set B} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a ⊆ e.baseSet) : - MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) a ↔ + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (T% s) a ↔ MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) a := by refine ⟨fun h x hx ↦ ?_, fun h x hx ↦ ?_⟩ <;> have := (h x hx).mdifferentiableAt <| ha.mem_nhds hx @@ -319,7 +306,7 @@ can be determined using `e`. -/ theorem Trivialization.mdifferentiableOn_section_baseSet_iff {s : ∀ x, E x} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)) [MemTrivializationAtlas e] : - MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) e.baseSet ↔ + MDifferentiableOn IB (IB.prod 𝓘(𝕜, F)) (T% s) e.baseSet ↔ MDifferentiableOn IB 𝓘(𝕜, F) (fun x ↦ (e ⟨x, s x⟩).2) e.baseSet := e.mdifferentiableOn_section_iff e.open_baseSet subset_rfl @@ -344,9 +331,8 @@ variable variable {f : B → 𝕜} {a : 𝕜} {s t : Π x : B, E x} {u : Set B} {x₀ : B} lemma mdifferentiableWithinAt_add_section - (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (ht : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by + (hs : MDiffAt[u] (T% s) x₀) (ht : MDiffAt[u] (T% t) x₀) : + MDiffAt[u] (T% (s + t)) x₀ := by rw [mdifferentiableWithinAt_section] at hs ht ⊢ set e := trivializationAt F E x₀ refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ @@ -357,27 +343,21 @@ lemma mdifferentiableWithinAt_add_section · exact (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).1 .. lemma mdifferentiableAt_add_section - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (ht : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by + (hs : MDiffAt (T% s) x₀) (ht : MDiffAt (T% t) x₀) : + MDiffAt (T% (s + t)) x₀ := by rw [← mdifferentiableWithinAt_univ] at hs ht ⊢ apply mdifferentiableWithinAt_add_section hs ht lemma mdifferentiableOn_add_section - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) - (ht : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u := + (hs : MDiff[u] (T% s)) (ht : MDiff[u] (T% t)) : MDiff[u] (T% (s + t)) := fun x₀ hx₀ ↦ mdifferentiableWithinAt_add_section (hs x₀ hx₀) (ht x₀ hx₀) lemma mdifferentiable_add_section - (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) - (ht : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := + (hs : MDiff (T% s)) (ht : MDiff (T% t)) : MDiff (T% (s + t)) := fun x₀ ↦ mdifferentiableAt_add_section (hs x₀) (ht x₀) lemma mdifferentiableWithinAt_neg_section - (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (- s x)) u x₀ := by + (hs : MDiffAt[u] (T% s) x₀) : MDiffAt[u] (T% (-s)) x₀ := by rw [mdifferentiableWithinAt_section] at hs ⊢ set e := trivializationAt F E x₀ refine hs.neg.congr_of_eventuallyEq ?_ ?_ @@ -388,51 +368,39 @@ lemma mdifferentiableWithinAt_neg_section · exact (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).map_neg .. lemma mdifferentiableAt_neg_section - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (- s x)) x₀ := by + (hs : MDiffAt (T% s) x₀) : MDiffAt (T% (-s)) x₀ := by rw [← mdifferentiableWithinAt_univ] at hs ⊢ exact mdifferentiableWithinAt_neg_section hs lemma mdifferentiableOn_neg_section - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (-s x)) u := + (hs : MDiff[u] (T% s)) : MDiff[u] (T% (-s)) := fun x₀ hx₀ ↦ mdifferentiableWithinAt_neg_section (hs x₀ hx₀) -lemma mdifferentiable_neg_section - (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (-s x)) := +lemma mdifferentiable_neg_section (hs : MDiff (T% s)) : MDiff (T% (-s)) := fun x₀ ↦ mdifferentiableAt_neg_section (hs x₀) lemma mdifferentiableWithinAt_sub_section - (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (ht : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u x₀ := by + (hs : MDiffAt[u] (T% s) x₀) (ht : MDiffAt[u] (T% t) x₀) : + MDiffAt[u] (T% (s - t)) x₀ := by rw [sub_eq_add_neg] apply mdifferentiableWithinAt_add_section hs <| mdifferentiableWithinAt_neg_section ht lemma mdifferentiableAt_sub_section - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (ht : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) x₀ := by + (hs : MDiffAt (T% s) x₀) (ht : MDiffAt (T% t) x₀) : + MDiffAt (T% (s - t)) x₀ := by rw [sub_eq_add_neg] apply mdifferentiableAt_add_section hs <| mdifferentiableAt_neg_section ht lemma mDifferentiableOn_sub_section - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) - (ht : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u := + (hs : MDiff[u] (T% s)) (ht : MDiff[u] (T% t)) : MDiff[u] (T% (s - t)) := fun x₀ hx₀ ↦ mdifferentiableWithinAt_sub_section (hs x₀ hx₀) (ht x₀ hx₀) lemma mdifferentiable_sub_section - (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) - (ht : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x ((s - t) x)) := + (hs : MDiff (T% s)) (ht : MDiff (T% t)) : MDiff (T% (s - t)) := fun x₀ ↦ mdifferentiableAt_sub_section (hs x₀) (ht x₀) lemma MDifferentiableWithinAt.smul_section - (hf : MDifferentiableWithinAt I 𝓘(𝕜) f u x₀) - (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by + (hf : MDiffAt[u] f x₀) (hs : MDiffAt[u] (T% s) x₀) : MDiffAt[u] (T% (f • s)) x₀ := by rw [mdifferentiableWithinAt_section] at hs ⊢ set e := trivializationAt F E x₀ refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ @@ -442,47 +410,39 @@ lemma MDifferentiableWithinAt.smul_section · exact fun x hx ↦ (e.linear 𝕜 hx).2 .. · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 -lemma MDifferentiableAt.smul_section (hf : MDifferentiableAt I 𝓘(𝕜) f x₀) - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by +lemma MDifferentiableAt.smul_section + (hf : MDiffAt f x₀) (hs : MDiffAt (T% s) x₀) : MDiffAt (T% (f • s)) x₀ := by rw [← mdifferentiableWithinAt_univ] at hs ⊢ exact .smul_section hf hs -lemma MDifferentiableOn.smul_section (hf : MDifferentiableOn I 𝓘(𝕜) f u) - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := +lemma MDifferentiableOn.smul_section + (hf : MDiff[u] f) (hs : MDiff[u] (T% s)) : MDiff[u] (T% (f • s)) := fun x₀ hx₀ ↦ .smul_section (hf x₀ hx₀) (hs x₀ hx₀) -lemma mdifferentiable_smul_section (hf : MDifferentiable I 𝓘(𝕜) f) - (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (f x • s x)) := +lemma mdifferentiable_smul_section + (hf : MDiff f) (hs : MDiff (T% s)) : MDiff (T% (f • s)) := fun x₀ ↦ (hf x₀).smul_section (hs x₀) lemma mdifferentiableWithinAt_smul_const_section - (hs : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := + (hs : MDiffAt[u] (T% s) x₀) : + MDiffAt[u] (T% (a • s)) x₀ := .smul_section mdifferentiableWithinAt_const hs lemma MDifferentiableAt.smul_const_section - (hs : MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := + (hs : MDiffAt (T% s) x₀) : MDiffAt (T% (a • s)) x₀ := .smul_section mdifferentiableAt_const hs lemma MDifferentiableOn.smul_const_section - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) u := + (hs : MDiff[u] (T% s)) : MDiff[u] (T% (a • s)) := .smul_section mdifferentiableOn_const hs lemma mdifferentiable_smul_const_section - (hs : MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (a • s x)) := + (hs : MDiff (T% s)) : MDiff (T% (a • s)) := fun x₀ ↦ (hs x₀).smul_const_section lemma MDifferentiableWithinAt.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} - (hs : ∀ i, MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by + (hs : ∀ i, MDiffAt[u] (T% (t i ·)) x₀) : + MDiffAt[u] (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by classical induction s using Finset.induction_on with | empty => simpa using (contMDiffWithinAt_zeroSection 𝕜 E).mdifferentiableWithinAt le_rfl @@ -490,19 +450,19 @@ lemma MDifferentiableWithinAt.sum_section {ι : Type*} {s : Finset ι} {t : ι simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h lemma MDifferentiableAt.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} {x₀ : B} - (hs : ∀ i, MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by + (hs : ∀ i, MDiffAt (T% (t i ·)) x₀) : + MDiffAt (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by simp_rw [← mdifferentiableWithinAt_univ] at hs ⊢ exact MDifferentiableWithinAt.sum_section hs lemma MDifferentiableOn.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} - (hs : ∀ i, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := + (hs : ∀ i, MDiff[u] (T% (t i ·))) : + MDiff[u] (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := fun x₀ hx₀ ↦ .sum_section fun i ↦ hs i x₀ hx₀ lemma MDifferentiable.sum_section {ι : Type*} {s : Finset ι} {t : ι → (x : B) → E x} - (hs : ∀ i, MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := + (hs : ∀ i, MDiff (T% (t i ·))) : + MDiff (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := fun x₀ ↦ .sum_section fun i ↦ (hs i) x₀ /-- The scalar product `ψ • s` of a differentiable function `ψ : M → 𝕜` and a section `s` of a @@ -511,9 +471,8 @@ vector bundle `V → M` is differentiable once `s` is differentiable on an open See `ContMDiffOn.smul_section_of_tsupport` for the analogous result about `C^n` sections. -/ lemma MDifferentiableOn.smul_section_of_tsupport {s : Π (x : B), E x} {ψ : B → 𝕜} - (hψ : MDifferentiableOn I 𝓘(𝕜) ψ u) (ht : IsOpen u) (ht' : tsupport ψ ⊆ u) - (hs : MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (s x)) u) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by + (hψ : MDiff[u] ψ) (ht : IsOpen u) (ht' : tsupport ψ ⊆ u) (hs : MDiff[u] (T% s)) : + MDiff (T% (ψ • s)) := by apply mdifferentiable_of_mdifferentiableOn_union_of_isOpen (hψ.smul_section hs) ?_ ?_ ht (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) · apply ((mdifferentiable_zeroSection _ _).mdifferentiableOn (s := (tsupport ψ)ᶜ)).congr @@ -529,18 +488,15 @@ open Function Version at a point within a set. -/ lemma MDifferentiableWithinAt.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) u x₀ := by + (ht' : ∀ i, MDiffAt[u] (T% (t i ·)) x₀) : + MDiffAt[u] (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) x₀ := by obtain ⟨u', hu', hfin⟩ := ht x₀ -- All sections `t i` but a finite set `s` vanish near `x₀`: choose a neighbourhood `u` of `x₀` -- and a finite set `s` of sections which don't vanish. let s := {i | ((fun i ↦ {x | t i x ≠ 0}) i ∩ u').Nonempty} have := hfin.fintype - have : MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) (u ∩ u') x₀ := - MDifferentiableWithinAt.sum_section fun i ↦ ((ht' i).mono inter_subset_left) + have : MDiffAt[u ∩ u'] (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := + .sum_section fun i ↦ ((ht' i).mono inter_subset_left) apply (mdifferentiableWithinAt_inter hu').mp apply this.congr' (fun y hy ↦ ?_) inter_subset_right (mem_of_mem_nhds hu') rw [TotalSpace.mk_inj, tsum_eq_sum'] @@ -557,8 +513,8 @@ lemma MDifferentiableWithinAt.sum_section_of_locallyFinite if each section is. -/ lemma MDifferentiableAt.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) x₀ := by + (ht' : ∀ i, MDiffAt (T% (t i ·)) x₀) : + MDiffAt (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) x₀ := by simp_rw [← mdifferentiableWithinAt_univ] at ht' ⊢ exact .sum_section_of_locallyFinite ht ht' @@ -566,22 +522,20 @@ lemma MDifferentiableAt.sum_section_of_locallyFinite if each section is. -/ lemma MDifferentiableOn.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) u := + (ht' : ∀ i, MDiff[u] (T% (t i ·))) : + MDiff[u] (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := fun x hx ↦ .sum_section_of_locallyFinite ht (ht' · x hx) /-- The sum of a locally finite collection of sections is differentiable if each section is. -/ lemma MDifferentiable.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := + (ht' : ∀ i, MDiff (T% (t i ·))) : + MDiff (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := fun x ↦ .sum_section_of_locallyFinite ht fun i ↦ ht' i x lemma MDifferentiableWithinAt.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - MDifferentiableWithinAt I (I.prod 𝓘(𝕜, F)) - (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) u x₀ := by + (ht' : ∀ i, MDiffAt[u] (T% (t i ·)) x₀) : + MDiffAt[u] (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by apply (MDifferentiableWithinAt.sum_section_of_locallyFinite ht ht').congr' (t := Set.univ) (fun y hy ↦ ?_) (by grind) trivial choose U hu hfin using ht y @@ -594,21 +548,19 @@ lemma MDifferentiableWithinAt.finsum_section_of_locallyFinite lemma MDifferentiableAt.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by + (ht' : ∀ i, MDiffAt (T% (t i ·)) x₀) : + MDiffAt (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by simp_rw [← mdifferentiableWithinAt_univ] at ht' ⊢ exact .finsum_section_of_locallyFinite ht ht' lemma MDifferentiableOn.finsum_section_of_locallyFinite - (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) u := + (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) (ht' : ∀ i, MDiff[u] (T% (t i ·))) : + MDiff[u] (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := fun x hx ↦ .finsum_section_of_locallyFinite ht fun i ↦ ht' i x hx lemma MDifferentiable.finsum_section_of_locallyFinite - (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) - (ht' : ∀ i, MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (t i x))) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := + (ht : LocallyFinite fun i ↦ {x : B | t i x ≠ 0}) (ht' : ∀ i, MDiff (T% (t i ·))) : + MDiff (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := fun x ↦ .finsum_section_of_locallyFinite ht fun i ↦ ht' i x end operations @@ -657,7 +609,7 @@ lemma MDifferentiableWithinAt.clm_apply_of_inCoordinates (hϕ : MDifferentiableWithinAt IM 𝓘(𝕜, F₁ →L[𝕜] F₂) (fun m ↦ inCoordinates F₁ E₁ F₂ E₂ (b₁ m₀) (b₁ m) (b₂ m₀) (b₂ m) (ϕ m)) s m₀) (hv : MDifferentiableWithinAt IM (IB₁.prod 𝓘(𝕜, F₁)) (fun m ↦ (v m : TotalSpace F₁ E₁)) s m₀) - (hb₂ : MDifferentiableWithinAt IM IB₂ b₂ s m₀) : + (hb₂ : MDiffAt[s] b₂ m₀) : MDifferentiableWithinAt IM (IB₂.prod 𝓘(𝕜, F₂)) (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) s m₀ := by rw [mdifferentiableWithinAt_totalSpace] at hv ⊢ @@ -695,7 +647,7 @@ lemma MDifferentiableAt.clm_apply_of_inCoordinates (hϕ : MDifferentiableAt IM 𝓘(𝕜, F₁ →L[𝕜] F₂) (fun m ↦ inCoordinates F₁ E₁ F₂ E₂ (b₁ m₀) (b₁ m) (b₂ m₀) (b₂ m) (ϕ m)) m₀) (hv : MDifferentiableAt IM (IB₁.prod 𝓘(𝕜, F₁)) (fun m ↦ (v m : TotalSpace F₁ E₁)) m₀) - (hb₂ : MDifferentiableAt IM IB₂ b₂ m₀) : + (hb₂ : MDiffAt b₂ m₀) : MDifferentiableAt IM (IB₂.prod 𝓘(𝕜, F₂)) (fun m ↦ (ϕ m (v m) : TotalSpace F₂ E₂)) m₀ := by rw [← mdifferentiableWithinAt_univ] at hϕ hv hb₂ ⊢ exact MDifferentiableWithinAt.clm_apply_of_inCoordinates hϕ hv hb₂ From 174d2eb0331a2f1b707f7e1ec94ea0a41b7043d5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 15:54:51 -0700 Subject: [PATCH 393/601] chore(SmoothSection): golf in the same way --- .../Manifold/VectorBundle/SmoothSection.lean | 168 +++++++----------- 1 file changed, 65 insertions(+), 103 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 67e3f7095596a3..96baf2686b8318 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -5,8 +5,9 @@ Authors: Heather Macbeth, Floris van Doorn, Michael Rothgang -/ import Mathlib.Geometry.Manifold.Algebra.LieGroup import Mathlib.Geometry.Manifold.MFDeriv.Basic -import Mathlib.Topology.ContinuousMap.Basic +import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.Basic +import Mathlib.Topology.ContinuousMap.Basic /-! # `C^n` sections @@ -46,9 +47,8 @@ variable {I F n V} variable {f : M → 𝕜} {a : 𝕜} {s t : Π x : M, V x} {u : Set M} {x₀ : M} lemma ContMDiffWithinAt.add_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (ht : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u x₀ := by + (hs : CMDiffAt[u] n (T% s) x₀) (ht : CMDiffAt[u] n (T% t) x₀) : + CMDiffAt[u] n (T% (s + t)) x₀ := by rw [contMDiffWithinAt_section] at hs ht ⊢ set e := trivializationAt F V x₀ refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ @@ -60,27 +60,20 @@ lemma ContMDiffWithinAt.add_section · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).1 lemma ContMDiffAt.add_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) x₀ := by + (hs : CMDiffAt n (T% s) x₀) (ht : CMDiffAt n (T% t) x₀) : CMDiffAt n (T% (s + t)) x₀ := by rw [← contMDiffWithinAt_univ] at hs ⊢ exact hs.add_section ht lemma ContMDiffOn.add_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) - (ht : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) u := + (hs : CMDiff[u] n (T% s)) (ht : CMDiff[u] n (T% t)) : CMDiff[u] n (T% (s + t)) := fun x₀ hx₀ ↦ (hs x₀ hx₀).add_section (ht x₀ hx₀) lemma ContMDiff.add_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) - (ht : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s + t) x)) := + (hs : CMDiff n (T% s)) (ht : CMDiff n (T% t)) : CMDiff n (T% (s + t)) := fun x₀ ↦ (hs x₀).add_section (ht x₀) lemma ContMDiffWithinAt.neg_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (- s x)) u x₀ := by + (hs : CMDiffAt[u] n (T% s) x₀) : CMDiffAt[u] n (T% (-s)) x₀ := by rw [contMDiffWithinAt_section] at hs ⊢ set e := trivializationAt F V x₀ refine hs.neg.congr_of_eventuallyEq ?_ ?_ @@ -91,51 +84,36 @@ lemma ContMDiffWithinAt.neg_section apply (e.linear 𝕜 hx).map_neg · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).map_neg -lemma ContMDiffAt.neg_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (- s x)) x₀ := by +lemma ContMDiffAt.neg_section (hs : CMDiffAt n (T% s) x₀) : CMDiffAt n (T% (-s)) x₀ := by rw [← contMDiffWithinAt_univ] at hs ⊢ exact hs.neg_section -lemma ContMDiffOn.neg_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (-s x)) u := +lemma ContMDiffOn.neg_section (hs : CMDiff[u] n (T% s)) : CMDiff[u] n (T% (-s)) := fun x₀ hx₀ ↦ (hs x₀ hx₀).neg_section -lemma ContMDiff.neg_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (-s x)) := +lemma ContMDiff.neg_section (hs : CMDiff n (T% s)) : CMDiff n (T% (-s)) := fun x₀ ↦ (hs x₀).neg_section -lemma ContMDiffWithinAt.sub_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) - (ht : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u x₀ := by +lemma ContMDiffWithinAt.sub_section (hs : CMDiffAt[u] n (T% s) x₀) (ht : CMDiffAt[u] n (T% t) x₀) : + CMDiffAt[u] n (T% (s - t)) x₀ := by rw [sub_eq_add_neg] exact hs.add_section ht.neg_section lemma ContMDiffAt.sub_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) - (ht : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) x₀ := by + (hs : CMDiffAt n (T% s) x₀) (ht : CMDiffAt n (T% t) x₀) : CMDiffAt n (T% (s - t)) x₀ := by rw [sub_eq_add_neg] apply hs.add_section ht.neg_section lemma ContMDiffOn.sub_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) - (ht : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) u := + (hs : CMDiff[u] n (T% s)) (ht : CMDiff[u] n (T% t)) : CMDiff[u] n (T% (s - t)) := fun x₀ hx₀ ↦ (hs x₀ hx₀).sub_section (ht x₀ hx₀) lemma ContMDiff.sub_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) - (ht : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x ((s - t) x)) := + (hs : CMDiff n (T% s)) (ht : CMDiff n (T% t)) : CMDiff n (T% (s - t)) := fun x₀ ↦ (hs x₀).sub_section (ht x₀) -lemma ContMDiffWithinAt.smul_section (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u x₀) - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u x₀ := by +lemma ContMDiffWithinAt.smul_section + (hf : CMDiffAt[u] n f x₀) (hs : CMDiffAt[u] n (T% s) x₀) : CMDiffAt[u] n (T% (f • s)) x₀ := by rw [contMDiffWithinAt_section] at hs ⊢ set e := trivializationAt F V x₀ refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ @@ -146,49 +124,39 @@ lemma ContMDiffWithinAt.smul_section (hf : ContMDiffWithinAt I 𝓘(𝕜) n f u apply (e.linear 𝕜 hx).2 · apply (e.linear 𝕜 (FiberBundle.mem_baseSet_trivializationAt' x₀)).2 -lemma ContMDiffAt.smul_section (hf : ContMDiffAt I 𝓘(𝕜) n f x₀) - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) x₀ := by +lemma ContMDiffAt.smul_section (hf : CMDiffAt n f x₀) (hs : CMDiffAt n (T% s) x₀) : + CMDiffAt n (T% (f • s)) x₀ := by rw [← contMDiffWithinAt_univ] at hs ⊢ exact .smul_section hf hs -lemma ContMDiffOn.smul_section (hf : ContMDiffOn I 𝓘(𝕜) n f u) - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) u := +lemma ContMDiffOn.smul_section (hf : CMDiff[u] n f) (hs : CMDiff[u] n (T% s)) : + CMDiff[u] n (T% (f • s)) := fun x₀ hx₀ ↦ (hf x₀ hx₀).smul_section (hs x₀ hx₀) -lemma ContMDiff.smul_section (hf : ContMDiff I 𝓘(𝕜) n f) - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (f x • s x)) := +lemma ContMDiff.smul_section (hf : CMDiff n f) (hs : CMDiff n (T% s)) : CMDiff n (T% (f • s)) := fun x₀ ↦ (hf x₀).smul_section (hs x₀) lemma ContMDiffWithinAt.const_smul_section - (hs : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u x₀ := + (hs : CMDiffAt[u] n (T% s) x₀) : CMDiffAt[u] n (T% (a • s)) x₀ := contMDiffWithinAt_const.smul_section hs lemma ContMDiffAt.const_smul_section - (hs : ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) x₀ := + (hs : CMDiffAt n (T% s) x₀) : CMDiffAt n (T% (a • s)) x₀ := contMDiffAt_const.smul_section hs lemma ContMDiffOn.const_smul_section - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) u := + (hs : CMDiff[u] n (T% s)) : CMDiff[u] n (T% (a • s)) := contMDiffOn_const.smul_section hs lemma ContMDiff.const_smul_section - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (a • s x)) := + (hs : CMDiff n (T% s)) : CMDiff n (T% (a • s)) := fun x₀ ↦ (hs x₀).const_smul_section variable {ι : Type*} {t : ι → (x : M) → V x} lemma ContMDiffWithinAt.sum_section {s : Finset ι} - (hs : ∀ i ∈ s, - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n - (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u x₀ := by + (hs : ∀ i ∈ s, CMDiffAt[u] n (T% (t i ·)) x₀) : + CMDiffAt[u] n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by classical induction s using Finset.induction_on with | empty => @@ -199,29 +167,28 @@ lemma ContMDiffWithinAt.sum_section {s : Finset ι} exact h fun i a ↦ hs _ (s.mem_insert_of_mem a) lemma ContMDiffAt.sum_section {s : Finset ι} {x₀ : M} - (hs : ∀ i ∈ s, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by + (hs : ∀ i ∈ s, CMDiffAt n (T% (t i ·)) x₀) : + CMDiffAt n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := by simp_rw [← contMDiffWithinAt_univ] at hs ⊢ exact .sum_section hs lemma ContMDiffOn.sum_section {s : Finset ι} - (hs : ∀ i ∈ s, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) u := + (hs : ∀ i ∈ s, CMDiff[u] n (T% (t i ·))) : + CMDiff[u] n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := fun x₀ hx₀ ↦ .sum_section fun i hi ↦ hs i hi x₀ hx₀ lemma ContMDiff.sum_section {s : Finset ι} - (hs : ∀ i ∈ s, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := + (hs : ∀ i ∈ s, CMDiff n (T% (t i ·))) : + CMDiff n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) := fun x₀ ↦ .sum_section fun i hi ↦ (hs i hi) x₀ /-- The scalar product `ψ • s` of a `C^k` function `ψ : M → 𝕜` and a section `s` of a vector bundle `V → M` is `C^k` once `s` is `C^k` on an open set containing `tsupport ψ`. This is a vector bundle analogue of `contMDiff_of_tsupport`. -/ -lemma ContMDiffOn.smul_section_of_tsupport {s : Π (x : M), V x} {ψ : M → 𝕜} - (hψ : ContMDiffOn I 𝓘(𝕜) n ψ u) (ht : IsOpen u) (ht' : tsupport ψ ⊆ u) - (hs : ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (s x)) u) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by +lemma ContMDiff.smul_section_of_tsupport {s : Π (x : M), V x} {ψ : M → 𝕜} + (hψ : CMDiff[u] n ψ) (ht : IsOpen u) (ht' : tsupport ψ ⊆ u) (hs : CMDiff[u] n (T% s)) : + CMDiff n (T% (ψ • s)) := by apply contMDiff_of_contMDiffOn_union_of_isOpen (hψ.smul_section hs) ?_ ?_ ht (isOpen_compl_iff.mpr <| isClosed_tsupport ψ) · apply ((contMDiff_zeroSection _ _).contMDiffOn (s := (tsupport ψ)ᶜ)).congr @@ -234,26 +201,24 @@ lemma ContMDiffOn.smul_section_of_tsupport {s : Π (x : M), V x} {ψ : M → bundle `V → M` is `C^k` once `s` is `C^k` at each point in `tsupport ψ`. This is a vector bundle analogue of `contMDiff_of_tsupport`. -/ -lemma ContMDiffOn.smul_section_of_tsupport' {s : Π (x : M), V x} {ψ : M → 𝕜} {u : Set M} - (hs : ∀ x ∈ tsupport ψ, - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) x) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (ψ x • s x)) := by +lemma ContMDiff.smul_section_of_tsupport' {s : Π (x : M), V x} {ψ : M → 𝕜} {u : Set M} + (hs : ∀ x ∈ tsupport ψ, CMDiffAt n (T% (ψ • s)) x) : + CMDiff n (T% (ψ • s)) := by sorry /-- The sum of a locally finite collection of sections is `C^k` iff each section is. Version at a point within a set. -/ lemma ContMDiffWithinAt.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) u x₀ := by + (ht' : ∀ i, CMDiffAt[u] n (T% (t i ·)) x₀) : + CMDiffAt[u] n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) x₀ := by obtain ⟨u', hu', hfin⟩ := ht x₀ -- All sections `t i` but a finite set `s` vanish near `x₀`: choose a neighbourhood `u` of `x₀` -- and a finite set `s` of sections which don't vanish. let s := {i | ((fun i ↦ {x | t i x ≠ 0}) i ∩ u').Nonempty} have := hfin.fintype - have : ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n - (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) (u ∩ u') x₀ := - ContMDiffWithinAt.sum_section fun i hi ↦ ((ht' i).mono Set.inter_subset_left) + have : CMDiffAt[u ∩ u'] n (fun x ↦ TotalSpace.mk' F x (∑ i ∈ s, (t i x))) x₀ := + .sum_section fun i hi ↦ ((ht' i).mono Set.inter_subset_left) apply (contMDiffWithinAt_inter hu').mp apply this.congr fun y hy ↦ ?_ · rw [TotalSpace.mk_inj, tsum_eq_sum'] @@ -277,29 +242,29 @@ lemma ContMDiffWithinAt.sum_section_of_locallyFinite /-- The sum of a locally finite collection of sections is `C^k` at `x` iff each section is. -/ lemma ContMDiffAt.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) x₀ := by + (ht' : ∀ i, CMDiffAt n (T% (t i ·)) x₀) : + CMDiffAt n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) x₀ := by simp_rw [← contMDiffWithinAt_univ] at ht' ⊢ exact .sum_section_of_locallyFinite ht ht' /-- The sum of a locally finite collection of sections is `C^k` on a set `u` iff each section is. -/ lemma ContMDiffOn.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) u := + (ht' : ∀ i, CMDiff[u] n (T% (t i ·))) : + CMDiff[u] n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := fun x hx ↦ .sum_section_of_locallyFinite ht (ht' · x hx) /-- The sum of a locally finite collection of sections is `C^k` iff each section is. -/ lemma ContMDiff.sum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := + (ht' : ∀ i, CMDiff n (T% (t i ·))) : + CMDiff n (fun x ↦ TotalSpace.mk' F x (∑' i, (t i x))) := fun x ↦ .sum_section_of_locallyFinite ht fun i ↦ ht' i x -- Future: the next four lemmas can presumably be generalised, but some hypotheses on the supports -- of the sections `t i` are necessary. lemma ContMDiffWithinAt.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u x₀) : - ContMDiffWithinAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) u x₀ := by + (ht' : ∀ i, CMDiffAt[u] n (T% (t i ·)) x₀) : + CMDiffAt[u] n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by apply (ContMDiffWithinAt.sum_section_of_locallyFinite ht ht').congr' (t := Set.univ) (fun y hy ↦ ?_) (by grind) trivial rw [← tsum_eq_finsum (L := SummationFilter.unconditional ι)] @@ -313,20 +278,20 @@ lemma ContMDiffWithinAt.finsum_section_of_locallyFinite lemma ContMDiffAt.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) x₀) : - ContMDiffAt I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by + (ht' : ∀ i, CMDiffAt n (T% (t i ·)) x₀) : + CMDiffAt n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) x₀ := by simp_rw [← contMDiffWithinAt_univ] at ht' ⊢ exact ContMDiffWithinAt.finsum_section_of_locallyFinite ht ht' lemma ContMDiffOn.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x)) u) : - ContMDiffOn I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) u := + (ht' : ∀ i, CMDiff[u] n (T% (t i ·))) : + CMDiff[u] n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := fun x hx ↦ ContMDiffWithinAt.finsum_section_of_locallyFinite ht fun i ↦ ht' i x hx lemma ContMDiff.finsum_section_of_locallyFinite (ht : LocallyFinite fun i ↦ {x : M | t i x ≠ 0}) - (ht' : ∀ i, ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (t i x))) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := + (ht' : ∀ i, CMDiff n (T% (t i ·))) : + CMDiff n (fun x ↦ TotalSpace.mk' F x (∑ᶠ i, t i x)) := fun x ↦ ContMDiffAt.finsum_section_of_locallyFinite ht fun i ↦ ht' i x end operations @@ -337,8 +302,7 @@ structure ContMDiffSection where /-- the underlying function of this section -/ protected toFun : ∀ x, V x /-- proof that this section is `C^n` -/ - protected contMDiff_toFun : ContMDiff I (I.prod 𝓘(𝕜, F)) n fun x ↦ - TotalSpace.mk' F x (toFun x) + protected contMDiff_toFun : CMDiff n (T% toFun) @[inherit_doc] scoped[Manifold] notation "Cₛ^" n "⟮" I "; " F ", " V "⟯" => ContMDiffSection I F n V @@ -353,13 +317,11 @@ instance : DFunLike Cₛ^n⟮I; F, V⟯ M V where variable {s t : Cₛ^n⟮I; F, V⟯} @[simp] -theorem coeFn_mk (s : ∀ x, V x) - (hs : ContMDiff I (I.prod 𝓘(𝕜, F)) n fun x => TotalSpace.mk x (s x)) : - (mk s hs : ∀ x, V x) = s := +theorem coeFn_mk (s : ∀ x, V x) (hs : CMDiff n (T% s)) : (mk s hs : ∀ x, V x) = s := rfl protected theorem contMDiff (s : Cₛ^n⟮I; F, V⟯) : - ContMDiff I (I.prod 𝓘(𝕜, F)) n fun x => TotalSpace.mk' F x (s x : V x) := + CMDiff n (fun x ↦ TotalSpace.mk' F x (s x : V x)) := s.contMDiff_toFun theorem coe_inj ⦃s t : Cₛ^n⟮I; F, V⟯⦄ (h : (s : ∀ x, V x) = t) : s = t := @@ -451,15 +413,15 @@ instance instModule : Module 𝕜 Cₛ^n⟮I; F, V⟯ := end protected theorem mdifferentiable' (s : Cₛ^n⟮I; F, V⟯) (hn : 1 ≤ n) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) fun x => TotalSpace.mk' F x (s x : V x) := + MDiff fun x => TotalSpace.mk' F x (s x : V x) := s.contMDiff.mdifferentiable hn protected theorem mdifferentiable (s : Cₛ^∞⟮I; F, V⟯) : - MDifferentiable I (I.prod 𝓘(𝕜, F)) fun x => TotalSpace.mk' F x (s x : V x) := + MDiff fun x => TotalSpace.mk' F x (s x : V x) := s.contMDiff.mdifferentiable (mod_cast le_top) protected theorem mdifferentiableAt (s : Cₛ^∞⟮I; F, V⟯) {x} : - MDifferentiableAt I (I.prod 𝓘(𝕜, F)) (fun x => TotalSpace.mk' F x (s x : V x)) x := + MDiffAt (fun x => TotalSpace.mk' F x (s x : V x)) x := s.mdifferentiable x end ContMDiffSection From b26811a4c56966704b21d7a55c420a5b9782acfa Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 21:24:46 -0700 Subject: [PATCH 394/601] Revert unintentional changes --- Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean | 2 +- Mathlib/Geometry/Manifold/PartitionOfUnity.lean | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index ebbf7fe867f8b5..30fc1ba3dc8cad 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -25,7 +25,7 @@ and outputs a set of orthogonal vectors which have the same span. then the output vectors are non-zero. - `gramSchmidtBasis`: the basis produced by the Gram-Schmidt process when given a basis as input - `gramSchmidtNormed`: - the normalized `gramSchmidt` (i.e each vector in `gramSchmidtNormed` has unit length.) + the normalized `gramSchmidt` process, i.e each vector in `gramSchmidtNormed` has unit length. - `gramSchmidt_orthonormal`: `gramSchmidtNormed` produces an orthornormal system of vectors. - `gramSchmidtOrthonormalBasis`: orthonormal basis constructed by the Gram-Schmidt process from an indexed set of vectors of the right size diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index ea65178c05a47a..98736bcc241719 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -573,7 +573,7 @@ end SmoothPartitionOfUnity variable [SigmaCompactSpace M] [T2Space M] {t : M → Set F} {n : ℕ∞} -/-- Let `V` be a vector bundle over a σ-compact Hausdorff finite dimensional topological manifold +/-- Let `V` be a vector bundle over a σ-compact Hausdorff finite-dimensional topological manifold `M`. Let `t : M → Set (V x)` be a family of convex sets in the fibers of `V`. Suppose that for each point `x₀ : M` there exists a neighborhood `U_x₀` of `x₀` and a local section `s_loc : M → V x` such that `s_loc` is $C^n$ smooth on `U_x₀` (when viewed as a map to @@ -626,7 +626,7 @@ theorem exists_contMDiffOn_section_forall_mem_convex_of_local have h_x_in_Umap_j : x ∈ W j := interior_subset (hρU j h_x_in_tsupport_ρj) exact h_mem_t j x h_x_in_Umap_j -/-- Let `V` be a vector bundle over a σ-compact Hausdorff finite dimensional topological manifold +/-- Let `V` be a vector bundle over a σ-compact Hausdorff finite-dimensional topological manifold `M`. Let `t : M → Set (V x)` be a family of convex sets in the fibers of `V`. Suppose that for each point `x₀ : M` there exists a neighborhood `U_x₀` of `x₀` and a local section `s_loc : M → V x` such that `s_loc` is $C^∞$ smooth on `U_x₀` (when viewed as a map to @@ -646,7 +646,7 @@ theorem exists_smooth_section_forall_mem_convex_of_local ∃ s : Cₛ^∞⟮I; F_fiber, V⟯, ∀ x : M, s x ∈ t x := exists_contMDiffOn_section_forall_mem_convex_of_local I V t ht_conv Hloc -/-- Let `M` be a σ-compact Hausdorff finite dimensional topological manifold. Let `t : M → Set F` +/-- Let `M` be a σ-compact Hausdorff finite-dimensional topological manifold. Let `t : M → Set F` be a family of convex sets. Suppose that for each point `x : M` there exists a neighborhood `U ∈ 𝓝 x` and a function `g : M → F` such that `g` is $C^n$ smooth on `U` and `g y ∈ t y` for all `y ∈ U`. Then there exists a $C^n$ smooth function `g : C^n⟮I, M; 𝓘(ℝ, F), F⟯` such that `g x ∈ t x` From bf8b4b75993f7d8ca6cdfa989a3cb47a58c9a04f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 8 Oct 2025 21:26:31 -0700 Subject: [PATCH 395/601] Missed one --- Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean index 30fc1ba3dc8cad..4a9b49653e66b6 100644 --- a/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean +++ b/Mathlib/Analysis/InnerProductSpace/GramSchmidtOrtho.lean @@ -25,7 +25,7 @@ and outputs a set of orthogonal vectors which have the same span. then the output vectors are non-zero. - `gramSchmidtBasis`: the basis produced by the Gram-Schmidt process when given a basis as input - `gramSchmidtNormed`: - the normalized `gramSchmidt` process, i.e each vector in `gramSchmidtNormed` has unit length. + the normalized `gramSchmidt` process, i.e each vector in `gramSchmidtNormed` has unit length - `gramSchmidt_orthonormal`: `gramSchmidtNormed` produces an orthornormal system of vectors. - `gramSchmidtOrthonormalBasis`: orthonormal basis constructed by the Gram-Schmidt process from an indexed set of vectors of the right size From ebd470904b28e90248da1c3693e022620c1a5834 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 23 Oct 2025 23:26:13 +0200 Subject: [PATCH 396/601] chore: sync elaborator changes to current master; that's all we need for now --- Mathlib/Geometry/Manifold/Notation.lean | 134 +++--- .../DifferentialGeometry/Notation.lean | 407 +++++++----------- .../NotationAdvanced.lean | 389 +++++++++++++++++ 3 files changed, 617 insertions(+), 313 deletions(-) create mode 100644 MathlibTest/DifferentialGeometry/NotationAdvanced.lean diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index 6b408c0e2521f0..7f5f6c65064348 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -100,7 +100,7 @@ private def findSomeLocalInstanceOf? (c : Name) {α} (p : Expr → Expr → Meta MetaM (Option α) := do (← getLocalInstances).findSomeM? fun inst ↦ do if inst.className == c then - let type ← whnfR <|← instantiateMVars <|← inferType inst.fvar + let type ← whnfR <| ← instantiateMVars <| ← inferType inst.fvar p inst.fvar type else return none @@ -110,7 +110,7 @@ to `p`. -/ private def findSomeLocalHyp? {α} (p : Expr → Expr → MetaM (Option α)) : MetaM (Option α) := do (← getLCtx).findDeclRevM? fun decl ↦ do if decl.isImplementationDetail then return none - let type ← whnfR <|← instantiateMVars decl.type + let type ← whnfR <| ← instantiateMVars decl.type p decl.toExpr type end Elab @@ -132,7 +132,7 @@ run. -- TODO: factor out `MetaM` component for reuse scoped elab:max "T% " t:term:arg : term => do let e ← Term.elabTerm t none - let etype ← whnf <|← instantiateMVars <|← inferType e + let etype ← whnf <| ← instantiateMVars <| ← inferType e match etype with | .forallE x base tgt _ => withLocalDeclD x base fun x ↦ do let tgtHasLooseBVars := tgt.hasLooseBVars @@ -140,14 +140,14 @@ scoped elab:max "T% " t:term:arg : term => do -- Note: we do not run `whnfR` on `tgt` because `Bundle.Trivial` is reducible. match_expr tgt with | Bundle.Trivial E E' _ => - trace[Elab.DiffGeo.TotalSpaceMk] "Section of a trivial bundle" + trace[Elab.DiffGeo.TotalSpaceMk] "`{e}` is a section of `Bundle.Trivial {E} {E'}`" -- Note: we allow `isDefEq` here because any mvar assignments should persist. if ← withReducible (isDefEq E base) then let body ← mkAppM ``Bundle.TotalSpace.mk' #[E', x, e.app x] mkLambdaFVars #[x] body else return e - | TangentSpace _k _ E _ _ _H _ _I _M _ _ _x => - trace[Elab.DiffGeo.TotalSpaceMk] "Vector field" + | TangentSpace _k _ E _ _ _H _ _I M _ _ _x => + trace[Elab.DiffGeo.TotalSpaceMk] "`{e}` is a vector field on `{M}`" let body ← mkAppM ``Bundle.TotalSpace.mk' #[E, x, e.app x] mkLambdaFVars #[x] body | _ => match (← instantiateMVars tgt).cleanupAnnotations with @@ -170,8 +170,9 @@ scoped elab:max "T% " t:term:arg : term => do -- Check that `x` is not a bound variable in `tgt`! if tgtHasLooseBVars then throwError "Attempted to fall back to creating a section of the trivial bundle out of \ - ({e} : {etype}) as a non-dependent function, but return type {tgt} depends on the bound - variable ({x} : {base}).\nHint: applying the `T%` elaborator twice makes no sense." + (`{e}` : `{etype}`) as a non-dependent function, but return type `{tgt}` depends on the + bound variable (`{x}` : `{base}`).\n\ + Hint: applying the `T%` elaborator twice makes no sense." let trivBundle ← mkAppOptM ``Bundle.Trivial #[base, tgt] let body ← mkAppOptM ``Bundle.TotalSpace.mk' #[base, trivBundle, tgt, x, e.app x] mkLambdaFVars #[x] body @@ -202,7 +203,7 @@ private def tryStrategy (strategyDescr : MessageData) (x : TermElabM Expr) : catch ex => trace[Elab.DiffGeo.MDiff] "Failed with error:\n{ex.toMessageData}" throw ex - trace[Elab.DiffGeo.MDiff] "Found model: {e}" + trace[Elab.DiffGeo.MDiff] "Found model: `{e}`" return e catch _ => -- Restore infotrees to prevent any stale hovers, code actions, etc. @@ -213,7 +214,8 @@ private def tryStrategy (strategyDescr : MessageData) (x : TermElabM Expr) : /-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), using the local context to infer the appropriate instance. This supports the following cases: - the model with corners on the total space of a vector bundle -- a model with corners on a manifold +- the model with corners on the tangent space of a manifold +- a model with corners on a manifold, or on its underlying model space - the trivial model `𝓘(𝕜, E)` on a normed space - if the above are not found, try to find a `NontriviallyNormedField` instance on the type of `e`, and if successful, return `𝓘(𝕜)`. @@ -227,6 +229,10 @@ bundle. In this case, it contains a pair of expressions `(e, i)` describing the and the model with corners on the base: these are required to construct the right model with corners. +Note that the matching on `e` does not see through reducibility (e.g. we distinguish the `abbrev` +`TangentBundle` from its definition), so `whnfR` should not be run on `e` prior to calling +`findModel` on it. + This implementation is not maximally robust yet. -/ -- TODO: better error messages when all strategies fail @@ -236,9 +242,9 @@ def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM if let some m ← tryStrategy m!"TotalSpace" fromTotalSpace then return m if let some m ← tryStrategy m!"TangentBundle" fromTangentBundle then return m if let some m ← tryStrategy m!"NormedSpace" fromNormedSpace then return m - if let some m ← tryStrategy m!"ChartedSpace" fromChartedSpace then return m + if let some m ← tryStrategy m!"Manifold" fromManifold then return m if let some m ← tryStrategy m!"NormedField" fromNormedField then return m - throwError "Could not find models with corners for {e}" + throwError "Could not find a model with corners for `{e}`" where /- Note that errors thrown in the following are caught by `tryStrategy` and converted to trace messages. -/ @@ -250,27 +256,19 @@ where if let some m ← tryStrategy m!"From base info" (fromTotalSpace.fromBaseInfo F) then return m if let some m ← tryStrategy m!"TangentSpace" (fromTotalSpace.tangentSpace V) then return m throwError "Having a TotalSpace as source is not yet supported" - | _ => throwError "{e} is not a `Bundle.TotalSpace`." - /-- Attempt to find a model on a `TangentBundle` -/ - fromTangentBundle : TermElabM Expr := do - match_expr e with - | TangentBundle _k _ _E _ _ _H _ I M _ _ => do - trace[Elab.DiffGeo.MDiff] "{e} is a TangentBundle over model {I} on {M}" - let srcIT : Term ← Term.exprToSyntax I - let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT) - Term.elabTerm resTerm none - | _ => throwError "{e} is not a `TangentBundle`" + | _ => throwError "`{e}` is not a `Bundle.TotalSpace`." /-- Attempt to use the provided `baseInfo` to find a model. -/ fromTotalSpace.fromBaseInfo (F : Expr) : TermElabM Expr := do if let some (src, srcI) := baseInfo then - trace[Elab.DiffGeo.MDiff] "Using base info {src}, {srcI}" + trace[Elab.DiffGeo.MDiff] "Using base info `{src}`, `{srcI}`" let some K ← findSomeLocalInstanceOf? ``NormedSpace fun _ type ↦ do match_expr type with | NormedSpace K E _ _ => - if ← withReducible (pureIsDefEq E F) then return some K else return none + if ← withReducible (pureIsDefEq E F) then + trace[Elab.DiffGeo.MDiff] "`{F}` is a normed field over `{K}`"; return some K + else return none | _ => return none - | throwError "Couldn't find a `NormedSpace` structure on {F} among local instances." - trace[Elab.DiffGeo.MDiff] "{F} is a normed field over {K}" + | throwError "Couldn't find a `NormedSpace` structure on `{F}` among local instances." let kT : Term ← Term.exprToSyntax K let srcIT : Term ← Term.exprToSyntax srcI let FT : Term ← Term.exprToSyntax F @@ -282,39 +280,57 @@ where fromTotalSpace.tangentSpace (V : Expr) : TermElabM Expr := do match_expr V with | TangentSpace _k _ _E _ _ _H _ I M _ _ => do - trace[Elab.DiffGeo.MDiff] "This is the total space of the tangent bundle of {M}" + trace[Elab.DiffGeo.MDiff] "`{V}` is the total space of the `TangentBundle` of `{M}`" let srcIT : Term ← Term.exprToSyntax I let resTerm : Term ← ``(ModelWithCorners.prod $srcIT (ModelWithCorners.tangent $srcIT)) Term.elabTerm resTerm none | _ => throwError "{V} is not a `TangentSpace`" + /-- Attempt to find a model on a `TangentBundle` -/ + fromTangentBundle : TermElabM Expr := do + match_expr e with + | TangentBundle _k _ _E _ _ _H _ I M _ _ => do + trace[Elab.DiffGeo.MDiff] "{e} is a `TangentBundle` over model `{I}` on `{M}`" + let srcIT : Term ← Term.exprToSyntax I + let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT) + Term.elabTerm resTerm none + | _ => throwError "`{e}` is not a `TangentBundle`" /-- Attempt to find the trivial model on a normed space. -/ fromNormedSpace : TermElabM Expr := do let some (inst, K) ← findSomeLocalInstanceOf? ``NormedSpace fun inst type ↦ do match_expr type with | NormedSpace K E _ _ => - if ← withReducible (pureIsDefEq E e) then return some (inst, K) else return none + if ← withReducible (pureIsDefEq E e) then return some (inst, K) + else return none | _ => return none - | throwError "Couldn't find a `NormedSpace` structure on {e} among local instances." - trace[Elab.DiffGeo.MDiff] "Field is: {K}" + | throwError "Couldn't find a `NormedSpace` structure on `{e}` among local instances." + trace[Elab.DiffGeo.MDiff] "`{e}` is a normed space over the field `{K}`" mkAppOptM ``modelWithCornersSelf #[K, none, e, none, inst] - /-- Attempt to find a model with corners on a manifold. -/ - fromChartedSpace : TermElabM Expr := do - let some H ← findSomeLocalInstanceOf? ``ChartedSpace fun _ type ↦ do + /-- Attempt to find a model with corners on a manifold, or on the charted space of a manifold. -/ + fromManifold : TermElabM Expr := do + -- Return an expression for a type `H` (if any) such that `e` is a ChartedSpace over `H`, + -- or `e` is `H` itself. + let some H ← findSomeLocalInstanceOf? ``ChartedSpace fun inst type ↦ do + trace[Elab.DiffGeo.MDiff] "considering instance of type `{type}`" match_expr type with | ChartedSpace H _ M _ => - if ← withReducible (pureIsDefEq M e) then return some H else return none + if ← withReducible (pureIsDefEq M e) then + trace[Elab.DiffGeo.MDiff] "`{e}` is a charted space over `{H}` via `{inst}`" + return some H else + if ← withReducible (pureIsDefEq H e) then + trace[Elab.DiffGeo.MDiff] "`{e}` is the charted space of `{M}` via `{inst}`" + return some H else return none | _ => return none - | throwError "Couldn't find a `ChartedSpace` structure on {e} among local instances." - trace[Elab.DiffGeo.MDiff] "H is: {H}" + | throwError "Couldn't find a `ChartedSpace` structure on {e} among local instances, \ + and {e} is not the charted space of some type in the local context either." let some m ← findSomeLocalHyp? fun fvar type ↦ do match_expr type with | ModelWithCorners _ _ _ _ _ H' _ => do if ← withReducible (pureIsDefEq H' H) then return some fvar else return none | _ => return none - | throwError "Couldn't find a `ModelWithCorners` with model space {H} in the local context." + | throwError "Couldn't find a `ModelWithCorners` with model space `{H}` in the local context." return m - /-- Attempt to find a model with corners from a normed field. We attempt to find a global - instance here. -/ + /-- Attempt to find a model with corners from a normed field. + We attempt to find a global instance here. -/ fromNormedField : TermElabM Expr := do let eT : Term ← Term.exprToSyntax e let iTerm : Term ← ``(𝓘($eT, $eT)) @@ -327,36 +343,36 @@ We pass `e` instead of just its type for better diagnostics. If `es` is `some`, we verify that `src` and the type of `es` are definitionally equal. -/ def findModels (e : Expr) (es : Option Expr) : TermElabM (Expr × Expr) := do - let etype ← whnf <|← instantiateMVars <|← inferType e + let etype ← whnf <| ← instantiateMVars <| ← inferType e match etype with | .forallE _ src tgt _ => if tgt.hasLooseBVars then -- TODO: try `T%` here, and if it works, add an interactive suggestion to use it - throwError "Term {e} is a dependent function, of type {etype}\nHint: you can use the `T%` \ - elaborator to convert a dependent function to a non-dependent one" + throwError "Term `{e}` is a dependent function, of type `{etype}`\nHint: you can use \ + the `T%` elaborator to convert a dependent function to a non-dependent one" let srcI ← findModel src if let some es := es then let estype ← inferType es /- Note: we use `isDefEq` here since persistent metavariable assignments in `src` and `estype` are acceptable. TODO: consider attempting to coerce `es` to a `Set`. -/ - if !(← isDefEq estype <|← mkAppM ``Set #[src]) then - throwError "The domain {src} of {e} is not definitionally equal to the carrier type of \ - the set {es} : {estype}" + if !(← isDefEq estype <| ← mkAppM ``Set #[src]) then + throwError "The domain `{src}` of `{e}` is not definitionally equal to the carrier type of \ + the set `{es}` : `{estype}`" let tgtI ← findModel tgt (src, srcI) return (srcI, tgtI) | _ => throwError "Expected{indentD e}\nof type{indentD etype}\nto be a function" end Elab -open Elab Lean.Meta +open Elab /-- `MDiffAt[s] f x` elaborates to `MDifferentiableWithinAt I J f s x`, trying to determine `I` and `J` from the local context. The argument `x` can be omitted. -/ scoped elab:max "MDiffAt[" s:term "]" ppSpace f:term:arg : term => do let es ← Term.elabTerm s none - let ef ← ensureIsFunction <|← Term.elabTerm f none + let ef ← ensureIsFunction <| ← Term.elabTerm f none let (srcI, tgtI) ← findModels ef es mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es] @@ -364,7 +380,7 @@ scoped elab:max "MDiffAt[" s:term "]" ppSpace f:term:arg : term => do trying to determine `I` and `J` from the local context. The argument `x` can be omitted. -/ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do - let e ← ensureIsFunction <|← Term.elabTerm t none + let e ← ensureIsFunction <| ← Term.elabTerm t none let (srcI, tgtI) ← findModels e none mkAppM ``MDifferentiableAt #[srcI, tgtI, e] @@ -374,7 +390,7 @@ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do -- The argument `x` can be omitted. -/ -- scoped elab:max "MDiffAt2" ppSpace t:term:arg : term => do -- let e ← Term.elabTerm t none --- let etype ← whnfR <|← instantiateMVars <|← inferType e +-- let etype ← whnfR <| ← instantiateMVars <| ← inferType e -- forallBoundedTelescope etype (some 1) fun src tgt ↦ do -- if let some src := src[0]? then -- let srcI ← findModel (← inferType src) @@ -391,19 +407,21 @@ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do trying to determine `I` and `J` from the local context. -/ scoped elab:max "MDiff[" s:term "]" ppSpace t:term:arg : term => do let es ← Term.elabTerm s none - let et ← ensureIsFunction <|← Term.elabTerm t none + let et ← ensureIsFunction <| ← Term.elabTerm t none let (srcI, tgtI) ← findModels et es mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es] /-- `MDiff f` elaborates to `MDifferentiable I J f`, trying to determine `I` and `J` from the local context. -/ scoped elab:max "MDiff" ppSpace t:term:arg : term => do - let e ← ensureIsFunction <|← Term.elabTerm t none + let e ← ensureIsFunction <| ← Term.elabTerm t none let (srcI, tgtI) ← findModels e none mkAppM ``MDifferentiable #[srcI, tgtI, e] -- We ensure the type of `n` before checking `f` is a function to provide better error messages --- in case e.g. just `n` was forgotten. +-- in case e.g. `f` and `n` are swapped. +-- TODO: provide better error messages if just `n` is forgotten (say, by making `n` optional in +-- the parser and erroring later in the elaborator); currently, this yields just a parser error. /-- `CMDiffAt[s] n f x` elaborates to `ContMDiffWithinAt I J n f s x`, trying to determine `I` and `J` from the local context. @@ -412,7 +430,7 @@ The argument `x` can be omitted. -/ scoped elab:max "CMDiffAt[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do let es ← Term.elabTerm s none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) - let ef ← ensureIsFunction <|← Term.elabTerm f none + let ef ← ensureIsFunction <| ← Term.elabTerm f none let (srcI, tgtI) ← findModels ef es mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es] @@ -421,7 +439,7 @@ trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). The argument `x` can be omitted. -/ scoped elab:max "CMDiffAt" ppSpace nt:term:arg ppSpace t:term:arg : term => do - let e ← ensureIsFunction <|← Term.elabTerm t none + let e ← ensureIsFunction <| ← Term.elabTerm t none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) let (srcI, tgtI) ← findModels e none mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e] @@ -432,7 +450,7 @@ trying to determine `I` and `J` from the local context. scoped elab:max "CMDiff[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do let es ← Term.elabTerm s none let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) - let ef ← ensureIsFunction <|← Term.elabTerm f none + let ef ← ensureIsFunction <| ← Term.elabTerm f none let (srcI, tgtI) ← findModels ef es mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es] @@ -441,7 +459,7 @@ trying to determine `I` and `J` from the local context. `n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/ scoped elab:max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞) - let e ← ensureIsFunction <|← Term.elabTerm f none + let e ← ensureIsFunction <| ← Term.elabTerm f none let (srcI, tgtI) ← findModels e none mkAppM ``ContMDiff #[srcI, tgtI, ne, e] @@ -449,14 +467,14 @@ scoped elab:max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do trying to determine `I` and `J` from the local context. -/ scoped elab:max "mfderiv[" s:term "]" ppSpace t:term:arg : term => do let es ← Term.elabTerm s none - let e ← ensureIsFunction <|← Term.elabTerm t none + let e ← ensureIsFunction <| ← Term.elabTerm t none let (srcI, tgtI) ← findModels e es mkAppM ``mfderivWithin #[srcI, tgtI, e, es] /-- `mfderiv% f x` elaborates to `mfderiv I J f x`, trying to determine `I` and `J` from the local context. -/ scoped elab:max "mfderiv%" ppSpace t:term:arg : term => do - let e ← ensureIsFunction <|← Term.elabTerm t none + let e ← ensureIsFunction <| ← Term.elabTerm t none let (srcI, tgtI) ← findModels e none mkAppM ``mfderiv #[srcI, tgtI, e] diff --git a/MathlibTest/DifferentialGeometry/Notation.lean b/MathlibTest/DifferentialGeometry/Notation.lean index dc3fa5bb945e8c..e9ca0e1e623698 100644 --- a/MathlibTest/DifferentialGeometry/Notation.lean +++ b/MathlibTest/DifferentialGeometry/Notation.lean @@ -1,17 +1,10 @@ import Mathlib.Geometry.Manifold.Notation -import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -import Mathlib.Geometry.Manifold.VectorBundle.Tangent -import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -import Mathlib.Geometry.Manifold.VectorField.LieBracket +import Mathlib.Geometry.Manifold.VectorBundle.Basic set_option pp.unicode.fun true open Bundle Filter Function Topology - -open scoped Bundle Manifold ContDiff +open scoped Manifold variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @@ -43,8 +36,30 @@ variable {σ : Π x : M, V x} #guard_msgs in #check T% σ --- Testing precedence. +-- Note how the name of the bound variable `x` resp. `y` is preserved. +/-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% σ' + +/-- info: fun y ↦ TotalSpace.mk' E' y (σ'' y) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% σ'' + +/-- info: fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E') -/ +#guard_msgs in +#check T% s + +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + +/-- info: fun m ↦ TotalSpace.mk' E m (X m) : M → TotalSpace E (TangentSpace I) -/ +#guard_msgs in +#check T% X + variable {x : M} + +-- Testing precedence. +section precedence + /-- info: (fun x ↦ TotalSpace.mk' F x (σ x)) x : TotalSpace F V -/ #guard_msgs in #check (T% σ) x @@ -56,24 +71,32 @@ variable {x : M} #guard_msgs in #check T% (σ x) --- Note how the name of the bound variable `x` resp. `y` is preserved. -/-- info: fun x ↦ TotalSpace.mk' E' x (σ' x) : E → TotalSpace E' (Trivial E E') -/ -#guard_msgs in -#check T% σ' +-- Testing precedence when applied to a family of section. +variable {ι j : Type*} -/-- info: fun y ↦ TotalSpace.mk' E' y (σ'' y) : E → TotalSpace E' (Trivial E E') -/ +-- Partially applied. +/-- +info: fun a ↦ TotalSpace.mk' ((x : M) → V x) a (s a) : ι → TotalSpace ((x : M) → V x) (Trivial ι ((x : M) → V x)) +-/ #guard_msgs in -#check T% σ'' +variable {s : ι → (x : M) → V x} in +#check T% s -/-- info: fun a ↦ TotalSpace.mk' E' a (s a) : E → TotalSpace E' (Trivial E E') -/ +/-- +info: (fun a ↦ TotalSpace.mk' (ι → (x : M) → V x) a (s a)) i : TotalSpace (ι → (x : M) → V x) (Trivial ι (ι → (x : M) → V x)) +-/ #guard_msgs in -#check T% s +variable {s : ι → ι → (x : M) → V x} {i : ι} in +#check T% s i -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] +variable {X : ι → Π x : M, TangentSpace I x} {i : ι} -/-- info: fun m ↦ TotalSpace.mk' E m (X m) : M → TotalSpace E (TangentSpace I) -/ +-- Error message is okay, but not great. +/-- error: Could not find a model with corners for `ι` -/ #guard_msgs in -#check T% X +#check MDiffAt (T% X) x + +end precedence example : (fun m ↦ (X m : TangentBundle I M)) = (fun m ↦ TotalSpace.mk' E m (X m)) := rfl @@ -92,11 +115,13 @@ end TotalSpace /-! Tests for the elaborators for `MDifferentiable{WithinAt,At,On}`. -/ section differentiability --- Start with some basic tests: a simple function, both in applied and unapplied form. variable {EM' : Type*} [NormedAddCommGroup EM'] [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] +/-! Some basic tests: a simple function, both in applied and unapplied form -/ +section basic + -- General case: a function between two manifolds. variable {f : M → M'} {s : Set M} {m : M} @@ -120,6 +145,17 @@ variable {f : M → M'} {s : Set M} {m : M} #guard_msgs in #check MDiff[s] f +-- A partial homeomorphism or partial equivalence. +variable {φ : OpenPartialHomeomorph M E} {ψ : PartialEquiv M E} + +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑φ) s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] φ + +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑ψ) s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] ψ + -- Testing an error message. section @@ -306,92 +342,35 @@ variable {f : 𝕜 → 𝕜} {u : Set 𝕜} {a : 𝕜} #guard_msgs in #check MDiff[u] f --- This elaborator can be combined with the total space elaborator. --- XXX: these tests might be incomplete; extend as needed! +end basic variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ -#guard_msgs in -#check MDiffAt (T% X) - -/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ -#guard_msgs in -#check MDiffAt (T% σ) - -/-- -info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop --/ -#guard_msgs in -#check MDiffAt (T% σ') - +/-! (Extended) charts -/ section -variable [IsManifold I 2 M] - -variable {h : Bundle.TotalSpace F (TangentSpace I : M → Type _) → F} {h' : TangentBundle I M → F} +variable {φ : OpenPartialHomeomorph M H} {ψ : PartialEquiv M E} {s : Set M} --- Test the inference of a model with corners on a trivial bundle over the tangent space of a --- manifold. (This code path is not covered by the other tests, hence should be kept.) --- Stating smoothness this way does not make sense, but finding a model with corners should work. -/-- -error: failed to synthesize - TopologicalSpace (TotalSpace F (TangentSpace I)) - -Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. ---- -trace: [Elab.DiffGeo.MDiff] Finding a model for: TotalSpace F (TangentSpace I) -[Elab.DiffGeo.MDiff] ✅️ TotalSpace - [Elab.DiffGeo.MDiff] ❌️ From base info - [Elab.DiffGeo.MDiff] Failed with error: - No `baseInfo` provided - [Elab.DiffGeo.MDiff] ✅️ TangentSpace - [Elab.DiffGeo.MDiff] This is the total space of the tangent bundle of M - [Elab.DiffGeo.MDiff] Found model: I.prod I.tangent - [Elab.DiffGeo.MDiff] Found model: I.prod I.tangent -[Elab.DiffGeo.MDiff] Finding a model for: F -[Elab.DiffGeo.MDiff] ❌️ TotalSpace - [Elab.DiffGeo.MDiff] Failed with error: - F is not a `Bundle.TotalSpace`. -[Elab.DiffGeo.MDiff] ❌️ TangentBundle - [Elab.DiffGeo.MDiff] Failed with error: - F is not a `TangentBundle` -[Elab.DiffGeo.MDiff] ✅️ NormedSpace - [Elab.DiffGeo.MDiff] Field is: 𝕜 - [Elab.DiffGeo.MDiff] Found model: 𝓘(𝕜, F) --/ +/-- info: ContMDiff I I 37 ↑φ : Prop -/ #guard_msgs in -set_option trace.Elab.DiffGeo true in -#check MDiff h - --- The reason this test fails is that Bundle.TotalSpace F (TangentSpace I : M → Type _) is not --- the way to state smoothness. -/-- -error: failed to synthesize - TopologicalSpace (TotalSpace F (TangentSpace I)) - -Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. --/ -#guard_msgs in -#synth IsManifold I.tangent 1 (Bundle.TotalSpace F (TangentSpace I : M → Type _)) +#check CMDiff 37 φ --- The correct way is this. -/-- info: TotalSpace.isManifold E (TangentSpace I) -/ +/-- info: MDifferentiable I I ↑φ : Prop -/ #guard_msgs in -#synth IsManifold I.tangent 1 (TangentBundle I M) +#check MDiff φ -/-- info: MDifferentiable I.tangent 𝓘(𝕜, F) h' : Prop -/ +/-- info: MDifferentiable I 𝓘(𝕜, E) ↑ψ : Prop -/ #guard_msgs in -#check MDifferentiable I.tangent 𝓘(𝕜, F) h' +#check MDiff ψ -/-- info: MDifferentiable (I.prod 𝓘(𝕜, E)) 𝓘(𝕜, F) h' : Prop -/ +/-- info: MDifferentiableWithinAt I I (↑φ) s : M → Prop -/ #guard_msgs in -#check MDifferentiable (I.prod (𝓘(𝕜, E))) 𝓘(𝕜, F) h' +#check MDiffAt[s] φ -/-- info: MDifferentiable I.tangent 𝓘(𝕜, F) h' : Prop -/ +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑ψ) s : M → Prop -/ #guard_msgs in -#check MDiff h' +#check MDiffAt[s] ψ end @@ -399,63 +378,63 @@ end section /-- -error: Term X is a dependent function, of type (m : M) → TangentSpace I m +error: Term `X` is a dependent function, of type `(m : M) → TangentSpace I m` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiff X /-- -error: Term σ is a dependent function, of type (x : M) → V x +error: Term `σ` is a dependent function, of type `(x : M) → V x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiff σ /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiff σ' /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiff[s] σ' /-- -error: Term X is a dependent function, of type (m : M) → TangentSpace I m +error: Term `X` is a dependent function, of type `(m : M) → TangentSpace I m` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiffAt (X) /-- -error: Term σ is a dependent function, of type (x : M) → V x +error: Term `σ` is a dependent function, of type `(x : M) → V x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiffAt ((σ)) /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiff[s] σ' /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check MDiffAt σ' /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in @@ -481,10 +460,11 @@ variable {f : M → M'} {s : Set M} {m : M} variable [IsManifold I 1 M] [IsManifold I' 1 M'] --- TODO: can there be better error messages when forgetting the smoothness exponent? +-- Testing error messages when forgetting the smoothness exponent or swapping arguments. section error --- yields a parse error, "unexpected toekn '/--'; expected term" +-- yields a parse error, "unexpected token '/--'; expected term" +-- TODO: make this parse, but error in the elaborator -- #check CMDiffAt[s] f /-- @@ -521,11 +501,29 @@ of type to be a function, or to be coercible to a function -/ #guard_msgs in -#check CMDiffAt[s] f m +#check CMDiff[s] f m --- yields a parse error, "unexpected toekn '/--'; expected term" +-- yields a parse error, "unexpected token '/--'; expected term" -- #check CMDiffAt f +/-- +error: Type mismatch + f +has type + M → M' +of sort `Type (max u_10 u_4)` but is expected to have type + WithTop ℕ∞ +of sort `Type` +--- +error: Expected + n +of type + Option ℕ∞ +to be a function, or to be coercible to a function +-/ +#guard_msgs in +#check CMDiff f n + end error /-- info: ContMDiffWithinAt I I' 1 f s : M → Prop -/ @@ -673,71 +671,85 @@ end coercions section dependent variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] +variable {ι : Type*} {i : ι} (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + (X' : ι → (m : M) → TangentSpace I m) /-- -error: Term X is a dependent function, of type (m : M) → TangentSpace I m +error: Term `X` is a dependent function, of type `(m : M) → TangentSpace I m` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiff 0 X /-- -error: Term σ is a dependent function, of type (x : M) → V x +error: Term `σ` is a dependent function, of type `(x : M) → V x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiff 0 σ /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiff 0 σ' /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiff[s] 0 σ' /-- -error: Term X is a dependent function, of type (m : M) → TangentSpace I m +error: Term `X` is a dependent function, of type `(m : M) → TangentSpace I m` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiffAt 0 (X) /-- -error: Term σ is a dependent function, of type (x : M) → V x +error: Term `σ` is a dependent function, of type `(x : M) → V x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiffAt 0 ((σ)) /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiff[s] 0 σ' /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiffAt 0 σ' /-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one -/ #guard_msgs in #check CMDiffAt[s] 0 σ' +/-- +error: Term `X' i` is a dependent function, of type `(m : M) → TangentSpace I m` +Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one +-/ +#guard_msgs in +#check MDiffAt ((X' i)) x + +-- This error message is not great: this is missing *both* a T% elaborator +-- and an argument i. +/-- error: Could not find a model with corners for `ι` -/ +#guard_msgs in +#check MDiffAt X' x + end dependent -- Function from a manifold into a normed space. @@ -826,161 +838,45 @@ variable {f : E → E'} {s : Set E} {x : E} end smoothness -/-! Tests for the custom elaborators for `mfderiv` and `mfderivWithin` -/ -section mfderiv +-- Inferring the type of `x` for all ContMDiff/MDifferentiable{Within}At elaborators. +section variable {EM' : Type*} [NormedAddCommGroup EM'] [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + {f : M → M'} {s : Set M} -variable {f : M → M'} {s : Set M} {m : M} - -/-- info: mfderiv I I' f : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ -#guard_msgs in -#check mfderiv% f - -/-- info: mfderiv I I' f m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ -#guard_msgs in -#check mfderiv% f m - -/-- info: mfderivWithin I I' f s : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ -#guard_msgs in -#check mfderiv[s] f - -/-- info: mfderivWithin I I' f s m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ -#guard_msgs in -#check mfderiv[s] f m - -variable {f : E → EM'} {s : Set E} {m : E} - -/-- -info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) --/ -#guard_msgs in -#check mfderiv% f - -/-- -info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) --/ -#guard_msgs in -#check mfderiv% f m - -/-- -info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) --/ -#guard_msgs in -#check mfderiv[s] f - -/-- -info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) --/ -#guard_msgs in -#check mfderiv[s] f m - -variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} -variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] {x : M} - -/-- -info: mfderiv I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) - x : TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, E)) (TotalSpace.mk' E x (X x)) --/ -#guard_msgs in -#check mfderiv% (T% X) x - -/-- -info: mfderiv I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) - x : TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) (TotalSpace.mk' F x (σ x)) --/ +/-- info: {x | MDifferentiableAt I I' f x} : Set M -/ #guard_msgs in -#check mfderiv% (T% σ) x - -variable {t : Set E} {p : E} +#check {x | MDiffAt f x} -/-- -info: mfderivWithin 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ' x)) t - p : TangentSpace 𝓘(𝕜, E) p →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (TotalSpace.mk' E' p (σ' p)) --/ +/-- info: {x | MDifferentiableWithinAt I I' f s x} : Set M -/ #guard_msgs in -#check mfderiv[t] (T% σ') p +#check {x | MDiffAt[s] f x} -/-- -info: mfderivWithin 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ' x)) - t : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (TotalSpace.mk' E' x (σ' x)) --/ +/-- info: {x | ContMDiffAt I I' ⊤ f x} : Set M -/ #guard_msgs in -#check mfderiv[t] (T% σ') - -section errors - --- Test an error message, about mismatched types. -variable {s' : Set M} {m' : M} +#check {x | CMDiffAt ⊤ f x} -/-- -error: Application type mismatch: The argument - m' -has type - M -of sort `Type u_4` but is expected to have type - E -of sort `Type u_2` in the application - mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m' ---- -info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f sorry : TangentSpace 𝓘(𝕜, E) sorry →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f sorry) --/ +/-- info: {x | ContMDiffWithinAt I I' 2 f s x} : Set M -/ #guard_msgs in -#check mfderiv% f m' +#check {x | CMDiffAt[s] 2 f x} --- Error messages: argument s has mismatched type. -/-- -error: The domain E of f is not definitionally equal to the carrier type of the set s' : Set M --/ +open ContDiff in -- for the ∞ notation +/-- info: {x | ContMDiffAt I I' ∞ f x} : Set M -/ #guard_msgs in -#check mfderiv[s'] f +#check {x | CMDiffAt ∞ f x} -/-- -error: The domain E of f is not definitionally equal to the carrier type of the set s' : Set M --/ +/-- info: {x | Injective ⇑(mfderiv I I' f x)} : Set M -/ #guard_msgs in -#check mfderiv[s'] f m +#check {x | Function.Injective (mfderiv% f x) } -end errors - -section - -/-- -error: Term X is a dependent function, of type (m : M) → TangentSpace I m -Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one --/ +/-- info: {x | Surjective ⇑(mfderivWithin I I' f s x)} : Set M -/ #guard_msgs in -#check mfderiv% X x - -/-- -error: Term σ is a dependent function, of type (x : M) → V x -Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one --/ -#guard_msgs in -#check mfderiv% σ x - -variable {t : Set E} {p : E} - -/-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x -Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one --/ -#guard_msgs in -#check mfderiv[t] σ' p - -/-- -error: Term σ' is a dependent function, of type (x : E) → Trivial E E' x -Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one --/ -#guard_msgs in -#check mfderiv[t] σ' +#check {x | Function.Surjective (mfderiv[s] f x) } end -end mfderiv - section trace /- Test that basic tracing works. -/ @@ -990,21 +886,22 @@ set_option trace.Elab.DiffGeo true variable {f : Unit → Unit} /-- -error: Could not find models with corners for Unit +error: Could not find a model with corners for `Unit` --- trace: [Elab.DiffGeo.MDiff] Finding a model for: Unit [Elab.DiffGeo.MDiff] ❌️ TotalSpace [Elab.DiffGeo.MDiff] Failed with error: - Unit is not a `Bundle.TotalSpace`. + `Unit` is not a `Bundle.TotalSpace`. [Elab.DiffGeo.MDiff] ❌️ TangentBundle [Elab.DiffGeo.MDiff] Failed with error: - Unit is not a `TangentBundle` + `Unit` is not a `TangentBundle` [Elab.DiffGeo.MDiff] ❌️ NormedSpace [Elab.DiffGeo.MDiff] Failed with error: - Couldn't find a `NormedSpace` structure on Unit among local instances. -[Elab.DiffGeo.MDiff] ❌️ ChartedSpace + Couldn't find a `NormedSpace` structure on `Unit` among local instances. +[Elab.DiffGeo.MDiff] ❌️ Manifold + [Elab.DiffGeo.MDiff] considering instance of type `ChartedSpace H M` [Elab.DiffGeo.MDiff] Failed with error: - Couldn't find a `ChartedSpace` structure on Unit among local instances. + Couldn't find a `ChartedSpace` structure on Unit among local instances, and Unit is not the charted space of some type in the local context either. [Elab.DiffGeo.MDiff] ❌️ NormedField [Elab.DiffGeo.MDiff] Failed with error: failed to synthesize diff --git a/MathlibTest/DifferentialGeometry/NotationAdvanced.lean b/MathlibTest/DifferentialGeometry/NotationAdvanced.lean new file mode 100644 index 00000000000000..9c474e1eca9451 --- /dev/null +++ b/MathlibTest/DifferentialGeometry/NotationAdvanced.lean @@ -0,0 +1,389 @@ +import Mathlib.Geometry.Manifold.Notation +import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +import Mathlib.Geometry.Manifold.VectorBundle.Tangent +import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.BumpFunction +import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +import Mathlib.Geometry.Manifold.VectorField.LieBracket + +/-! +# Tests for the differential geometry elaborators which require stronger imports +-/ + +set_option pp.unicode.fun true + +open Bundle Filter Function Topology +open scoped Manifold + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +section + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + (V : M → Type*) [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] + -- `V` vector bundle + +/-! Additional tests for the elaborators for `MDifferentiable{WithinAt,At,On}`. -/ +section differentiability + +variable {EM' : Type*} [NormedAddCommGroup EM'] + [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +/-! A partial homeomorphism or partial equivalence. More generally, this works for any type +with a coercion to (possibly dependent) functions. -/ +section coercion + +variable {s : Set M} {m : M} + +variable {φ : OpenPartialHomeomorph M E} {ψ : PartialEquiv M E} + +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑φ) s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] φ + +/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑ψ) s : M → Prop -/ +#guard_msgs in +#check MDiffAt[s] ψ + +/-- info: MDifferentiableAt I 𝓘(𝕜, E) ↑φ : M → Prop -/ +#guard_msgs in +#check MDiffAt φ + +/-- info: MDifferentiableAt I 𝓘(𝕜, E) ↑ψ : M → Prop -/ +#guard_msgs in +#check MDiffAt ψ + +/-- info: MDifferentiableOn I 𝓘(𝕜, E) (↑φ) s : Prop -/ +#guard_msgs in +#check MDiff[s] φ + +/-- info: MDifferentiableOn I 𝓘(𝕜, E) (↑ψ) s : Prop -/ +#guard_msgs in +#check MDiff[s] ψ + +/-- info: MDifferentiable I 𝓘(𝕜, E) ↑φ : Prop -/ +#guard_msgs in +#check MDiff φ + +/-- info: ContMDiffWithinAt I 𝓘(𝕜, E) 2 (↑ψ) s : M → Prop -/ +#guard_msgs in +#check CMDiffAt[s] 2 ψ + +/-- info: ContMDiffOn I 𝓘(𝕜, E) 2 (↑φ) s : Prop -/ +#guard_msgs in +#check CMDiff[s] 2 φ + +/-- info: ContMDiffAt I 𝓘(𝕜, E) 2 ↑φ : M → Prop -/ +#guard_msgs in +#check CMDiffAt 2 φ + +/-- info: ContMDiff I 𝓘(𝕜, E) 2 ↑ψ : Prop -/ +#guard_msgs in +#check CMDiff 2 ψ + +/-- info: mfderiv I 𝓘(𝕜, E) ↑φ : (x : M) → TangentSpace I x →L[𝕜] TangentSpace 𝓘(𝕜, E) (↑φ x) -/ +#guard_msgs in +#check mfderiv% φ + +/-- +info: mfderivWithin I 𝓘(𝕜, E) (↑ψ) s : (x : M) → TangentSpace I x →L[𝕜] TangentSpace 𝓘(𝕜, E) (↑ψ x) +-/ +#guard_msgs in +#check mfderiv[s] ψ + +/-- +info: mfderivWithin I 𝓘(𝕜, E) (↑ψ) s : (x : M) → TangentSpace I x →L[𝕜] TangentSpace 𝓘(𝕜, E) (↑ψ x) +-/ +#guard_msgs in +variable {f : ContMDiffSection I F n V} in +#check mfderiv[s] ψ + +/-- info: mfderiv I I' ⇑g : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (g x) -/ +#guard_msgs in +variable {g : ContMDiffMap I I' M M' n} in +#check mfderiv% g + +-- An example of "any type" which coerces to functions. +/-- info: mfderiv I I' ⇑g : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (g x) -/ +#guard_msgs in +variable {g : Equiv M M'} in +#check mfderiv% g + +end coercion + +variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] + +/-! These elaborators can be combined with the total space elaborator. -/ +section interaction + +-- Note: these tests might be incomplete; extend as needed! + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, E)) fun m ↦ TotalSpace.mk' E m (X m) : M → Prop -/ +#guard_msgs in +#check MDiffAt (T% X) + +/-- info: MDifferentiableAt I (I.prod 𝓘(𝕜, F)) fun x ↦ TotalSpace.mk' F x (σ x) : M → Prop -/ +#guard_msgs in +#check MDiffAt (T% σ) + +/-- +info: MDifferentiableAt 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) fun x ↦ TotalSpace.mk' E' x (σ' x) : E → Prop +-/ +#guard_msgs in +#check MDiffAt (T% σ') + +end interaction + +-- Total space over the tangent space and tangent bundle. +section + +variable [IsManifold I 2 M] + +variable {h : Bundle.TotalSpace F (TangentSpace I : M → Type _) → F} {h' : TangentBundle I M → F} + +-- Test the inference of a model with corners on a trivial bundle over the tangent space of a +-- manifold. (This code path is not covered by the other tests, hence should be kept.) +-- Stating smoothness this way does not make sense, but finding a model with corners should work. +/-- +error: failed to synthesize + TopologicalSpace (TotalSpace F (TangentSpace I)) + +Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. +--- +trace: [Elab.DiffGeo.MDiff] Finding a model for: TotalSpace F (TangentSpace I) +[Elab.DiffGeo.MDiff] ✅️ TotalSpace + [Elab.DiffGeo.MDiff] ❌️ From base info + [Elab.DiffGeo.MDiff] Failed with error: + No `baseInfo` provided + [Elab.DiffGeo.MDiff] ✅️ TangentSpace + [Elab.DiffGeo.MDiff] `TangentSpace I` is the total space of the `TangentBundle` of `M` + [Elab.DiffGeo.MDiff] Found model: `I.prod I.tangent` + [Elab.DiffGeo.MDiff] Found model: `I.prod I.tangent` +[Elab.DiffGeo.MDiff] Finding a model for: F +[Elab.DiffGeo.MDiff] ❌️ TotalSpace + [Elab.DiffGeo.MDiff] Failed with error: + `F` is not a `Bundle.TotalSpace`. +[Elab.DiffGeo.MDiff] ❌️ TangentBundle + [Elab.DiffGeo.MDiff] Failed with error: + `F` is not a `TangentBundle` +[Elab.DiffGeo.MDiff] ✅️ NormedSpace + [Elab.DiffGeo.MDiff] `F` is a normed space over the field `𝕜` + [Elab.DiffGeo.MDiff] Found model: `𝓘(𝕜, F)` +-/ +#guard_msgs in +set_option trace.Elab.DiffGeo true in +#check MDiff h + +-- The reason this test fails is that Bundle.TotalSpace F (TangentSpace I : M → Type _) is not +-- the way to state smoothness. +/-- +error: failed to synthesize + TopologicalSpace (TotalSpace F (TangentSpace I)) + +Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. +-/ +#guard_msgs in +#synth IsManifold I.tangent 1 (Bundle.TotalSpace F (TangentSpace I : M → Type _)) + +-- The correct way is this. +/-- info: TotalSpace.isManifold E (TangentSpace I) -/ +#guard_msgs in +#synth IsManifold I.tangent 1 (TangentBundle I M) + +/-- info: MDifferentiable I.tangent 𝓘(𝕜, F) h' : Prop -/ +#guard_msgs in +#check MDifferentiable I.tangent 𝓘(𝕜, F) h' + +/-- info: MDifferentiable (I.prod 𝓘(𝕜, E)) 𝓘(𝕜, F) h' : Prop -/ +#guard_msgs in +#check MDifferentiable (I.prod (𝓘(𝕜, E))) 𝓘(𝕜, F) h' + +/-- info: MDifferentiable I.tangent 𝓘(𝕜, F) h' : Prop -/ +#guard_msgs in +#check MDiff h' + +end + +-- Inferring a model with corners on a space of linear maps between normed spaces +-- is currently not supported. +variable {f : M → E →L[𝕜] E'} in +/-- error: Could not find a model with corners for `E →L[𝕜] E'` -/ +#guard_msgs in +#check MDiff f + +variable {f : M → E →L[𝕜] E'} in +/-- error: Could not find a model with corners for `E →L[𝕜] E'` -/ +#guard_msgs in +#check CMDiff 2 f + +end differentiability + +/-! Tests for the custom elaborators for `mfderiv` and `mfderivWithin` -/ +section mfderiv + +variable {EM' : Type*} [NormedAddCommGroup EM'] + [NormedSpace 𝕜 EM'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 EM' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +variable {f : M → M'} {s : Set M} {m : M} + +/-- info: mfderiv I I' f : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ +#guard_msgs in +#check mfderiv% f + +/-- info: mfderiv I I' f m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ +#guard_msgs in +#check mfderiv% f m + +/-- info: mfderivWithin I I' f s : (x : M) → TangentSpace I x →L[𝕜] TangentSpace I' (f x) -/ +#guard_msgs in +#check mfderiv[s] f + +/-- info: mfderivWithin I I' f s m : TangentSpace I m →L[𝕜] TangentSpace I' (f m) -/ +#guard_msgs in +#check mfderiv[s] f m + +variable {f : E → EM'} {s : Set E} {m : E} + +/-- +info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) +-/ +#guard_msgs in +#check mfderiv% f + +/-- +info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) +-/ +#guard_msgs in +#check mfderiv% f m + +/-- +info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f x) +-/ +#guard_msgs in +#check mfderiv[s] f + +/-- +info: mfderivWithin 𝓘(𝕜, E) 𝓘(𝕜, EM') f s m : TangentSpace 𝓘(𝕜, E) m →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f m) +-/ +#guard_msgs in +#check mfderiv[s] f m + +variable {σ : Π x : M, V x} {σ' : (x : E) → Trivial E E' x} {s : E → E'} +variable (X : (m : M) → TangentSpace I m) [IsManifold I 1 M] {x : M} + +/-- +info: mfderiv I (I.prod 𝓘(𝕜, E)) (fun m ↦ TotalSpace.mk' E m (X m)) + x : TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, E)) (TotalSpace.mk' E x (X x)) +-/ +#guard_msgs in +#check mfderiv% (T% X) x + +/-- +info: mfderiv I (I.prod 𝓘(𝕜, F)) (fun x ↦ TotalSpace.mk' F x (σ x)) + x : TangentSpace I x →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) (TotalSpace.mk' F x (σ x)) +-/ +#guard_msgs in +#check mfderiv% (T% σ) x + +variable {t : Set E} {p : E} + +/-- +info: mfderivWithin 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ' x)) t + p : TangentSpace 𝓘(𝕜, E) p →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (TotalSpace.mk' E' p (σ' p)) +-/ +#guard_msgs in +#check mfderiv[t] (T% σ') p + +/-- +info: mfderivWithin 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (fun x ↦ TotalSpace.mk' E' x (σ' x)) + t : (x : E) → TangentSpace 𝓘(𝕜, E) x →L[𝕜] TangentSpace (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (TotalSpace.mk' E' x (σ' x)) +-/ +#guard_msgs in +#check mfderiv[t] (T% σ') + +section errors + +-- Test an error message, about mismatched types. +variable {s' : Set M} {m' : M} + +/-- +error: Application type mismatch: The argument + m' +has type + M +of sort `Type u_4` but is expected to have type + E +of sort `Type u_2` in the application + mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f m' +--- +info: mfderiv 𝓘(𝕜, E) 𝓘(𝕜, EM') f sorry : TangentSpace 𝓘(𝕜, E) sorry →L[𝕜] TangentSpace 𝓘(𝕜, EM') (f sorry) +-/ +#guard_msgs in +#check mfderiv% f m' + +-- Error messages: argument s has mismatched type. +/-- +error: The domain `E` of `f` is not definitionally equal to the carrier type of the set `s'` : `Set M` +-/ +#guard_msgs in +#check mfderiv[s'] f + +/-- +error: The domain `E` of `f` is not definitionally equal to the carrier type of the set `s'` : `Set M` +-/ +#guard_msgs in +#check mfderiv[s'] f m + +end errors + +section + +/-- +error: Term `X` is a dependent function, of type `(m : M) → TangentSpace I m` +Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one +-/ +#guard_msgs in +#check mfderiv% X x + +/-- +error: Term `σ` is a dependent function, of type `(x : M) → V x` +Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one +-/ +#guard_msgs in +#check mfderiv% σ x + +variable {t : Set E} {p : E} + +/-- +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` +Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one +-/ +#guard_msgs in +#check mfderiv[t] σ' p + +/-- +error: Term `σ'` is a dependent function, of type `(x : E) → Trivial E E' x` +Hint: you can use the `T%` elaborator to convert a dependent function to a non-dependent one +-/ +#guard_msgs in +#check mfderiv[t] σ' + +end + +end mfderiv From 4196b276e69f00f76b5f7a7206c751d429bf19c6 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 23 Oct 2025 23:33:58 +0200 Subject: [PATCH 397/601] Fix the build, again --- Mathlib/Geometry/Manifold/PartitionOfUnity.lean | 2 +- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index 98736bcc241719..1343524be021cd 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -608,7 +608,7 @@ theorem exists_contMDiffOn_section_forall_mem_convex_of_local -- Prove that `s`, when viewed as a map to the total space, is smooth. have (j : M) : ContMDiff I (I.prod 𝓘(ℝ, F_fiber)) n (fun x ↦ TotalSpace.mk' F_fiber x ((ρ j x) • (s_loc j x))) := by - refine ContMDiffOn.smul_section_of_tsupport ?_ isOpen_interior (hρU j) + refine .smul_section_of_tsupport ?_ isOpen_interior (hρU j) ((s_smooth j).mono interior_subset) exact ((ρ j).contMDiff).of_le (sup_eq_left.mp rfl) |>.contMDiffOn have hs : ContMDiff I (I.prod 𝓘(ℝ, F_fiber)) n (fun x ↦ TotalSpace.mk' F_fiber x (s x)) := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index f0ad2253d772ba..240b28c2940296 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -289,8 +289,8 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - apply ψ.contMDiff.contMDiffOn.smul_section_of_tsupport t.open_baseSet hψ.1 - apply contMDiffOn_localExtensionOn _ hx + exact .smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 + (contMDiffOn_localExtensionOn _ hx _) lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : From 2ca3197ccd4efc6bcb1ce27b1a8bb086211f0304 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 23 Oct 2025 23:41:49 +0200 Subject: [PATCH 398/601] Fix a few warnings --- .../Riemannian/ExistsRiemannianMetric.lean | 4 ++-- .../CovariantDerivative/LeviCivita.lean | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean index 4e04abb735a264..120a5bc85168a2 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean @@ -36,6 +36,7 @@ variable (E) in /-- This is the bundle `Hom_ℝ(E, T)`, where `T` is the rank one trivial bundle over `B`. -/ private def V : (b : B) → Type _ := (fun b ↦ E b →L[ℝ] Trivial B ℝ b) +-- TODO: all of these instances are really slow, investigate and fix this! noncomputable instance : (x : B) → TopologicalSpace (V E x) := by unfold V infer_instance @@ -135,8 +136,7 @@ lemma convex_condition1 (x : B) : Convex ℝ (condition1 E x) := by omit [TopologicalSpace B] in lemma convex_condition2 (x : B) : Convex ℝ (condition2 E x) := by unfold condition2 - intro φ hφ ψ hψ s t hs ht hst - intro v hv + intro φ hφ ψ hψ s t hs ht hst v hv rw [Set.mem_setOf] at hφ hψ have aux := Convex.min_le_combo ((φ v) v) ((ψ v) v) hs ht hst have : 0 < min ((φ v) v) ((ψ v) v) := lt_min (hφ v hv) (hψ v hv) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 65b931682ff524..ca8c875fd25494 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -504,7 +504,7 @@ lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} exact leviCivitaRhs_smulY_const_apply (hX x) (hY x) (hZ x) lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} - (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs' I X (f • Y) Z x = f x • leviCivitaRhs' I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by simp only [leviCivitaRhs'] @@ -546,7 +546,7 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} ring lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M → ℝ} - (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs I X (f • Y) Z x = f x • leviCivitaRhs I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] @@ -587,7 +587,7 @@ lemma leviCivitaRhs_addZ [CompleteSpace E] exact leviCivitaRhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} - (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs' I X Y (f • Z) x = f x • leviCivitaRhs' I X Y Z x := by simp only [leviCivitaRhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] @@ -765,7 +765,7 @@ variable (X Y) in /-- The definition `lcCandidate` behaves well: for each compatible trivialisation `e`, the candidate definition using `e` agrees with `lcCandidate` on `e.baseSet`. -/ lemma lcCandidate_eq_lcCandidateAux [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj: TangentBundle I M → M)) [MemTrivializationAtlas e] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} {x : M} (hx : x ∈ e.baseSet) : lcCandidate I M o X Y x = lcCandidateAux I e o X Y x := by by_cases hE : Subsingleton E @@ -1006,7 +1006,7 @@ A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fintype ι] (hf : IsCovariantDerivativeOn E f U) - {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) -- (hx : x ∈ U) + {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : IsTorsionFreeOn f U ↔ ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by @@ -1106,11 +1106,11 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x have : LocallyFiniteOrderBot ι := sorry have : ∑ k', inner ℝ (leviCivitaRhs I (s i) (s j) - (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') (s k x') = - ∑ k', inner ℝ ( - leviCivitaRhs I (s j) (s i) + ∑ k', inner ℝ + (leviCivitaRhs I (s j) (s i) (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') (s k x') := by From 90cee50b3de7338b355ad190c0aadc93d5edd98e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 23 Oct 2025 23:50:27 +0200 Subject: [PATCH 399/601] perf/chore: comment out ExistsRiemannianMetric for now That file is extremely slow; let's postpone that investigation and move forward with the remaining project first. --- .../Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean index 120a5bc85168a2..93f1e495a30f9d 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean @@ -30,6 +30,10 @@ variable [FiberBundle F E] [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] +-- This file is really slow, for reasons to be investigated, and not crucially required for +-- studying Ehresman or the Levi-Civita connections. Thus, let us not compile it for now. +#exit + section variable (E) in From cdfddf07cf377d6952d9e0b38ee62d19e5f5cbed Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 23 Oct 2025 23:55:57 +0200 Subject: [PATCH 400/601] chore: sync local frame changes from review And fix the remaining branch to compile with them. --- .../CovariantDerivative/Basic.lean | 8 +- .../CovariantDerivative/LeviCivita.lean | 32 +- .../CovariantDerivative/Torsion.lean | 32 +- .../Manifold/VectorBundle/LocalFrame.lean | 559 +++++++++--------- .../VectorBundle/OrthonormalFrame.lean | 18 +- .../Manifold/VectorBundle/Tensoriality.lean | 24 +- 6 files changed, 329 insertions(+), 344 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 240b28c2940296..81a14aa0d1b70e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -251,7 +251,7 @@ noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) -- and return ψ • V₀ instead. letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - ψ.toFun • localExtensionOn b t x v + ψ.toFun • localExtensionOn b t v variable {I F} @@ -1208,10 +1208,10 @@ lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I let e := trivializationAt E (TangentSpace I) x let Xi (i : Fin n) := b.localFrame e i -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. - let a := fun i ↦ b.localFrame_repr e i X + let a := fun i ↦ b.localFrame_coeff e i X have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_repr_spec this X - have (i : Fin n) : a i x = 0 := b.localFrame_repr_apply_zero_at hX i + have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_eventually_eq_sum_coeff_smul this X + have (i : Fin n) : a i x = 0 := b.localFrame_coeff_apply_zero_at hX i calc cov X σ x _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ca8c875fd25494..9ff485ba5d5e31 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -704,12 +704,12 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g let real := b.orthonormalFrame t have hframe := b.orthonormalFrame_isOrthonormalFrameOn t (F := E) (IB := I) (n := 1) - rw [hframe.eq_iff_repr hx] + rw [hframe.eq_iff_coeff hx] intro i - have h₁ : ⟪X, real i⟫ x = (hframe.repr i) X x := by + have h₁ : ⟪X, real i⟫ x = (hframe.coeff i) X x := by rw [hframe.repr_eq_inner' _ hx] simp [real, real_inner_comm] - have h₂ : ⟪X', real i⟫ x = (hframe.repr i) X' x := by + have h₂ : ⟪X', real i⟫ x = (hframe.coeff i) X' x := by rw [hframe.repr_eq_inner' _ hx] simp [real, real_inner_comm] rw [← h₁, ← h₂, h (real i)] @@ -820,10 +820,10 @@ lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ (Basis.ofVectorSpace ℝ E).orthonormalFrame_isOrthonormalFrameOn e have hZ' : ∑ i, ⟪σ, Z i⟫ x • Z i x = σ x := by calc _ - _ = ∑ i, hZ.repr i σ x • Z i x := by + _ = ∑ i, hZ.coeff i σ x • Z i x := by congr; ext i rw [hZ.repr_eq_inner' σ hx i, product_swap] - _ = σ x := (hZ.toIsLocalFrameOn.repr_sum_eq _ hx).symm + _ = σ x := (hZ.toIsLocalFrameOn.coeff_sum_eq _ hx).symm trans ∑ i, leviCivitaRhs I X (g • σ) (Z i) x • (Z i) x · congr have (i : (Basis.ofVectorSpaceIndex ℝ E)) : MDiffAt (T% (Z i)) x := @@ -903,7 +903,7 @@ noncomputable def ChristoffelSymbol (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) {U : Set M} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := - hs.repr k (f (s i) (s j)) + hs.coeff k (f (s i) (s j)) -- special case of `foobar` below; needed? lemma ChristoffelSymbol.sum_eq @@ -912,7 +912,7 @@ lemma ChristoffelSymbol.sum_eq (hs : IsLocalFrameOn I E n s U) (i j : ι) (hx : x ∈ U) : f (s i) (s j) x = ∑ k, (ChristoffelSymbol I f hs i j k x) • (s k) x := by simp only [ChristoffelSymbol] - exact hs.repr_sum_eq _ hx + exact hs.coeff_sum_eq _ hx variable {U : Set M} {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} @@ -935,15 +935,15 @@ lemma eq_product_apply [Fintype ι] lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E 1 s U) {x : M} (hx : x ∈ U) : f X Y x = ∑ k, - letI S₁ := ∑ i, ∑ j, (hs.repr i X) * (hs.repr j Y) * (ChristoffelSymbol I f hs i j k) + letI S₁ := ∑ i, ∑ j, (hs.coeff i X) * (hs.coeff j Y) * (ChristoffelSymbol I f hs i j k) letI S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! S₁ x • s k x := by - have hY := hs.repr_sum_eq Y hx + have hY := hs.coeff_sum_eq Y hx -- should this be a separate lemma also? - have : ∀ x ∈ U, Y x = ∑ i, (hs.repr i) Y x • s i x := by + have : ∀ x ∈ U, Y x = ∑ i, (hs.coeff i) Y x • s i x := by intro x hx - apply hs.repr_sum_eq Y hx - have : f X Y x = f X (fun x ↦ ∑ i, (hs.repr i) Y x • s i x) x := by + apply hs.coeff_sum_eq Y hx + have : f X Y x = f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by -- apply `congr_σ_of_eventuallyEq` from Basic.lean (after restoring it) -- want U to be a neighbourhood of x to make this work sorry @@ -965,7 +965,7 @@ lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] ∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x := by have (i j : ι) : ∀ x ∈ U, f (s i) (s j) x = g (s i) (s j) x := by intro x hx - rw [hs.eq_iff_repr hx] + rw [hs.eq_iff_coeff hx] exact fun k ↦ hfg i j k x hx intro X Y x hx -- use linearity (=formula for f in terms of Christoffel symbols) now, another separate lemma! @@ -978,7 +978,7 @@ lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ι] (hs : IsLocalFrameOn I E n s U) : (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x) ↔ ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x := - ⟨fun hfg _i _j _k _x hx ↦ hs.repr_congr (hfg _ _ _ hx ) .., + ⟨fun hfg _i _j _k _x hx ↦ hs.coeff_congr (hfg _ _ _ hx ) .., fun h X Y x hx ↦ hf.congr_of_christoffelSymbol_eq I hg hs h X Y x hx⟩ -- TODO: global version for convenience, with an alias for the interesting direction! @@ -1018,12 +1018,12 @@ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fin refine ⟨?_, ?_⟩ · intro h k x hx simp only [ChristoffelSymbol] - apply hs.repr_congr + apply hs.coeff_congr specialize h x hx rw [this i j hx, sub_eq_zero] at h exact h · intro h x hx - rw [this i j hx, sub_eq_zero, hs.eq_iff_repr hx] + rw [this i j hx, sub_eq_zero, hs.eq_iff_coeff hx] exact fun k ↦ h k x hx -- Exercise 4.2(b) in Lee, Chapter 4 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 5de5bc510ad785..20c2180bd419f3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -246,15 +246,15 @@ lemma aux1 {ι : Type*} [Fintype ι] {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.repr i) X x • torsion f (s i) Y x := + torsion f X Y x = ∑ i, (hs.coeff i) X x • torsion f (s i) Y x := have hU : U ∈ 𝓝 x := sorry - have aux := hs.repr_spec X hU - have hX : X x = ∑ i, (hs.repr i) X x • s i x := sorry + have aux := hs.eventually_eq_sum_coeff_smul X hU + have hX : X x = ∑ i, (hs.coeff i) X x • s i x := sorry calc torsion f X Y x - _ = torsion f (fun x ↦ ∑ i, (hs.repr i) X x • s i x) Y x := by + _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) X x • s i x) Y x := by sorry -- tensoriality and [hX] - _ = ∑ i, (torsion f (fun x ↦ (hs.repr i) X x • s i x) Y x) := sorry - _ = ∑ i, (hs.repr i) X x • (torsion f (s i) Y x) := sorry + _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) X x • s i x) Y x) := sorry + _ = ∑ i, (hs.coeff i) X x • (torsion f (s i) Y x) := sorry -- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x variable {n} in @@ -263,19 +263,19 @@ lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.repr i) Y x • torsion f X (s i) x := + torsion f X Y x = ∑ i, (hs.coeff i) Y x • torsion f X (s i) x := have hU : U ∈ 𝓝 x := sorry - have aux := hs.repr_spec Y hU - have hY : Y x = ∑ i, (hs.repr i) Y x • s i x := hs.repr_sum_eq Y hx + have aux := hs.eventually_eq_sum_coeff_smul Y hU + have hY : Y x = ∑ i, (hs.coeff i) Y x • s i x := hs.coeff_sum_eq Y hx calc torsion f X Y x - _ = torsion f X (fun x ↦ ∑ i, (hs.repr i) Y x • s i x) x := by + _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by sorry -- tensoriality and [hY] - _ = ∑ i, (torsion f X (fun x ↦ (hs.repr i) Y x • s i x) x) := sorry - _ = ∑ i, (hs.repr i) Y x • (torsion f X (s i) x) := by + _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) Y x • s i x) x) := sorry + _ = ∑ i, (hs.coeff i) Y x • (torsion f X (s i) x) := by congr with i - have hsi : MDiffAt (hs.repr i Y) x := sorry + have hsi : MDiffAt (hs.coeff i Y) x := sorry have hsi' : MDiffAt (T% (s i)) x := sorry - have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.repr i) Y) hx hsi hsi' + have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.coeff i) Y) hx hsi hsi' rw [← this] congr @@ -291,10 +291,10 @@ lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame intro x hx X Y rw [aux1 hs hx] calc - _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • torsion f (s i) (s j) x := by + _ = ∑ i, (hs.coeff i) X x • ∑ j, (hs.coeff j) Y x • torsion f (s i) (s j) x := by congr! rw [aux2 hf hs hx] - _ = ∑ i, (hs.repr i) X x • ∑ j, (hs.repr j) Y x • 0 := by + _ = ∑ i, (hs.coeff i) X x • ∑ j, (hs.coeff j) Y x • 0 := by congr! with i _ j _ exact h i j x hx _ = 0 := by simp diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 7405aabd845e99..5112366346d543 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -8,57 +8,112 @@ import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection + /-! # Local frames in a vector bundle Let `V → M` be a finite rank smooth vector bundle with standard fiber `F`. -Given a basis `b` for `F` and a local trivialisation `e` for `V`, -we construct a **smooth local frame** on `V` w.r.t. `e` and `b`, -i.e. a collection of sections `sᵢ` of `V` which is smooth on `e.baseSet` such that `{sᵢ x}` is a -basis of `V x` for each `x ∈ e.baseSet`. Any section `s` of `e` can be uniquely written as -`s = ∑ i, f^i sᵢ` near `x`, and `s` is smooth at `x` iff the functions `f^i` are. - -The latter statement holds in many cases, but not for every vector bundle. In this file, we prove -it for local frames induced by a trivialisation, for finite rank bundles over a complete field. -In `OrthonormalFrame.lean`, we prove the same for real vector bundles of any rank which admit -a `C^n` bundle metric. This includes bundles of finite rank, modelled on a Hilbert space or -on a Banach space which has smooth partitions of unity. - -We use this to construct local extensions of a vector to a section which is smooth on the -trivialisation domain. +A family of sections `s i` of `V → M` is called a **C^k local frame** on a set `U ⊆ M` iff each +section `s i` is `C^k` on `U`, and the section values `s i x` form a basis for each `x ∈ U`. +We define a predicate `IsLocalFrame` for a collection of sections to be a local frame on a set, +and define basic notions (such as the coefficients of a section w.r.t. a local frame, and +checking the smoothness of `t` via its coefficients in a local frame). + +Given a basis `b` for `F` and a local trivialisation `e` for `V`, we construct a +**smooth local frame** on `V` w.r.t. `e` and `b`, i.e. a collection of sections `sᵢ` of `V` +which is smooth on `e.baseSet` such that `{sᵢ x}` is a basis of `V x` for each `x ∈ e.baseSet`. +Any section `s` of `e` can be uniquely written as `s = ∑ i, f^i sᵢ` near `x`, +and `s` is smooth at `x` iff the functions `f^i` are. + +In this file, we prove the latter statement for finite-rank bundles (with coefficients in a +complete field). In `OrthonormalFrame.lean`, we will prove the same for real vector bundles of any +rank which admit a `C^n` bundle metric. This includes bundles of finite rank, modelled on a Hilbert +space or on a Banach space which has smooth partitions of unity. + +We also use this to extend a vector in a single fiber `V x` to a section near `x` which is +smooth on the trivialisation domain. ## Main definitions and results -TODO: this doc-string is outdated, needs to be augmented for the recent refactoring! +* `IsLocalFrameOn`: a family of sections `s i` of `V → M` is called a **C^k local frame** on a set + `U ⊆ M` iff each section `s i` is `C^k` on `U`, and the section values `s i x` form a basis for + each `x ∈ U` + +Suppose `{sᵢ}` is a local frame on `U`, and `hs : IsLocalFrameOn s U`. +* `IsLocalFrameOn.toBasisAt hs`: for each `x ∈ U`, the vectors `sᵢ x` form a basis of `F` +* `IsLocalFrameOn.coeff hs` describes the coefficient of sections of `V` w.r.t. `{sᵢ}`. + `hs.coeff i` is a linear map from sections of `V` to functions `M → 𝕜`. +* `IsLocalFrameOn.eventually_eq_sum_coeff_smul hs`: for a local frame `{sᵢ}` near `x`, + for each section `t` we have `t = ∑ i, (hs.coeff i t) • sᵢ`. +* `IsLocalFrameOn.coeff_sum_eq hs t hx` proves that `t x = ∑ i, (hs.coeff i t) x • sᵢ x`, provided + that `hx : x ∈ U`. +* `IsLocalFrameOn.coeff_congr hs`: the coefficient `hs.coeff i` of `t` in the local frame `{sᵢ}` + only depends on `t` at `x`. +* `IsLocalFrameOn.eq_iff_coeff hs`: two sections `t` and `t'` are equal at `x` if and only if their + coefficients at `x` w.r.t. `{sᵢ}` agree. +* `IsLocalFrameOn.contMDiffOn_of_coeff hs`: a section `t` is `C^k` on `U` if each coefficient + `hs.coeff i t` is `C^k` on `U` +* `IsLocalFrameOn.contMDiffAt_of_coeff hs`: a section `t` is `C^k` at `x ∈ U` + if all of its frame coefficients are +* `IsLocalFrameOn.contMDiffOn_off_coeff hs`: a section `t` is `C^k` on an open set `t ⊆ U` + ff all of its frame coefficients are +* `MDifferentiable` versions of the previous three statements + +Given a basis of the standard fibre `F` of `V`, a compatible trivialisation of `V` near `x` +induces a local frame for `V` on `e.baseSet`: * `Basis.localFrame e b`: the local frame on `V` w.r.t. a local trivialisation `e` of `V` and a basis `b` of `F`. Use `b.localFrame e i` to access the i-th section in that frame. * `b.contMDiffOn_localFrame_baseSet`: each section `b.localFrame e i` is smooth on `e.baseSet` * `b.localFrame_toBasis_at e`: for each `x ∈ e.baseSet`, the vectors `b.localFrame e i x` form a basis of `F` -* `Basis.localFrame_repr e b i` describes the coefficient of sections of `V` w.r.t.`b.localFrame e`: - `b.localFrame e i` is a linear map from sections of `V` to functions `M → 𝕜`. -* `b.localFrame_repr_spec e`: near `x`, we have - `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` -* `b.localFrame_repr_congr e`: the coefficient `b.localFrame_repr e b i` of `s` in the local frame +* `Basis.localFrame_coeff e b i` describes the coefficient of sections of `V` w.r.t. + `b.localFrame e`: `b.localFrame e i` is a linear map from sections of `V` to functions `M → 𝕜`. +* `b.localFrame_eventually_eq_sum_coeff_smul e`: near `x`, we have + `s = ∑ i, (b.localFrame_coeff e i s) • b.localFrame e i` +* `b.localFrame_coeff_congr e`: the coefficient `b.localFrame_coeff e b i` of `s` in the local frame induced by `e` and `b` at `x` only depends on `s` at `x`. -* `b.contMDiffOn_localFrame_repr`: if `s` is a `C^k` section, each coefficient - `b.localFrame_repr e i s` is `C^k` on `e.baseSet` -* `b.contMDiffAt_iff_localFrame_repr e`: a section `s` is `C^k` at `x ∈ e.baseSet` +* `b.contMDiffOn_localFrame_coeff`: if `s` is a `C^k` section, each coefficient + `b.localFrame_coeff e i s` is `C^k` on `e.baseSet` +* `b.contMDiffAt_iff_localFrame_coeff e`: a section `s` is `C^k` at `x ∈ e.baseSet` iff all of its frame coefficients are -* `b.contMDiffOn_iff_localFrame_repr e`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` +* `b.contMDiffOn_iff_localFrame_coeff e`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` iff all of its frame coefficients are -* TODO: mention all the localExtensionOn definitions and results - -TODO add a more complete doc-string! +A local frame can be used to extend any single vector `v : V x` to a section which is smooth near +`x`, such that the construction is linear in `v`. +* `localExtensionOn b e v`: given a basis `b` and a compatible trivialisation `e` of `V` near `x`, + extend the vector `v : V x` to a section of `V` which is smooth on `e.baseSet` +* `localExtensionOn_apply_self`: `localExtensionOn b e v x = v`, i.e. we really extend `v` at `x` +* `contMDiffOn_localExtensionOn`: `localExtensionOn b e v` is `C^n` on `e.baseSet` +* `localExtensionOn_localFrame_coeff`: `localExtensionOn` has constant frame coefficients + (knowing this is sometimes useful when working with local extensions for covariant derivatives) +* `localExtensionOn_add`, `localExtensionOn_zero` and `localExtensionOn_smul` prove that + `v ↦ localExtensionON b e v` is a linear map. + + +# TODO +* `IsLocalFrameOn.contMDiffOn_coeff hs`: if `t` is a `C^k` section, each coefficient + `hs.coeff i t` is `C^k` on `U` +* `IsLocalFrameOn.contMDiffAt_iff_coeff hs`: a section `t` is `C^k` at `x ∈ U` + iff all of its frame coefficients are +* `IsLocalFrameOn.contMDiffOn_iff_coeff hs`: a section `t` is `C^k` on an open set `t ⊆ U` + iff all of its frame coefficients are +* a `MDifferentiable` version of each of these ## Implementation notes -* local frames use the junk value pattern: they are defined on all of `M`, but their value is - only meaningful inside `e.baseSet` -* something about local extensions (and different fields) + +Local frames use the junk value pattern: they are defined on all of `M`, but their value is +only meaningful on the set on which they are a local frame. + +Note that `localExtensionOn` need not be smooth globally; in turn, this definition makes sense over +any field. In contrast, an extension to a global holomorphic vector field is more delicate for +complex vector bundles (whereas *locally* holomorphic sections always exist). +For real bundles, global extensions always exist and can be constructed by scalar multiplication +of a local extension with a smooth bump function of sufficiently small support. + ## Tags -vector bundle, local frame, smoothness +vector bundle, local frame, smoothness, local extension of section -/ open Bundle Filter Function Topology Module @@ -76,8 +131,6 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] - -- not needed in this file - -- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] -- `V` vector bundle @@ -90,7 +143,7 @@ omit [IsManifold I 0 M] [VectorBundle 𝕜 F V] variable {ι : Type*} {s s' : ι → (x : M) → V x} {u u' : Set M} {x : M} {n : WithTop ℕ∞} variable (I F n) in -/- +/-- A family of sections `s i` of `V → M` is called a **C^k local frame** on a set `U ⊆ M` iff - the section values `s i x` form a basis for each `x ∈ U`, - each section `s i` is `C^k` on `U`. @@ -113,7 +166,7 @@ lemma congr (hs : IsLocalFrameOn I F n s u) (hs' : ∀ i, ∀ x, x ∈ u → s i intro x hx have := hs.generating hx simp_all - contMDiffOn i := (hs.contMDiffOn i).congr fun y hy ↦ by simp [hs' i y hy] + contMDiffOn i := (hs.contMDiffOn i).congr (by simp +contextual [hs']) lemma mono (hs : IsLocalFrameOn I F n s u) (hu'u : u' ⊆ u) : IsLocalFrameOn I F n s u' where linearIndependent := by @@ -134,15 +187,13 @@ def toBasisAt (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) : Basis ι 𝕜 (V @[simp] lemma toBasisAt_coe (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) (i : ι) : - (toBasisAt hs hx) i = s i x := by + toBasisAt hs hx i = s i x := by simpa only [toBasisAt] using Basis.mk_apply (hs.linearIndependent hx) (hs.generating hx) i open scoped Classical in /-- Coefficients of a section `s` of `V` w.r.t. a local frame `{s i}` on `u`. Outside of `u`, this returns the junk value 0. -/ --- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate --- cases. -def repr (hs : IsLocalFrameOn I F n s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where +def coeff (hs : IsLocalFrameOn I F n s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 where toFun s x := if hx : x ∈ u then (hs.toBasisAt hx).repr (s x) i else 0 map_add' s s' := by ext x @@ -154,86 +205,86 @@ def repr (hs : IsLocalFrameOn I F n s u) (i : ι) : (Π x : M, V x) →ₗ[𝕜] variable {x : M} @[simp] -lemma repr_apply_of_notMem (hs : IsLocalFrameOn I F n s u) (hx : x ∉ u) (t : Π x : M, V x) (i : ι) : - hs.repr i t x = 0 := by - simp [repr, hx] +lemma coeff_apply_of_notMem (hs : IsLocalFrameOn I F n s u) (hx : x ∉ u) (t : Π x : M, V x) + (i : ι) : hs.coeff i t x = 0 := by + simp [coeff, hx] @[simp] -lemma repr_apply_of_mem (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) (t : Π x : M, V x) (i : ι) : - hs.repr i t x = (hs.toBasisAt hx).repr (t x) i := by - simp [repr, hx] +lemma coeff_apply_of_mem (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) (t : Π x : M, V x) (i : ι) : + hs.coeff i t x = (hs.toBasisAt hx).repr (t x) i := by + simp [coeff, hx] -- TODO: add uniqueness of the decomposition; follows from the IsBasis property in the definition -lemma repr_sum_eq [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hx : x ∈ u) : - t x = (∑ i, (hs.repr i t x) • (s i x)) := by - simpa [repr, hx] using (Basis.sum_repr (hs.toBasisAt hx) (t x)).symm +lemma coeff_sum_eq [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hx : x ∈ u) : + t x = ∑ i, (hs.coeff i t x) • (s i x) := by + simpa [coeff, hx] using (Basis.sum_repr (hs.toBasisAt hx) (t x)).symm /-- A local frame locally spans the space of sections for `V`: for each local frame `s i` on an open -set `u` around `x`, we have `t = ∑ i, (hs.repr i t) • (s i x)` near `x`. -/ -lemma repr_spec [Fintype ι] (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hu'' : u ∈ 𝓝 x) : - ∀ᶠ x' in 𝓝 x, t x' = ∑ i, (hs.repr i t x') • (s i x') := - eventually_of_mem hu'' fun _ hx ↦ hs.repr_sum_eq _ hx +set `u` around `x`, we have `t = ∑ i, (hs.coeff i t) • (s i x)` near `x`. -/ +lemma eventually_eq_sum_coeff_smul [Fintype ι] + (hs : IsLocalFrameOn I F n s u) (t : Π x : M, V x) (hu'' : u ∈ 𝓝 x) : + ∀ᶠ x' in 𝓝 x, t x' = ∑ i, (hs.coeff i t x') • (s i x') := + eventually_of_mem hu'' fun _ hx ↦ hs.coeff_sum_eq _ hx -/-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma repr_congr (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} - (htt' : t x = t' x) (i : ι) : - hs.repr i t x = hs.repr i t' x := by +variable {t t' : Π x : M, V x} + +/-- The coefficients of `t` in a local frame at `x` only depend on `t` at `x`. -/ +lemma coeff_congr (hs : IsLocalFrameOn I F n s u) (htt' : t x = t' x) (i : ι) : + hs.coeff i t x = hs.coeff i t' x := by by_cases hxe : x ∈ u - · simp [repr, hxe] + · simp [coeff, hxe] congr - · simp [repr, hxe] + · simp [coeff, hxe] /-- If `s` and `s'` are local frames which are equal at `x`, a section `t` has equal frame coefficients in them. -/ -lemma repr_eq_of_eq (hs : IsLocalFrameOn I F n s u) (hs' : IsLocalFrameOn I F n s' u) {x} +lemma coeff_eq_of_eq (hs : IsLocalFrameOn I F n s u) (hs' : IsLocalFrameOn I F n s' u) (hss' : ∀ i, s i x = s' i x) {t : Π x : M, V x} (i : ι) : - hs.repr i t x = hs'.repr i t x := by + hs.coeff i t x = hs'.coeff i t x := by by_cases hxe : x ∈ u - · simp [repr, hxe] + · simp [coeff, hxe] simp_all [toBasisAt] - · simp [repr, hxe] + · simp [coeff, hxe] /-- Two sections `s` and `t` are equal at `x` if and only if their coefficients w.r.t. some local frame at `x` agree. -/ -lemma eq_iff_repr [Fintype ι] (hs : IsLocalFrameOn I F n s u) {t t' : Π x : M, V x} (hx : x ∈ u) : - t x = t' x ↔ ∀ i, hs.repr i t x = hs.repr i t' x := - ⟨fun h i ↦ hs.repr_congr h i, fun h ↦ by - simp +contextual [h, hs.repr_sum_eq t hx, hs.repr_sum_eq t' hx]⟩ +lemma eq_iff_coeff [Fintype ι] (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) : + t x = t' x ↔ ∀ i, hs.coeff i t x = hs.coeff i t' x := + ⟨fun h i ↦ hs.coeff_congr h i, fun h ↦ by + simp +contextual [h, hs.coeff_sum_eq t hx, hs.coeff_sum_eq t' hx]⟩ -lemma repr_apply_zero_at (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} (ht : t x = 0) (i : ι) : - hs.repr i t x = 0 := by - simp [hs.repr_congr (t' := 0) ht] +lemma coeff_apply_zero_at (hs : IsLocalFrameOn I F n s u) (ht : t x = 0) (i : ι) : + hs.coeff i t x = 0 := by + simp [hs.coeff_congr (t' := 0) ht] -variable (hs : IsLocalFrameOn I F n s u) {t : Π x : M, V x} [VectorBundle 𝕜 F V] +variable (hs : IsLocalFrameOn I F n s u) [VectorBundle 𝕜 F V] /-- Given a local frame `s i ` on `u`, if a section `t` has `C^k` coefficients on `u` w.r.t. `s i`, then `t` is `C^n` on `u`. -/ -lemma contMDiffOn_of_repr [Fintype ι] (h : ∀ i, CMDiff[u] n (hs.repr i t)) : +lemma contMDiffOn_of_coeff [Fintype ι] (h : ∀ i, CMDiff[u] n (hs.coeff i t)) : CMDiff[u] n (T% t) := by - have this (i) : CMDiff[u] n (T% (hs.repr i t • s i)) := + have this (i) : CMDiff[u] n (T% (hs.coeff i t • s i)) := (h i).smul_section (hs.contMDiffOn i) - have almost : CMDiff[u] n (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) := + have almost : CMDiff[u] n (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) := .sum_section fun i _ ↦ this i apply almost.congr intro y hy - simp [hs.repr_sum_eq t hy] + simp [hs.coeff_sum_eq t hy] /-- Given a local frame `s i` on a neighbourhood `u` of `x`, if a section `t` has `C^k` coefficients at `x` w.r.t. `s i`, then `t` is `C^n` at `x`. -/ -lemma contMDiffAt_of_repr [Fintype ι] - (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x := by - have this (i) : CMDiffAt n (T% (hs.repr i t • s i)) x := - (h i).smul_section <| (hs.contMDiffOn i).contMDiffAt hu - have almost : CMDiffAt n - (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := .sum_section (fun i _ ↦ this i) - exact almost.congr_of_eventuallyEq <| (hs.repr_spec t hu).mono fun x h ↦ by simp [h] +lemma contMDiffAt_of_coeff [Fintype ι] + (h : ∀ i, CMDiffAt n (hs.coeff i t) x) (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x := by + have almost : CMDiffAt n (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) x := + .sum_section (fun i _ ↦ (h i).smul_section <| (hs.contMDiffOn i).contMDiffAt hu) + exact almost.congr_of_eventuallyEq <| (hs.eventually_eq_sum_coeff_smul t hu).mono (by simp) /-- Given a local frame `s i` on an open set `u` containing `x`, if a section `t` has `C^k` coefficients at `x ∈ u` w.r.t. `s i`, then `t` is `C^n` at `x`. -/ -lemma contMDiffAt_of_repr_aux [Fintype ι] - (h : ∀ i, CMDiffAt n (hs.repr i t) x) (hu : IsOpen u) (hx : x ∈ u) : CMDiffAt n (T% t) x := - hs.contMDiffAt_of_repr h (hu.mem_nhds hx) +lemma contMDiffAt_of_coeff_aux [Fintype ι] (h : ∀ i, CMDiffAt n (hs.coeff i t) x) + (hu : IsOpen u) (hx : x ∈ u) : CMDiffAt n (T% t) x := + hs.contMDiffAt_of_coeff h (hu.mem_nhds hx) section @@ -241,72 +292,45 @@ variable (hs : IsLocalFrameOn I F 1 s u) /-- Given a local frame `s i ` on `u`, if a section `t` has differentiable coefficients on `u` w.r.t. `s i`, then `t` is differentiable on `u`. -/ -lemma mdifferentiableOn_of_repr [Fintype ι] (h : ∀ i, MDiff[u] (hs.repr i t)) : +lemma mdifferentiableOn_of_coeff [Fintype ι] (h : ∀ i, MDiff[u] (hs.coeff i t)) : MDiff[u] (T% t) := by - have this (i) : MDiff[u] (T% (hs.repr i t • s i)) := + have this (i) : MDiff[u] (T% (hs.coeff i t • s i)) := (h i).smul_section ((hs.contMDiffOn i).mdifferentiableOn le_rfl) - have almost : MDiff[u] (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) := + have almost : MDiff[u] (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) := .sum_section (fun i _ hx ↦ this i _ hx) apply almost.congr intro y hy - simp [hs.repr_sum_eq t hy] + simp [hs.coeff_sum_eq t hy] /-- Given a local frame `s i` on a neighbourhood `u` of `x`, if a section `t` has differentiable coefficients at `x` w.r.t. `s i`, then `t` is differentiable at `x`. -/ -lemma mdifferentiableAt_of_repr [Fintype ι] - (h : ∀ i, MDiffAt (hs.repr i t) x) (hu : u ∈ 𝓝 x) : MDiffAt (T% t) x := by - have this (i) : MDiffAt (T% (hs.repr i t • s i)) x := - (h i).smul_section <| ((hs.contMDiffOn i).mdifferentiableOn le_rfl).mdifferentiableAt hu - have almost : MDiffAt - (T% (fun x ↦ ∑ i, (hs.repr i t) x • s i x)) x := .sum_section (fun i ↦ this i) - exact almost.congr_of_eventuallyEq <| (hs.repr_spec t hu).mono fun x h ↦ by simp [h] +lemma mdifferentiableAt_of_coeff [Fintype ι] + (h : ∀ i, MDiffAt (hs.coeff i t) x) (hu : u ∈ 𝓝 x) : MDiffAt (T% t) x := by + have almost : MDiffAt (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) x := + .sum_section (fun i ↦ (h i).smul_section <| + ((hs.contMDiffOn i).mdifferentiableOn le_rfl).mdifferentiableAt hu) + exact almost.congr_of_eventuallyEq <| (hs.eventually_eq_sum_coeff_smul t hu).mono (by simp) /-- Given a local frame `s i` on open set `u` containing `x`, if a section `t` has differentiable coefficients at `x ∈ u` w.r.t. `s i`, then `t` is differentiable at `x`. -/ -lemma mdifferentiableAt_of_repr_aux [Fintype ι] - (h : ∀ i, MDiffAt (hs.repr i t) x) (hu : IsOpen u) (hx : x ∈ u) : MDiffAt (T% t) x := - hs.mdifferentiableAt_of_repr h (hu.mem_nhds hx) +lemma mdifferentiableAt_of_coeff_aux [Fintype ι] (h : ∀ i, MDiffAt (hs.coeff i t) x) + (hu : IsOpen u) (hx : x ∈ u) : MDiffAt (T% t) x := + hs.mdifferentiableAt_of_coeff h (hu.mem_nhds hx) end -set_option linter.style.commandStart true - -section pullback - -variable {E' : Type*} [NormedAddCommGroup E'] - [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] -- [IsManifold I 0 M] - -- [ContMDiffVectorBundle n F V I] - --- Note: there is some mathematical content to the sorry. The `have` statement is --- about maps to the total space of the original bundle and we want to look at --- the same map seen as a map into the total space of the pullback bundle. -lemma pullback (hs : IsLocalFrameOn I F n s u) (f : ContMDiffMap I' I M' M n) : - letI (x : M') : AddCommGroup ((f *ᵖ V) x) := inferInstanceAs (AddCommGroup <| V (f x)) - letI (x : M') : Module 𝕜 ((f *ᵖ V) x) := inferInstanceAs (Module 𝕜 <| V (f x)) - IsLocalFrameOn I' F n (V := f *ᵖ V) (fun i x' ↦ s i (f x')) (f ⁻¹' u) := - letI (x : M') : AddCommGroup ((f *ᵖ V) x) := inferInstanceAs (AddCommGroup <| V (f x)) - letI (x : M') : Module 𝕜 ((f *ᵖ V) x) := inferInstanceAs (Module 𝕜 <| V (f x)) - { linearIndependent hx := hs.linearIndependent hx, - generating hx := hs.generating hx, - contMDiffOn (i : ι) := by - have := (hs.contMDiffOn i).comp (s := f ⁻¹' u) f.contMDiff.contMDiffOn subset_rfl - sorry - } -end pullback - end IsLocalFrameOn end IsLocalFrame namespace Module.Basis -variable {ι : Type*} +variable {ι : Type*} {x : M} noncomputable def localFrame_toBasis_at (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) {x : M} (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := + (b : Basis ι 𝕜 F) (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := b.map (e.linearEquivAt (R := 𝕜) x hx).symm open scoped Classical in @@ -353,53 +377,41 @@ lemma localFrame_isLocalFrameOn_baseSet omit [IsManifold I 0 M] in lemma _root_.contMDiffAt_localFrame_of_mem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) {x : M} (hx : x ∈ e.baseSet) : + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) (hx : x ∈ e.baseSet) : CMDiffAt n (T% (b.localFrame e i)) x := (b.localFrame_isLocalFrameOn_baseSet I n e).contMDiffAt e.open_baseSet hx _ @[simp] lemma localFrame_apply_of_mem_baseSet (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∈ e.baseSet) : + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} (hx : x ∈ e.baseSet) : b.localFrame e i x = b.localFrame_toBasis_at e hx i := by simp [localFrame, hx] @[simp] lemma localFrame_apply_of_notMem (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} {x : M} (hx : x ∉ e.baseSet) : + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) {i : ι} (hx : x ∉ e.baseSet) : b.localFrame e i x = 0 := by simp [localFrame, hx] lemma localFrame_toBasis_at_coe (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [MemTrivializationAtlas e] - (b : Basis ι 𝕜 F) {x : M} (i : ι) (hx : x ∈ e.baseSet) : + [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) (hx : x ∈ e.baseSet) : b.localFrame_toBasis_at e hx i = b.localFrame e i x := by simp [hx] --- -- XXX: is this result actually needed now? perhaps not, because of the toBasis definition? --- /-- At each point `x ∈ M`, the sections `{sⁱ(x)}` of a local frame form a basis for `V x`. -/ --- def isBasis_localFrame --- (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) --- [MemTrivializationAtlas e] --- (b : Basis ι 𝕜 F) : sorry := by --- -- the b i form a basis of F, --- -- and the trivialisation e is a linear equivalence (thus preserves bases) --- sorry - variable [ContMDiffVectorBundle 1 F V I] open scoped Classical in variable (I) in -/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i` -/ --- If x is outside of `e.baseSet`, this returns the junk value 0. --- NB. We don't use simps here, as we prefer to have dedicated `_apply` lemmas for the separate --- cases. -noncomputable def localFrame_repr +/-- Coefficients of a section `s` of `V` w.r.t. the local frame `b.localFrame e i`. + +If x is outside of `e.baseSet`, this returns the junk value 0. -/ +noncomputable def localFrame_coeff (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : (Π x : M, V x) →ₗ[𝕜] M → 𝕜 := - (b.localFrame_isLocalFrameOn_baseSet I 1 e).repr i + (b.localFrame_isLocalFrameOn_baseSet I 1 e).coeff i variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} @@ -407,51 +419,52 @@ variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V omit [IsManifold I 0 M] in variable (e b) in @[simp] -lemma localFrame_repr_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : - b.localFrame_repr I e i s x = 0 := by - simpa [localFrame_repr] using - (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_apply_of_notMem hx s i +lemma localFrame_coeff_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : + b.localFrame_coeff I e i s x = 0 := by + simpa [localFrame_coeff] using + (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_apply_of_notMem hx s i omit [IsManifold I 0 M] in variable (e b) in @[simp] -lemma localFrame_repr_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : - b.localFrame_repr I e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by +lemma localFrame_coeff_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : + b.localFrame_coeff I e i s x = (b.localFrame_toBasis_at e hx).repr (s x) i := by have ilf := b.localFrame_isLocalFrameOn_baseSet I 1 e rw [show localFrame_toBasis_at e b hx = ilf.toBasisAt hx by ext j; simp [localFrame, hx]] - exact ilf.repr_apply_of_mem hx s i + exact ilf.coeff_apply_of_mem hx s i -- XXX better variable name! -- TODO: better name? omit [IsManifold I 0 M] in -lemma localFrame_repr_sum_eq [Fintype ι] (s : Π x : M, V x) {x'} (hx : x' ∈ e.baseSet) : - s x' = (∑ i, (b.localFrame_repr I e i s x') • b.localFrame e i x') := by - simp only [localFrame_repr] - exact (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_sum_eq s hx +lemma localFrame_coeff_sum_eq [Fintype ι] (s : Π x : M, V x) {x'} (hx : x' ∈ e.baseSet) : + s x' = (∑ i, (b.localFrame_coeff I e i s x') • b.localFrame e i x') := by + simp only [localFrame_coeff] + exact (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_sum_eq s hx variable (b) in omit [IsManifold I 0 M] in /-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` - of `V` around `x`, we have `s = ∑ i, (b.localFrame_repr e i s) • b.localFrame e i` -/ -lemma localFrame_repr_spec [Fintype ι] {x : M} (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : - ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_repr I e i s x') • b.localFrame e i x' := - eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_repr_sum_eq s h, e.open_baseSet, hxe⟩ + of `V` around `x`, we have `s = ∑ i, (b.localFrame_coeff e i s) • b.localFrame e i` -/ +lemma localFrame_eventually_eq_sum_coeff_smul [Fintype ι] + (hxe : x ∈ e.baseSet) (s : Π x : M, V x) : + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_coeff I e i s x') • b.localFrame e i x' := + eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_coeff_sum_eq s h, e.open_baseSet, hxe⟩ omit [IsManifold I 0 M] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ -lemma localFrame_repr_congr (b : Basis ι 𝕜 F) +lemma localFrame_coeff_congr (b : Basis ι 𝕜 F) {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : - b.localFrame_repr I e i s x = b.localFrame_repr I e i s' x := by + b.localFrame_coeff I e i s x = b.localFrame_coeff I e i s' x := by by_cases hxe : x ∈ e.baseSet - · simp [localFrame_repr, hxe] + · simp [localFrame_coeff, hxe] congr - · simp [localFrame_repr, hxe] + · simp [localFrame_coeff, hxe] omit [IsManifold I 0 M] in -lemma localFrame_repr_apply_zero_at +lemma localFrame_coeff_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : - b.localFrame_repr I e i s x = 0 := by - simp only [localFrame_repr] - exact (localFrame_isLocalFrameOn_baseSet I 1 e b).repr_apply_zero_at hs i + b.localFrame_coeff I e i s x = 0 := by + simp only [localFrame_coeff] + exact (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_apply_zero_at hs i variable {n} @@ -459,10 +472,10 @@ omit [IsManifold I 0 M] in /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ -lemma localFrame_repr_eq_repr (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : - b.localFrame_repr I e i s x = b.repr (e (s x)).2 i := by - --simp only [localFrame_repr] - simp [b.localFrame_repr_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] +lemma localFrame_coeff_eq_coeff (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {i : ι} {s : Π x : M, V x} : + b.localFrame_coeff I e i s x = b.repr (e (s x)).2 i := by + --simp only [localFrame_coeff] + simp [b.localFrame_coeff_apply_of_mem_baseSet e hxe, Basis.localFrame_toBasis_at] end Module.Basis @@ -477,14 +490,15 @@ variable {ι : Type*} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.Tot [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} [ContMDiffVectorBundle 1 F V I] +-- TODO: can this be proven more generally, for any local frame? omit [IsManifold I 0 M] in -/-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame +/-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame near `x` induced by `e` and `b` -/ -lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma contMDiffAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] (hs : CMDiffAt k (T% s) x) (i : ι) : - CMDiffAt k (b.localFrame_repr I e i s) x := by + CMDiffAt k (b.localFrame_coeff I e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical -- step 1: on e.baseSet, can compute the coefficient very well @@ -494,7 +508,7 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 apply this.congr_of_eventuallyEq ?_ apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, Basis.localFrame_repr_eq_repr hy] + simp [aux, Basis.localFrame_coeff_eq_coeff hy] simp only [aux] -- step 2: `s` read in trivialization `e` is `C^k` @@ -515,70 +529,70 @@ lemma contMDiffAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜 exact hbas.comp x h₁ omit [IsManifold I 0 M] in -/-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` +/-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ -lemma contMDiffOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) +lemma contMDiffOn_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} {t : Set M} [ContMDiffVectorBundle k F V I] (ht : IsOpen t) (ht' : t ⊆ e.baseSet) - (hs : CMDiff[t] k (T% s)) (i : ι) : CMDiff[t] k (b.localFrame_repr I e i s) := - fun _ hx ↦ (contMDiffAt_localFrame_repr (ht' hx) b + (hs : CMDiff[t] k (T% s)) (i : ι) : CMDiff[t] k (b.localFrame_coeff I e i s) := + fun _ hx ↦ (contMDiffAt_localFrame_coeff (ht' hx) b (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -omit [IsManifold I 0 M] in -- [ContMDiffVectorBundle n F V I] in -/-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the local frame -induced by `e` -/ -lemma contMDiffOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +omit [IsManifold I 0 M] in +/-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_coeff e i` +in the local frame induced by `e` -/ +lemma contMDiffOn_baseSet_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] - (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : CMDiff[e.baseSet] k (b.localFrame_repr I e i s) := - contMDiffOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ + (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : CMDiff[e.baseSet] k (b.localFrame_coeff I e i s) := + contMDiffOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` at `x ∈ e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma contMDiffAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ +lemma contMDiffAt_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {x' : M} (hx : x' ∈ e.baseSet) : - CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_repr I e i s) x' := - ⟨fun h i ↦ contMDiffAt_localFrame_repr hx b h i, - fun hi ↦ (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_repr hi + CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_coeff I e i s) x' := + ⟨fun h i ↦ contMDiffAt_localFrame_coeff hx b h i, + fun hi ↦ (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_coeff hi (e.open_baseSet.mem_nhds hx)⟩ omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma contMDiffOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ +lemma contMDiffOn_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_repr I e i s) := by - refine ⟨fun h i ↦ contMDiffOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ + CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_coeff I e i s) := by + refine ⟨fun h i ↦ contMDiffOn_localFrame_coeff b ht ht' h i, fun hi ↦ ?_⟩ -- TODO: golf this using the lemmas above -- intro x hx - -- let aux := (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_repr (t := s) (x := x) - have this (i) : CMDiff[t] k (T% ((b.localFrame_repr I e i) s • b.localFrame e i)) := + -- let aux := (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_coeff (t := s) (x := x) + have this (i) : CMDiff[t] k (T% ((b.localFrame_coeff I e i) s • b.localFrame e i)) := (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') - let rhs := fun x' ↦ ∑ i, (b.localFrame_repr I e i) s x' • b.localFrame e i x' + let rhs := fun x' ↦ ∑ i, (b.localFrame_coeff I e i) s x' • b.localFrame e i x' have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i apply almost.congr intro y hy - simpa using b.localFrame_repr_sum_eq s (ht' hy) + simpa using b.localFrame_coeff_sum_eq s (ht' hy) omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma contMDiffOn_baseSet_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ +lemma contMDiffOn_baseSet_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] : - CMDiff[e.baseSet] k (T% s) ↔ ∀ i, CMDiff[e.baseSet] k (b.localFrame_repr I e i s) := by - rw [contMDiffOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] + CMDiff[e.baseSet] k (T% s) ↔ ∀ i, CMDiff[e.baseSet] k (b.localFrame_coeff I e i s) := by + rw [contMDiffOn_iff_localFrame_coeff b e.open_baseSet (subset_refl _)] -- Differentiability of a section can be checked in terms of its local frame coefficients section MDifferentiable omit [IsManifold I 0 M] in -/-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_repr e i` in the local frame +/-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame near `x` induced by `e` and `b` -/ -lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma mdifferentiableAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDiffAt (T% s) x) (i : ι) : - MDiffAt (b.localFrame_repr I e i s) x := by + MDiffAt (b.localFrame_coeff I e i s) x := by -- This boils down to computing the frame coefficients in a local trivialisation. classical -- step 1: on e.baseSet, can compute the coefficient very well @@ -588,7 +602,7 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac apply this.congr_of_eventuallyEq apply eventuallyEq_of_mem (s := e.baseSet) (by simp [e.open_baseSet.mem_nhds hxe]) intro y hy - simp [aux, Basis.localFrame_repr_eq_repr hy] + simp [aux, Basis.localFrame_coeff_eq_coeff hy] simp only [aux] -- step 2: `s` read in trivialization `e` is differentiable @@ -609,150 +623,121 @@ lemma mdifferentiableAt_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpac exact hbas.comp x h₁ omit [IsManifold I 0 M] in -/-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_repr e i` +/-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ -lemma mdifferentiableOn_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) +lemma mdifferentiableOn_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) (hs : MDiff[t] (T% s)) (i : ι) : - MDiff[t] (b.localFrame_repr I e i s) := - fun _ hx ↦ (mdifferentiableAt_localFrame_repr (ht' hx) b + MDiff[t] (b.localFrame_coeff I e i s) := + fun _ hx ↦ (mdifferentiableAt_localFrame_coeff (ht' hx) b (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt omit [IsManifold I 0 M] in -/-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_repr e i` in the +/-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ -lemma mdifferentiableOn_baseSet_localFrame_repr [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma mdifferentiableOn_baseSet_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDiff[e.baseSet] (T% s)) (i : ι) : - MDiff[e.baseSet] (b.localFrame_repr I e i s) := - mdifferentiableOn_localFrame_repr b e.open_baseSet (subset_refl _) hs _ + MDiff[e.baseSet] (b.localFrame_coeff I e i s) := + mdifferentiableOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable at `x ∈ e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma mdifferentiableAt_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ +lemma mdifferentiableAt_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : - MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_repr I e i s) x' := - ⟨fun h i ↦ mdifferentiableAt_localFrame_repr hx b h i, fun hi ↦ - (b.localFrame_isLocalFrameOn_baseSet I 1 e).mdifferentiableAt_of_repr_aux hi e.open_baseSet hx⟩ - -omit [IsManifold I 0 M] in -/-- A section `s` of `V` is differentiable on `t ⊆ e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma mdifferentiableOn_iff_localFrame_repr [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} - (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : - MDiff[t] (T% s) ↔ ∀ i, MDiff[t] (b.localFrame_repr I e i s) := by - refine ⟨fun h i ↦ mdifferentiableOn_localFrame_repr b ht ht' h i, fun hi ↦ ?_⟩ - apply ((b.localFrame_isLocalFrameOn_baseSet I 1 e).mono ht').mdifferentiableOn_of_repr (t := s) - convert hi - sorry -- should be easy/already done above. - -- This doesn’t seem to be used except in the next lemma that is not used anywhere. - -omit [IsManifold I 0 M] in -/-- A section `s` of `V` is differentiable on a trivialisation domain `e.baseSet` iff each of its -coefficients `b.localFrame_repr e i s` in a local frame near `x` is -/ -lemma mdifferentiableOn_baseSet_iff_localFrame_repr - [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} : - MDiff[e.baseSet] (T% s) ↔ ∀ i, MDiff[e.baseSet] (b.localFrame_repr I e i s) := by - rw [mdifferentiableOn_iff_localFrame_repr b e.open_baseSet (subset_refl _)] + MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_coeff I e i s) x' := + ⟨fun h i ↦ mdifferentiableAt_localFrame_coeff hx b h i, fun hi ↦ + (b.localFrame_isLocalFrameOn_baseSet I 1 e).mdifferentiableAt_of_coeff_aux hi e.open_baseSet hx⟩ end MDifferentiable end -- local extension of a vector field in a trivialisation's base set -section extendLocally +section localExtensionOn variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {x : M} + [MemTrivializationAtlas e] {x x' : M} open scoped Classical in --- TODO: add longer docs! --- a starting point (not fully updated any more) is this: -/- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. -The details of the extension are mostly unspecified: for covariant derivatives, the value of -`s` at points other than `x` will not matter (except for shorter proofs). -Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. --/ --- comment: need not be smooth (outside of e.baseSet), but this is a useful building block for --- global smooth extensions of vector fields --- the latter caps this with a smooth bump function, which need not exist if k=C --- In contrast, this definition makes sense over any field --- (for example, *locally* holomorphic sections always exist), +/- Extend a vector `v ∈ V x` to a section `s` of the bundle `V` which is smooth near `x`, +such that `s x = v` and this construction is linear in `v`. -/-- -Extend a vector `v ∈ V x` to a local section of `V`, w.r.t. a chosen local trivialisation. -This construction uses a choice of local frame near `x`, w.r.t. to a basis `b` of `F` and a -compatible local trivialisation `e` of `V` near `x`: the resulting extension has constant -coefficients on `e.baseSet` w.r.t. this trivialisation (and is zero otherwise). +The details of this extension are unspecified (and could be subject to change). +Currently, we construct this extension using a local frame induced by a choose of basis of the +fibre `F` and a compatible trivialisation `e` of `V` around `x`. +(Allowing any local frame near `x` would be easy to implement.) +Our construction has constant coefficients on `e.baseSet` w.r.t. this local frame, and is zero +otherwise. In particular, it is smooth on `e.baseSet`, and (globally) linear in `v`. -In particular, our construction is smooth on `e.baseSet`, and linear in the input vector `v`. +We choose an extension with these particularly nice properties because this simplifies later +constructions on covariant derivatives (and in this context, the value at `s` at points other than +`x` does not matter, but constant frame coefficients are useful). -/ +-- XXX: we could generalise this definition to any local frame on `U ∋ x`, with smoothness on `U`. +-- Would this be useful? Should do this? noncomputable def localExtensionOn (b : Basis ι 𝕜 F) (e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)) [MemTrivializationAtlas e] - (x : M) (v : V x) : (x' : M) → V x' := + {x : M} (v : V x) : (x' : M) → V x' := fun x' ↦ if hx : x ∈ e.baseSet then - letI bV := b.localFrame_toBasis_at e hx; ∑ i, bV.repr v i • b.localFrame e i x' - else 0 + ∑ i, (b.localFrame_toBasis_at e hx).repr v i • b.localFrame e i x' + else 0 variable (b e) in @[simp] lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : - ((localExtensionOn b e x v) x) = v := by + (localExtensionOn b e v) x = v := by simp [localExtensionOn, hx] omit [IsManifold I 0 M] in +variable (b) in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ -lemma localExtensionOn_localFrame_repr (b : Basis ι 𝕜 F) [ContMDiffVectorBundle 1 F V I] - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {x : M} (hx : x ∈ e.baseSet) (v : V x) (i : ι) - {x' : M} (hx' : x' ∈ e.baseSet) : - b.localFrame_repr I e i (localExtensionOn b e x v) x' = - b.localFrame_repr I e i (localExtensionOn b e x v) x := by +lemma localExtensionOn_localFrame_coeff [ContMDiffVectorBundle 1 F V I] + (hx : x ∈ e.baseSet) (hx' : x' ∈ e.baseSet) (v : V x) (i : ι) : + b.localFrame_coeff I e i (localExtensionOn b e v) x' = + b.localFrame_coeff I e i (localExtensionOn b e v) x := by simp [localExtensionOn, hx, hx'] -- By construction, localExtensionOn is a linear map. variable (b e) in lemma localExtensionOn_add (v v' : V x) : - localExtensionOn b e x (v + v') = localExtensionOn b e x v + localExtensionOn b e x v' := by + localExtensionOn b e (v + v') = localExtensionOn b e v + localExtensionOn b e v' := by ext x' by_cases hx: x ∈ e.baseSet; swap · simp [hx, localExtensionOn] · simp [hx, localExtensionOn, add_smul, Finset.sum_add_distrib] variable (b e) in -lemma localExtensionOn_zero : - localExtensionOn b e x 0 = 0 := by +lemma localExtensionOn_zero : localExtensionOn b e (x := x) 0 = 0 := by ext x' by_cases hx: x ∈ e.baseSet <;> simp [hx, localExtensionOn] variable (b e) in lemma localExtensionOn_smul (a : 𝕜) (v : V x) : - localExtensionOn b e x (a • v) = a • localExtensionOn b e x v := by + localExtensionOn b e (a • v) = a • localExtensionOn b e v := by ext x' by_cases hx: x ∈ e.baseSet; swap · simp [hx, localExtensionOn] - · simp [hx, localExtensionOn, Finset.smul_sum] - set B := Basis.localFrame_toBasis_at e b hx - congr - ext i - rw [mul_smul a ((B.repr v) i)] + · simp only [localExtensionOn, hx, ↓reduceDIte, map_smul, Finsupp.coe_smul, Pi.smul_apply, + smul_eq_mul, Finset.smul_sum] + congr with i + rw [mul_smul a (((b.localFrame_toBasis_at e hx).repr v) i)] variable (F) in omit [IsManifold I 0 M] in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] {x : M} (hx : x ∈ e.baseSet) (v : V x) [ContMDiffVectorBundle ∞ F V I] : - CMDiff[e.baseSet] ∞ (T% (localExtensionOn b e x v)) := by + CMDiff[e.baseSet] ∞ (T% (localExtensionOn b e v)) := by -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are -- constant, hence smoothness follows. - rw [contMDiffOn_baseSet_iff_localFrame_repr b] + rw [contMDiffOn_baseSet_iff_localFrame_coeff b] intro i - apply (contMDiffOn_const (c := (b.localFrame_repr I e i) (localExtensionOn b e x v) x)).congr + apply (contMDiffOn_const (c := (b.localFrame_coeff I e i) (localExtensionOn b e v) x)).congr intro y hy - rw [localExtensionOn_localFrame_repr b hx v i hy] + rw [localExtensionOn_localFrame_coeff b hx hy v i] -end extendLocally +end localExtensionOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 8a7b07098f86eb..9861f34a666847 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -110,7 +110,7 @@ omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in variable (t) in lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : - hs.repr i t x = ⟪s i x, t x⟫ := by + hs.coeff i t x = ⟪s i x, t x⟫ := by let b := VectorBundle.gramSchmidtOrthonormalBasis (hs.linearIndependent hx) (hs.generating hx) have beq (i : ι) : b i = s i x := by simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] @@ -119,7 +119,7 @@ lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] have aux := b.repr_apply_apply (t x) i rw [beq] at aux - simp [← aux, IsLocalFrameOn.repr, hx, ← heq'] + simp [← aux, IsLocalFrameOn.coeff, hx, ← heq'] -- This lemma would hold more generally for an *orthogonal frame*. -- variable (t) in @@ -129,13 +129,13 @@ lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : - CMDiffAt[u] n (hs.repr i t) x := + CMDiffAt[u] n (hs.coeff i t) x := ((hs.contMDiffOn i x hx).inner_bundle ht).congr_of_mem (fun _ hy ↦ hs.repr_eq_inner' _ hy _) hx omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] in /-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : - CMDiffAt n (hs.repr i t) x := + CMDiffAt n (hs.coeff i t) x := (((hs.contMDiffOn i).contMDiffAt hu).inner_bundle ht).congr_of_eventuallyEq <| Filter.eventually_of_mem hu fun _ hx ↦ hs.repr_eq_inner' _ hx _ @@ -148,19 +148,19 @@ lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : /-- If `{s i}` is an orthogonal local frame on a neighbourhood `u` of `x` and `t` is `C^k` on `u`, so is its coefficient in the frame `{s i}`. -/ -lemma contMDiffOn_repr (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.repr i t) := +lemma contMDiffOn_repr (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.coeff i t) := fun x' hx ↦ hs.contMDiffWithinAt_repr (ht x' hx) hx _ /-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal local frame near `x` is. -/ lemma contMDiffAt_iff_repr (hu : u ∈ 𝓝 x) : - CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.repr i t) x := - ⟨fun h i ↦ hs.contMDiffAt_repr hu h i, fun h ↦ hs.contMDiffAt_of_repr h hu⟩ + CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.coeff i t) x := + ⟨fun h i ↦ hs.contMDiffAt_repr hu h i, fun h ↦ hs.contMDiffAt_of_coeff h hu⟩ /-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff each of its coefficients `hs.repr i s` w.r.t. the local frame `{s i}` is. -/ -lemma contMDiffOn_iff_repr : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.repr i t) := - ⟨fun h i ↦ hs.contMDiffOn_repr h i, fun hi ↦ hs.contMDiffOn_of_repr hi⟩ +lemma contMDiffOn_iff_repr : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.coeff i t) := + ⟨fun h i ↦ hs.contMDiffOn_repr h i, fun hi ↦ hs.contMDiffOn_of_coeff hi⟩ -- unused, just stating for convenience/nice API include hs in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index f717970a4825b2..f3456d92a9934e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -86,25 +86,25 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_repr I t b + let c := Basis.localFrame_coeff I t b have hs (i) : MDiffAt (T% (s i)) x:= (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : MDiffAt ((c i) σ) x := - mdifferentiableAt_localFrame_repr x_mem b hσ i + mdifferentiableAt_localFrame_coeff x_mem b hσ i have hφ {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) : φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by exact locality hσ (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) - (Basis.localFrame_repr_spec b x_mem σ) + (Basis.localFrame_eventually_eq_sum_coeff_smul b x_mem σ) rw [hφ hσ, hφ hσ', sum_phi, sum_phi] · change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x congr ext i rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i), - Basis.localFrame_repr_congr b hσσ'] + Basis.localFrame_coeff_congr b hσσ'] · exact fun i ↦ (hc hσ' i).smul_section (hs i) · exact fun i ↦ (hc hσ i).smul_section (hs i) @@ -146,15 +146,15 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_repr (I := I) t b - rw [locality (b.localFrame_repr_spec (I := I) x_mem σ), - locality (b.localFrame_repr_spec (I := I) x_mem σ'), sum_phi, sum_phi] + let c := Basis.localFrame_coeff (I := I) t b + rw [locality (b.localFrame_eventually_eq_sum_coeff_smul (I := I) x_mem σ), + locality (b.localFrame_eventually_eq_sum_coeff_smul (I := I) x_mem σ'), sum_phi, sum_phi] change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x congr ext i rw [φ_smul, φ_smul] congr - apply b.localFrame_repr_congr + apply b.localFrame_coeff_congr assumption include I in @@ -250,14 +250,14 @@ lemma tensoriality_criterion'' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteD let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_repr t b - rw [locality (b.localFrame_repr_spec x_mem σ), locality (b.localFrame_repr_spec x_mem σ'), - sum_phi, sum_phi] + let c := Basis.localFrame_coeff t b + rw [locality (b.localFrame_eventually_eq_sum_coeff_smul x_mem σ), + locality (b.localFrame_eventually_eq_sum_coeff_smul x_mem σ'), sum_phi, sum_phi] change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x congr ext i rw [φ_smul, φ_smul] congr - apply b.localFrame_repr_congr + apply b.localFrame_coeff_congr assumption -/ From f518e95f005e52900ed2cb4bae8cb50e5981ddff Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 24 Oct 2025 00:25:16 +0200 Subject: [PATCH 401/601] chore(OrthonormalFrame): adopt coeff instead of repr also --- .../CovariantDerivative/LeviCivita.lean | 8 ++-- .../VectorBundle/OrthonormalFrame.lean | 40 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 9ff485ba5d5e31..fed3a7eb3930d5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -707,10 +707,10 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] rw [hframe.eq_iff_coeff hx] intro i have h₁ : ⟪X, real i⟫ x = (hframe.coeff i) X x := by - rw [hframe.repr_eq_inner' _ hx] + rw [hframe.coeff_eq_inner' _ hx] simp [real, real_inner_comm] have h₂ : ⟪X', real i⟫ x = (hframe.coeff i) X' x := by - rw [hframe.repr_eq_inner' _ hx] + rw [hframe.coeff_eq_inner' _ hx] simp [real, real_inner_comm] rw [← h₁, ← h₂, h (real i)] @@ -822,7 +822,7 @@ lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ calc _ _ = ∑ i, hZ.coeff i σ x • Z i x := by congr; ext i - rw [hZ.repr_eq_inner' σ hx i, product_swap] + rw [hZ.coeff_eq_inner' σ hx i, product_swap] _ = σ x := (hZ.toIsLocalFrameOn.coeff_sum_eq _ hx).symm trans ∑ i, leviCivitaRhs I X (g • σ) (Z i) x • (Z i) x · congr @@ -929,7 +929,7 @@ lemma eq_product_apply [Fintype ι] choose r wo using exists_wellOrder _ exact r have : LocallyFiniteOrderBot ι := by sorry - rw [ChristoffelSymbol, hs.repr_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] + rw [ChristoffelSymbol, hs.coeff_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] -- Lemma 4.3 in Lee, Chapter 5: first term still missing lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeOn E f U) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 9861f34a666847..6dc82c99ed61ba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -109,7 +109,7 @@ variable (hs : IsOrthonormalFrameOn IB F n s u) {t : (x : B) → E x} {x : B} omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in variable (t) in -lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : +lemma coeff_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : hs.coeff i t x = ⟪s i x, t x⟫ := by let b := VectorBundle.gramSchmidtOrthonormalBasis (hs.linearIndependent hx) (hs.generating hx) have beq (i : ι) : b i = s i x := by @@ -123,21 +123,21 @@ lemma repr_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : -- This lemma would hold more generally for an *orthogonal frame*. -- variable (t) in --- lemma repr_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : --- hs.repr i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by +-- lemma coeff_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : +-- hs.coeff i t x = ⟪s i x, t x⟫ / (‖s i x‖ ^ 2) := by -- sorry -- need a version of b.repr_apply_apply for *orthogonal* bases -/-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ -lemma contMDiffWithinAt_repr (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : +/-- If `t` is `C^k` at `x`, so is its coefficient `hs.coeff i t` in a local frame s near `x` -/ +lemma contMDiffWithinAt_coeff (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : CMDiffAt[u] n (hs.coeff i t) x := - ((hs.contMDiffOn i x hx).inner_bundle ht).congr_of_mem (fun _ hy ↦ hs.repr_eq_inner' _ hy _) hx + ((hs.contMDiffOn i x hx).inner_bundle ht).congr_of_mem (fun _ hy ↦ hs.coeff_eq_inner' _ hy _) hx omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] in -/-- If `t` is `C^k` at `x`, so is its coefficient `hs.repr i t` in a local frame s near `x` -/ -lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : +/-- If `t` is `C^k` at `x`, so is its coefficient `hs.coeff i t` in a local frame s near `x` -/ +lemma contMDiffAt_coeff (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : CMDiffAt n (hs.coeff i t) x := (((hs.contMDiffOn i).contMDiffAt hu).inner_bundle ht).congr_of_eventuallyEq <| - Filter.eventually_of_mem hu fun _ hx ↦ hs.repr_eq_inner' _ hx _ + Filter.eventually_of_mem hu fun _ hx ↦ hs.coeff_eq_inner' _ hx _ -- Future: prove the same result for all local frames -- if `{s i}` is a local frame on `u`, and `{s' i}` are the corresponding orthogonalised frame, @@ -148,31 +148,31 @@ lemma contMDiffAt_repr (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : /-- If `{s i}` is an orthogonal local frame on a neighbourhood `u` of `x` and `t` is `C^k` on `u`, so is its coefficient in the frame `{s i}`. -/ -lemma contMDiffOn_repr (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.coeff i t) := - fun x' hx ↦ hs.contMDiffWithinAt_repr (ht x' hx) hx _ +lemma contMDiffOn_coeff (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.coeff i t) := + fun x' hx ↦ hs.contMDiffWithinAt_coeff (ht x' hx) hx _ /-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal local frame near `x` is. -/ -lemma contMDiffAt_iff_repr (hu : u ∈ 𝓝 x) : +lemma contMDiffAt_iff_coeff (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.coeff i t) x := - ⟨fun h i ↦ hs.contMDiffAt_repr hu h i, fun h ↦ hs.contMDiffAt_of_coeff h hu⟩ + ⟨fun h i ↦ hs.contMDiffAt_coeff hu h i, fun h ↦ hs.contMDiffAt_of_coeff h hu⟩ /-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff -each of its coefficients `hs.repr i s` w.r.t. the local frame `{s i}` is. -/ -lemma contMDiffOn_iff_repr : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.coeff i t) := - ⟨fun h i ↦ hs.contMDiffOn_repr h i, fun hi ↦ hs.contMDiffOn_of_coeff hi⟩ +each of its coefficients `hs.coeff i s` w.r.t. the local frame `{s i}` is. -/ +lemma contMDiffOn_iff_coeff : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.coeff i t) := + ⟨fun h i ↦ hs.contMDiffOn_coeff h i, fun hi ↦ hs.contMDiffOn_of_coeff hi⟩ -- unused, just stating for convenience/nice API include hs in -lemma contMDiffAt_iff_repr' (hu : u ∈ 𝓝 x) : +lemma contMDiffAt_iff_coeff' (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫) x := by - rw [hs.contMDiffAt_iff_repr hu] - have (i : ι) := Filter.eventually_of_mem hu fun x hx ↦ (hs.repr_eq_inner' t hx i) + rw [hs.contMDiffAt_iff_coeff hu] + have (i : ι) := Filter.eventually_of_mem hu fun x hx ↦ (hs.coeff_eq_inner' t hx i) exact ⟨fun h i ↦ (h i).congr_of_eventuallyEq <| Filter.EventuallyEq.symm (this i), fun h i ↦ (h i).congr_of_eventuallyEq (this i)⟩ -- unused, just stating for convenience/nice API -lemma contMDiffOn_iff_repr' : +lemma contMDiffOn_iff_coeff' : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (fun x ↦ ⟪s i x, t x⟫) := sorry -- similar to the above lemma From 2b93ad30fb2689b86ee620c5e0c5e8fcf5a85e58 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 24 Oct 2025 17:19:55 +0200 Subject: [PATCH 402/601] Restore mem_horiz_iff_exists --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 81a14aa0d1b70e..cec277da7f63ea 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1103,7 +1103,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : replace huv : v = 0 := by simpa using huv subst huv use fun x ↦ f - sorry --simpa [hcov.zeroX, mdifferentiableAt_section] using mdifferentiableAt_const + simp [hcov.zeroX, mdifferentiableAt_section, mdifferentiableAt_const] rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ use map_of_one_jet u w, ?_, h, h'' · rw [hcov.eq_one_form] From db19098410ae73a1356a708bbc158156fa201498 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 16:31:54 +0100 Subject: [PATCH 403/601] Fix build in LocalFrame --- .../Manifold/VectorBundle/LocalFrame.lean | 49 ++++++------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 68518885ec67b9..dc3860b5708ae1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -359,12 +359,13 @@ end IsLocalFrame namespace Module.Basis variable {ι : Type*} {x : M} +variable [VectorBundle 𝕜 F V] noncomputable def localFrame_toBasis_at (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (hx : x ∈ e.baseSet) : Basis ι 𝕜 (V x) := - b.map (e.linearEquivAt (R := 𝕜) x hx).symm + b.map (Trivialization.linearEquivAt (R := 𝕜) e x hx).symm open scoped Classical in -- If x is outside of `e.baseSet`, this returns the junk value 0. @@ -378,10 +379,9 @@ noncomputable def localFrame -- TODO: understand why this isn’t already a simp lemma attribute [simp] Trivialization.apply_mk_symm -omit [IsManifold I 0 M] in /-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.baseSet`. -/ -lemma contMDiffOn_localFrame_baseSet +lemma contMDiffOn_localFrame_baseSet [ContMDiffVectorBundle n F V I] (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) : CMDiff[e.baseSet] n (T% (b.localFrame e i)) := by @@ -390,10 +390,9 @@ lemma contMDiffOn_localFrame_baseSet intro y hy simp [localFrame, hy, localFrame_toBasis_at] -omit [IsManifold I 0 M] in variable (I) in /-- `b.localFrame e i` is indeed a local frame on `e.baseSet` -/ -lemma localFrame_isLocalFrameOn_baseSet +lemma localFrame_isLocalFrameOn_baseSet [ContMDiffVectorBundle n F V I] (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) : IsLocalFrameOn I F n (b.localFrame e) e.baseSet where @@ -407,8 +406,7 @@ lemma localFrame_isLocalFrameOn_baseSet convert (b.localFrame_toBasis_at e hx).span_eq.ge simp [localFrame, hx, localFrame_toBasis_at] -omit [IsManifold I 0 M] in -lemma _root_.contMDiffAt_localFrame_of_mem +lemma _root_.contMDiffAt_localFrame_of_mem [ContMDiffVectorBundle n F V I] (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) [MemTrivializationAtlas e] (b : Basis ι 𝕜 F) (i : ι) (hx : x ∈ e.baseSet) : CMDiffAt n (T% (b.localFrame e i)) x := @@ -449,7 +447,6 @@ noncomputable def localFrame_coeff variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} -omit [IsManifold I 0 M] in variable (e b) in @[simp] lemma localFrame_coeff_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x : M, V x) (i : ι) : @@ -457,7 +454,6 @@ lemma localFrame_coeff_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (s : Π x simpa [localFrame_coeff] using (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_apply_of_notMem hx s i -omit [IsManifold I 0 M] in variable (e b) in @[simp] lemma localFrame_coeff_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M, V x) (i : ι) : @@ -467,14 +463,12 @@ lemma localFrame_coeff_apply_of_mem_baseSet (hx : x ∈ e.baseSet) (s : Π x : M exact ilf.coeff_apply_of_mem hx s i -- XXX better variable name! -- TODO: better name? -omit [IsManifold I 0 M] in lemma localFrame_coeff_sum_eq [Fintype ι] (s : Π x : M, V x) {x'} (hx : x' ∈ e.baseSet) : s x' = (∑ i, (b.localFrame_coeff I e i s x') • b.localFrame e i x') := by simp only [localFrame_coeff] exact (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_sum_eq s hx variable (b) in -omit [IsManifold I 0 M] in /-- A local frame locally spans the space of sections for `V`: for each local trivialisation `e` of `V` around `x`, we have `s = ∑ i, (b.localFrame_coeff e i s) • b.localFrame e i` -/ lemma localFrame_eventually_eq_sum_coeff_smul [Fintype ι] @@ -482,7 +476,6 @@ lemma localFrame_eventually_eq_sum_coeff_smul [Fintype ι] ∀ᶠ x' in 𝓝 x, s x' = ∑ i, (b.localFrame_coeff I e i s x') • b.localFrame e i x' := eventually_nhds_iff.mpr ⟨e.baseSet, fun _ h ↦ localFrame_coeff_sum_eq s h, e.open_baseSet, hxe⟩ -omit [IsManifold I 0 M] in /-- The representation of `s` in a local frame at `x` only depends on `s` at `x`. -/ lemma localFrame_coeff_congr (b : Basis ι 𝕜 F) {s s' : Π x : M, V x} {i : ι} (hss' : s x = s' x) : @@ -492,7 +485,6 @@ lemma localFrame_coeff_congr (b : Basis ι 𝕜 F) congr · simp [localFrame_coeff, hxe] -omit [IsManifold I 0 M] in lemma localFrame_coeff_apply_zero_at (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : s x = 0) (i : ι) : b.localFrame_coeff I e i s x = 0 := by @@ -501,7 +493,6 @@ lemma localFrame_coeff_apply_zero_at variable {n} -omit [IsManifold I 0 M] in /-- Suppose `e` is a compatible trivialisation around `x ∈ M`, and `s` a bundle section. Then the coefficient of `s` w.r.t. the local frame induced by `b` and `e` equals the cofficient of "`s x` read in the trivialisation `e`" for `b i`. -/ @@ -521,10 +512,9 @@ proven in `OrthonormalFrame.lean`). variable {ι : Type*} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} - [ContMDiffVectorBundle 1 F V I] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] -- TODO: can this be proven more generally, for any local frame? -omit [IsManifold I 0 M] in /-- If `s` is `C^k` at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame near `x` induced by `e` and `b` -/ lemma contMDiffAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -543,7 +533,6 @@ lemma contMDiffAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace intro y hy simp [aux, Basis.localFrame_coeff_eq_coeff hy] simp only [aux] - -- step 2: `s` read in trivialization `e` is `C^k` have h₁ : CMDiffAt k (fun x ↦ (e (s x)).2) x := e.contMDiffAt_section_iff hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth @@ -561,7 +550,6 @@ lemma contMDiffAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace contMDiffAt_iff_contDiffAt.mpr <| (basL.contDiff (n := k)).contDiffAt exact hbas.comp x h₁ -omit [IsManifold I 0 M] in /-- If `s` is `C^k` on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ lemma contMDiffOn_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) @@ -571,7 +559,6 @@ lemma contMDiffOn_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace fun _ hx ↦ (contMDiffAt_localFrame_coeff (ht' hx) b (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt -omit [IsManifold I 0 M] in /-- If `s` is `C^k` on `e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ lemma contMDiffOn_baseSet_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -579,10 +566,9 @@ lemma contMDiffOn_baseSet_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteS (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : CMDiff[e.baseSet] k (b.localFrame_coeff I e i s) := contMDiffOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ -omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` at `x ∈ e.baseSet` iff each of its coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ -lemma contMDiffAt_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma contMDiffAt_iff_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {x' : M} (hx : x' ∈ e.baseSet) : CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k (b.localFrame_coeff I e i s) x' := @@ -590,10 +576,9 @@ lemma contMDiffAt_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [ fun hi ↦ (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_coeff hi (e.open_baseSet.mem_nhds hx)⟩ -omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on `t ⊆ e.baseSet` iff each of its coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ -lemma contMDiffOn_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma contMDiffOn_iff_localFrame_coeff [Finite ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] {t : Set M} (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k (b.localFrame_coeff I e i s) := by @@ -601,6 +586,7 @@ lemma contMDiffOn_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [ -- TODO: golf this using the lemmas above -- intro x hx -- let aux := (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_coeff (t := s) (x := x) + have := Fintype.ofFinite ι have this (i) : CMDiff[t] k (T% ((b.localFrame_coeff I e i) s • b.localFrame e i)) := (hi i).smul_section ((b.contMDiffOn_localFrame_baseSet k e i).mono ht') let rhs := fun x' ↦ ∑ i, (b.localFrame_coeff I e i) s x' • b.localFrame e i x' @@ -609,10 +595,9 @@ lemma contMDiffOn_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [ intro y hy simpa using b.localFrame_coeff_sum_eq s (ht' hy) -omit [IsManifold I 0 M] in /-- A section `s` of `V` is `C^k` on a trivialisation domain `e.baseSet` iff each of its coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ -lemma contMDiffOn_baseSet_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma contMDiffOn_baseSet_iff_localFrame_coeff [Finite ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {k : WithTop ℕ∞} [ContMDiffVectorBundle k F V I] : CMDiff[e.baseSet] k (T% s) ↔ ∀ i, CMDiff[e.baseSet] k (b.localFrame_coeff I e i s) := by rw [contMDiffOn_iff_localFrame_coeff b e.open_baseSet (subset_refl _)] @@ -620,7 +605,6 @@ lemma contMDiffOn_baseSet_iff_localFrame_coeff [Fintype ι] [FiniteDimensional -- Differentiability of a section can be checked in terms of its local frame coefficients section MDifferentiable -omit [IsManifold I 0 M] in /-- If `s` is diffentiable at `x`, so is its coefficient `b.localFrame_coeff e i` in the local frame near `x` induced by `e` and `b` -/ lemma mdifferentiableAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -637,7 +621,6 @@ lemma mdifferentiableAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpa intro y hy simp [aux, Basis.localFrame_coeff_eq_coeff hy] simp only [aux] - -- step 2: `s` read in trivialization `e` is differentiable have h₁ : MDiffAt (fun x ↦ (e (s x)).2) x := e.mdifferentiableAt_section_iff I s hxe |>.1 hs -- step 3: `b.repr` is a linear map, so the composition is smooth @@ -655,7 +638,6 @@ lemma mdifferentiableAt_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpa mdifferentiableAt_iff_differentiableAt.mpr (basL.differentiable _) exact hbas.comp x h₁ -omit [IsManifold I 0 M] in /-- If `s` is differentiable on `t ⊆ e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ lemma mdifferentiableOn_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) @@ -665,7 +647,6 @@ lemma mdifferentiableOn_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpa fun _ hx ↦ (mdifferentiableAt_localFrame_coeff (ht' hx) b (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt -omit [IsManifold I 0 M] in /-- If `s` is differentiable on `e.baseSet`, so is its coefficient `b.localFrame_coeff e i` in the local frame induced by `e` -/ lemma mdifferentiableOn_baseSet_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -674,10 +655,9 @@ lemma mdifferentiableOn_baseSet_localFrame_coeff [FiniteDimensional 𝕜 F] [Com MDiff[e.baseSet] (b.localFrame_coeff I e i s) := mdifferentiableOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ -omit [IsManifold I 0 M] in /-- A section `s` of `V` is differentiable at `x ∈ e.baseSet` iff each of its coefficients `b.localFrame_coeff e i s` in a local frame near `x` is -/ -lemma mdifferentiableAt_iff_localFrame_coeff [Fintype ι] [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] +lemma mdifferentiableAt_iff_localFrame_coeff [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] (b : Basis ι 𝕜 F) {s : Π x : M, V x} {x' : M} (hx : x' ∈ e.baseSet) : MDiffAt (T% s) x' ↔ ∀ i, MDiffAt (b.localFrame_coeff I e i s) x' := ⟨fun h i ↦ mdifferentiableAt_localFrame_coeff hx b h i, fun hi ↦ @@ -695,7 +675,6 @@ variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} [MemTrivializationAtlas e] {x x' : M} open scoped Classical in - /- Extend a vector `v ∈ V x` to a section `s` of the bundle `V` which is smooth near `x`, such that `s x = v` and this construction is linear in `v`. @@ -712,20 +691,21 @@ constructions on covariant derivatives (and in this context, the value at `s` at -/ -- XXX: we could generalise this definition to any local frame on `U ∋ x`, with smoothness on `U`. -- Would this be useful? Should do this? -noncomputable def localExtensionOn (b : Basis ι 𝕜 F) +noncomputable def localExtensionOn (b : Basis ι 𝕜 F) [VectorBundle 𝕜 F V] (e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)) [MemTrivializationAtlas e] {x : M} (v : V x) : (x' : M) → V x' := fun x' ↦ if hx : x ∈ e.baseSet then ∑ i, (b.localFrame_toBasis_at e hx).repr v i • b.localFrame e i x' else 0 +variable [VectorBundle 𝕜 F V] + variable (b e) in @[simp] lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : (localExtensionOn b e v) x = v := by simp [localExtensionOn, hx] -omit [IsManifold I 0 M] in variable (b) in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ lemma localExtensionOn_localFrame_coeff [ContMDiffVectorBundle 1 F V I] @@ -761,7 +741,6 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : rw [mul_smul a (((b.localFrame_toBasis_at e hx).repr v) i)] variable (F) in -omit [IsManifold I 0 M] in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] {x : M} (hx : x ∈ e.baseSet) (v : V x) [ContMDiffVectorBundle ∞ F V I] : CMDiff[e.baseSet] ∞ (T% (localExtensionOn b e v)) := by From ab64b0d59545c0c00f75fa50552cfeef29a1c948 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 16:37:37 +0100 Subject: [PATCH 404/601] More fixes --- .../VectorBundle/GramSchmidtOrtho.lean | 16 ++++++++------ .../VectorBundle/OrthonormalFrame.lean | 21 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean index be451ad2a11407..874c1a5e272fdb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -3,11 +3,13 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho -import Mathlib.Analysis.SpecialFunctions.Sqrt -import Mathlib.Geometry.Manifold.VectorBundle.Riemannian -import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -import Mathlib.Geometry.Manifold.Notation +module + +public import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho +public import Mathlib.Analysis.SpecialFunctions.Sqrt +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.Notation /-! # Gram-Schmidt orthonormalisation on sections of Riemannian vector bundles @@ -33,6 +35,8 @@ vector bundle, bundle metric, orthonormal frame, Gram-Schmidt open Manifold Bundle ContinuousLinearMap ENat Bornology open scoped ContDiff Topology +@[expose] public section -- FIXME: re-consider if we really want to expose all definitions + -- Let `V` be a smooth vector bundle with a `C^n` Riemannian structure over a `C^k` manifold `B`. variable {EB : Type*} [NormedAddCommGroup EB] [NormedSpace ℝ EB] @@ -332,7 +336,7 @@ lemma contMDiffWithinAt_inner (hs : CMDiffAt[u] n (T% s) x) (hs' : s x ≠ 0) : exact Real.contDiffAt_sqrt (by simp [F, hs']) exact h1.comp x (hs.inner_bundle hs) (Set.mapsTo_image _ u) convert aux - simp [F, ← norm_eq_sqrt_real_inner] + simp [F] end helper diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 6dc82c99ed61ba..6f84fe2a8b6278 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho -import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +module + +public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho +public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame /-! # Existence of orthonormal frames on Riemannian vector bundles @@ -39,6 +41,8 @@ variable [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] +@[expose] public section -- FIXME: think if expose is desired! + local notation "⟪" x ", " y "⟫" => inner ℝ x y variable {ι : Type*} [LinearOrder ι] [LocallyFiniteOrderBot ι] [WellFoundedLT ι] @@ -153,18 +157,19 @@ lemma contMDiffOn_coeff (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.coe /-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal local frame near `x` is. -/ -lemma contMDiffAt_iff_coeff (hu : u ∈ 𝓝 x) : +lemma contMDiffAt_iff_coeff [FiniteDimensional ℝ F] (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.coeff i t) x := ⟨fun h i ↦ hs.contMDiffAt_coeff hu h i, fun h ↦ hs.contMDiffAt_of_coeff h hu⟩ /-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff each of its coefficients `hs.coeff i s` w.r.t. the local frame `{s i}` is. -/ -lemma contMDiffOn_iff_coeff : CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.coeff i t) := +lemma contMDiffOn_iff_coeff [FiniteDimensional ℝ F] : + CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.coeff i t) := ⟨fun h i ↦ hs.contMDiffOn_coeff h i, fun hi ↦ hs.contMDiffOn_of_coeff hi⟩ -- unused, just stating for convenience/nice API include hs in -lemma contMDiffAt_iff_coeff' (hu : u ∈ 𝓝 x) : +lemma contMDiffAt_iff_coeff' [FiniteDimensional ℝ F] (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (fun x ↦ ⟪s i x, t x⟫) x := by rw [hs.contMDiffAt_iff_coeff hu] have (i : ι) := Filter.eventually_of_mem hu fun x hx ↦ (hs.coeff_eq_inner' t hx i) @@ -223,14 +228,14 @@ variable [ContMDiffVectorBundle 1 F E IB] [IsContMDiffRiemannianBundle IB 1 F E] variable (b e) in lemma _root_.mdifferentiableAt_orthonormalFrame_of_mem (i : ι) {x : B} (hx : x ∈ e.baseSet) : MDiffAt (T% (b.orthonormalFrame e i)) x := by - apply ContMDiffAt.mdifferentiableAt _ le_rfl + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero exact (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx @[simp] lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : b.orthonormalFrame e i x = 0 := by - simp only [orthonormalFrame, VectorBundle.gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed] - simp + simp only [orthonormalFrame, VectorBundle.gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed, + RCLike.ofReal_real_eq_id, id_eq, smul_eq_zero, inv_eq_zero, norm_eq_zero, or_self] convert InnerProductSpace.gramSchmidt_zero ℝ i apply localFrame_apply_of_notMem e b hx From 694686b53442b77611a286990604788a10a663ac Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 16:42:27 +0100 Subject: [PATCH 405/601] More warnings and fixes --- .../CovariantDerivative/Basic.lean | 23 +++++++------------ .../Manifold/VectorBundle/Tensoriality.lean | 16 ++++++------- .../Manifold/VectorField/LieBracket.lean | 20 ++++++++-------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index cec277da7f63ea..851cec5674257c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -81,7 +81,7 @@ lemma map_of_loc_one_jet_spec [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] · apply (differentiableAt_const e').add apply diff.differentiableAt.comp fun_prop - · simp + · simp only [map_sub, fderiv_const_add] rw [fderiv_sub_const] change (fderiv 𝕜 φ e) u = _ rw [φ.hasFDerivAt.fderiv] @@ -96,13 +96,6 @@ def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I (map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ φ -lemma ContinuousLinearMap.IsInvertible.injective {R M M₂ : Type*} [TopologicalSpace M] - [TopologicalSpace M₂] [Semiring R] [AddCommMonoid M] [Module R M] - [AddCommMonoid M₂] [Module R M₂] {f : M →L[R] M₂} (h : f.IsInvertible) : - Function.Injective f := by - rcases h with ⟨ψ, hψ⟩ - refine Function.HasLeftInverse.injective ⟨ψ.symm, fun x ↦ ψ.symm_apply_eq.mpr (by simp [← hψ])⟩ - -- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. /-- For any `(x, u) ∈ TM` and `(x', u') ∈ TM'`, `map_of_one_jet u u'` sends `x` to `x'` and @@ -457,7 +450,7 @@ lemma zeroX (hf : IsCovariantDerivativeOn F f s) -- TODO: writing MDiffAt here yields an error! have : MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (T% (fun x ↦ (0 : TangentSpace I x))) x := by apply ContMDiff.mdifferentiableAt (n := 1) --(le_refl 1) - swap; simp_all + swap; · simp_all sorry -- zero section is smooth! simpa using IsCovariantDerivativeOn.addX f hf (X := 0) this this hσ @@ -925,7 +918,7 @@ lemma differenceAux_tensorial exact hcov.differenceAux_smul_eq hcov' σ f hx hX' hf x · intro σ σ' hσ hσ' unfold φ differenceAux - simp + simp only [Pi.sub_apply] rw [hcov.addσ, hcov'.addσ] <;> try assumption abel @@ -1075,7 +1068,7 @@ lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (X : Π x : M, TM x) noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : Submodule ℝ (TM x × F) := - LinearMap.ker (hcov.projection x f) + (hcov.projection x f).ker lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : IsCompl (hcov.horiz x f) (.prod ⊥ ⊤) := by @@ -1096,7 +1089,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : cov (extend I E u) σ x = 0 := by constructor · intro huv - simp [horiz] at huv + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv let w : TangentSpace 𝓘(ℝ, F) f := v by_cases hu : u = 0 · subst hu @@ -1111,7 +1104,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : · rwa [mdifferentiableAt_section] · rwa [mdifferentiableAt_section] · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ - simp [horiz, ← covσ] + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covσ] rw [hcov.eq_one_form σ_diff, extend_apply_self] end projection_trivial_bundle @@ -1148,11 +1141,11 @@ def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := - LinearMap.ker (cov.proj v) + (cov.proj v).ker noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := - LinearMap.ker (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v) + (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (v : TotalSpace F V) : IsCompl (cov.horiz v) (vert v) := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index f3456d92a9934e..60d959600f6e59 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -58,7 +58,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] · rw [Pi.smul_apply', Pi.smul_apply', h] · simp [notMem_support.mp fun a ↦ h (hψ a)] have hψ' : MDifferentiableAt I 𝓘(ℝ) ψ x := - ψ.contMDiffAt.mdifferentiableAt ENat.LEInfty.out + ψ.contMDiffAt.mdifferentiableAt (by simp) calc φ σ x _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul _ _ hψ' hσ] _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] @@ -71,16 +71,16 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] induction s using Finset.induction_on with | empty => simp only [Finset.sum_empty] - have h₁ : MDiffAt (fun x' : M ↦ (0 : ℝ)) x := by - exact contMDiffAt_const.mdifferentiableAt le_rfl + have h₁ : MDiffAt (fun x' : M ↦ (0 : ℝ)) x := mdifferentiableAt_const rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl] rw [φ_smul] simp - exact h₁ - apply (contMDiff_zeroSection _ _).mdifferentiableAt ENat.LEInfty.out + · exact h₁ + -- TODO: add mdifferentiable_zeroSection and/or use it! + apply (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero | insert a s ha h => change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp [Finset.sum_insert ha, ← h] + simp only [Finset.sum_insert ha, ← h] exact φ_add _ _ (hσ a) (.sum_section hσ) have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F @@ -88,7 +88,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] let s := b.localFrame (trivializationAt F V x) let c := Basis.localFrame_coeff I t b have hs (i) : MDiffAt (T% (s i)) x:= - (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt le_rfl + (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt (by simp) have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : MDiffAt ((c i) σ) x := mdifferentiableAt_localFrame_coeff x_mem b hσ i @@ -140,7 +140,7 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi simp | insert a s ha h => change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp [Finset.sum_insert ha, ← h] + simp only [Finset.sum_insert ha, ← h] erw [φ_add] have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 41287464e0fc0c..0fd99c0a3f1069 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -389,7 +389,7 @@ lemma aux_computation2 : have : fderivWithin 𝕜 (φ ∘ φ.symm) (range I) (φ x) = fderivWithin 𝕜 id (range I) (φ x) := by refine fderivWithin_congr' ?_ ?_ · intro x' hx' - simp + simp only [comp_apply, id_eq] refine PartialEquiv.right_inv φ ?_ rw [extChartAt_target] refine ⟨?_, hx'⟩ @@ -428,7 +428,6 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA rwa [extChartAt_self_eq] at hf let aux := lieBracketWithin_smul_right (V := V') hf' hW.differentiableWithinAt_mpullbackWithin_vectorField hs - -- rw [← Pi.smul_def'] -- We need the cast, since on the nose `B` is a map `E → E`, -- while we need a map between tangent spaces. @@ -440,11 +439,16 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA -- We prove the equality of each summand separately. rw [← Pi.add_def, mpullback_add_apply]; congr; swap · simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] - -- This part is still TODO/ in progress!! unfold A - simp [mfderivWithin, hf] - simp [mpullback] + simp only [mpullback, extChartAt.eq_1, OpenPartialHomeomorph.extend.eq_1, PartialEquiv.coe_trans, + ModelWithCorners.toPartialEquiv_coe, OpenPartialHomeomorph.toFun_eq_coe, comp_apply, extChartAt, + OpenPartialHomeomorph.extend, map_smul, mfderivWithin, hf, ↓reduceIte, writtenInExtChartAt, + OpenPartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, + OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, + PartialEquiv.trans_refl, PartialEquiv.refl_coe, PartialEquiv.coe_trans_symm, + OpenPartialHomeomorph.coe_coe_symm, ModelWithCorners.toPartialEquiv_coe_symm, + CompTriple.comp_eq] have cleanup1 : I ((chartAt H x) x) = x' := rfl have cleanup2 : f ∘ (chartAt H x).symm ∘ I.symm = f' := rfl rw [cleanup1, cleanup2, ← aux_computation x W] @@ -501,8 +505,7 @@ lemma mlieBracketWithin_const_smul_left (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (c • V) W s x = c • mlieBracketWithin I V W s x := by have aux := mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs - simp [mfderivWithin_const] at aux - exact aux + simpa [mfderivWithin_const] using aux lemma mlieBracket_const_smul_left (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) : @@ -516,8 +519,7 @@ lemma mlieBracketWithin_const_smul_right (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (c • W) s x = c • mlieBracketWithin I V W s x := by have aux := mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs - simp [mfderivWithin_const] at aux - exact aux + simpa [mfderivWithin_const] using aux lemma mlieBracket_const_smul_right (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : From d90bf9181713bdf24287f965c1d6887d9e08c247 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 16:48:06 +0100 Subject: [PATCH 406/601] Further, and modulize further --- .../CovariantDerivative/Basic.lean | 26 ++++++++------- .../CovariantDerivative/LeviCivita.lean | 32 +++++++++++-------- .../CovariantDerivative/Torsion.lean | 10 +++--- .../Geometry/Manifold/VectorBundle/Misc.lean | 8 +++-- .../Manifold/VectorBundle/Tensoriality.lean | 16 ++++++---- 5 files changed, 56 insertions(+), 36 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 851cec5674257c..ac590d944e4546 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -3,16 +3,18 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -import Mathlib.Geometry.Manifold.VectorBundle.Tangent -import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.Notation -import Mathlib.Geometry.Manifold.VectorBundle.Misc -import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -import Mathlib.Geometry.Manifold.VectorField.LieBracket -import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +module + +public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary /-! # Covariant derivatives @@ -27,6 +29,8 @@ open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] +@[expose] public section -- TODO: think if we want to expose all definitions! + section general_lemmas -- those lemmas should move section linear_algebra @@ -39,7 +43,7 @@ lemma exists_map_of (u : E) (u' : E') : by_cases h : u = 0 · simp [h] tauto - · have indep : LinearIndepOn 𝕜 id {u} := LinearIndepOn.id_singleton 𝕜 h + · have indep : LinearIndepOn 𝕜 id {u} := LinearIndepOn.singleton h let s := indep.extend (subset_univ _) have hus : u ∈ s := singleton_subset_iff.mp <| indep.subset_extend (subset_univ _) use (Basis.extend indep).constr (M' := E') (S := 𝕜) fun _ ↦ u' diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index fed3a7eb3930d5..9ff0a689e542cb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -3,11 +3,13 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion -import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame -import Mathlib.Geometry.Manifold.VectorBundle.Tangent -import Mathlib.Geometry.Manifold.VectorBundle.Riemannian -import Mathlib.Util.PrintSorries +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Util.PrintSorries /-! # The Levi-Civita connection @@ -27,6 +29,8 @@ open Bundle Filter Function Module Topology open scoped Bundle Manifold ContDiff +@[expose] public section -- TODO: think if we want to expose all definitions! + -- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. variable {n : WithTop ℕ∞} {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] @@ -511,19 +515,20 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} simp_rw [rhs_aux_smulX I Y Z X f] simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] rw [rhs_aux_smulY_apply I X hf hY hZ, rhs_aux_smulZ_apply I Z hf hX hY] - -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? have h1 : ⟪Z, mlieBracket I (f • Y) X⟫ x = - (bar _).toFun (((mfderiv% f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] congr - · simp [bar]; rw [real_inner_smul_right] + · simp only [neg_smul, inner_neg_right, bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul, + neg_mul, neg_inj] + rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = (bar _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] congr - · simp [bar]; rw [real_inner_smul_right] + · simp only [bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul]; rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] rw [h1, h2, product_swap I Y Z] @@ -591,7 +596,6 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} leviCivitaRhs' I X Y (f • Z) x = f x • leviCivitaRhs' I X Y Z x := by simp only [leviCivitaRhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] - -- Apply the product rule for the lie bracket. -- Let's encapsulate the going into the product and back out again. have h1 : ⟪Y, mlieBracket I X (f • Z)⟫ x = @@ -700,7 +704,6 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] choose r wo using exists_wellOrder _ exact r have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g let real := b.orthonormalFrame t have hframe := b.orthonormalFrame_isOrthonormalFrameOn t (F := E) (IB := I) (n := 1) @@ -869,7 +872,7 @@ variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: this is unique up to the value on non-differentiable vector fields. If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ -private noncomputable def LeviCivitaConnection_aux [FiniteDimensional ℝ E] +@[no_expose] noncomputable def LeviCivitaConnection_aux [FiniteDimensional ℝ E] (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : CovariantDerivative I E (TangentSpace I : M → Type _) where -- This is the existence part of the proof: take the formula derived above @@ -959,6 +962,7 @@ lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeO -/ lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] + [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) (hs : IsLocalFrameOn I E n s U) (hfg : ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x) : @@ -974,6 +978,7 @@ lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] /-- Two covariant derivatives on `U` are equal on `U` if and only if all of their covariant derivatives w.r.t. some local frame on `U` are equal on `U`. -/ lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ι] + [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) (hs : IsLocalFrameOn I E n s U) : (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x) ↔ @@ -1005,6 +1010,7 @@ variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSp A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fintype ι] + [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? (hf : IsCovariantDerivativeOn E f U) {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : @@ -1134,8 +1140,8 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x abel -- now, just rewrite `inner` to take out a sum: same lemma twice convert this - sorry - sorry + · sorry + · sorry -- deduce the goal from `aux` sorry diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 20c2180bd419f3..15628d5d192bfa 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -3,7 +3,9 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic /-! # Torsion of a covariant derivative @@ -16,6 +18,8 @@ TODO: add a more complete doc-string -/ +@[expose] public section -- TODO: think if we want to expose all definitions! + open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff @@ -200,8 +204,6 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] -- and related torsion-freeness to this -- (That will not work for torsion-freeness on a set, though.) -set_option linter.style.commandStart true - -- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, -- so it would apply here as well @@ -229,7 +231,7 @@ lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTo -- This should be obvious; am I doing something wrong? lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by - simp [IsTorsionFree] + simp only [IsTorsionFree] constructor · intro h X Y have : torsion cov X Y = 0 := by simp [h] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean index c5622ace701f72..c0b812eee40f77 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -3,8 +3,10 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.Notation -import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +module + +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! # Miscellaneous pre-requisites for covariant derivatives @@ -14,6 +16,8 @@ TODO: this file should not exist; move everything in here to a proper place -/ +@[expose] public section -- TODO: think if we want to expose all definitions! + section -- Building continuous bilinear maps structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 60d959600f6e59..b1e227b3a80b8a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -3,11 +3,13 @@ Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot, Michael Rothgang -/ -import Mathlib.Geometry.Manifold.BumpFunction -import Mathlib.Geometry.Manifold.MFDeriv.Basic -import Mathlib.Geometry.Manifold.Notation -import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame -import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +module + +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.MFDeriv.Basic +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! # The tensoriality criterion @@ -17,6 +19,8 @@ open Bundle Filter Function Topology Module open scoped Bundle Manifold ContDiff +@[expose] public section -- TODO: think if we want to expose all definitions! + variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M] @@ -74,7 +78,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] have h₁ : MDiffAt (fun x' : M ↦ (0 : ℝ)) x := mdifferentiableAt_const rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl] rw [φ_smul] - simp + · simp · exact h₁ -- TODO: add mdifferentiable_zeroSection and/or use it! apply (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero From 0bc103b9a3c8c69da10106d22cdb8168e3787109 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 17:00:13 +0100 Subject: [PATCH 407/601] chore: cherry-pick elaborator state as of 30463 --- Mathlib/Geometry/Manifold/Notation.lean | 266 ++++++++++++++++++------ 1 file changed, 198 insertions(+), 68 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index b4d7f88323e612..a6a77f63d73a7d 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -42,10 +42,13 @@ In each of these cases, the models with corners are inferred from the domain and The search for models with corners uses the local context and is (almost) only based on expression structure, hence hopefully fast enough to always run. -This has no dedicated support for product manifolds (or product vector spaces) yet; -adding this is left for future changes. (It would need to make a choice between e.g. the +Inferring models with corners supports all current `ModelWithCorners` instances in mathlib. +This will need to be updated as new instances are added. + +For products of manifolds, we explicitly track if the resulting space is a product of normed spaces: +that case is ambiguous, and the elaborators would need to make a choice between e.g. the trivial model with corners on a product `E × F` and the product of the trivial models on `E` and -`F`). In these settings, the elaborators should be avoided (for now). +`F`). If we encounter such an ambiguity, we warn about it and do not infer a model with corners. ## `T%` @@ -70,19 +73,18 @@ variable {s : E → E'} in These elaborators can be combined: `CMDiffAt[u] n (T% s) x` -**Warning.** These elaborators are a proof of concept; the implementation should be considered a -prototype. Don't rewrite all of mathlib to use it just yet. Notable limitations include -the following. - ## TODO -- extend the elaborators to guess models with corners on product manifolds - (this has to make a guess, hence cannot always be correct: but it could make the guess that - is correct 90% of the time). - For products of vector spaces `E × F`, this could print a warning about making a choice between - the model in `E × F` and the product of the models on `E` and `F`. -- better error messages (as needed), with tests -- further testing and fixing of edge cases (with tests) -- add delaborators for these elaborators + +* try an opinionated strategy on products of normed spaces: + is one guess correct more often than the other? +* alternatively, can the elaborator generate two `Try this` suggestions, corresponding to the + possible options? +* add delaborators for these elaborators +* add elaborators for more notation +* make the model finding extensible, by converting it to an environment extension + +If you would like to work on any of these, please coordinate with Michael Rothgang (@grunweg) +to avoid duplicating or conflicting work. -/ @@ -205,8 +207,60 @@ scoped elab:max "T% " t:term:arg : term => do namespace Elab -/-- Try a strategy `x : TermElabM` which either successfully produces some `Expr` or fails. On -failure in `x`, exceptions are caught, traced (`trace.Elab.DiffGeo.MDiff`), and `none` is +/-- Check if an expression `e` is a `ContinuousLinearMap` over an identity ring homomorphism where +the coefficient rings of the domain and codomain are reducibly definitionally equal. If so, we +return `(k, E, F)`, where `k` is the coefficient ring, `E` is the domain, and `F` is the codomain +of the continuous linear maps. Otherwise, we error. +Assumes that `e` is already in `whnf` and has had metavariables instantiated. -/ +private def isCLMReduciblyDefeqCoefficients (e : Expr) : TermElabM <| Expr × Expr × Expr := do + match_expr e with + | ContinuousLinearMap k S _ _ σ E _ _ F _ _ _ _ => + trace[Elab.DiffGeo.MDiff] "`{e}` is a space of continuous (semi-)linear maps" + unless ← withReducible <| pureIsDefEq k S do + throwError "Coefficients `{k}` and `{S}` of `{e}` are not reducibly definitionally equal" + match_expr ← whnfR σ with + | RingHom.id _ _ => return (k, E, F) + | _ => throwError "`{e}` is a space of continuous (semi-)linear maps over `{σ}`, \ + which is not the identity" + | _ => throwError "`{e}` is not a space of continuous linear maps" + +/-- +Captures information when a model with corners is the trivial model on a normed space +(or on an inner product space, which is also a normed space): +contains the expressions describing the normed space and its base field. + +Searching for a model with corners will return an `Option NormedSpaceInfo`, +which is `some` if and only if the trivial model on a normed space was found. +-/ +structure NormedSpaceInfo where + /-- The expression for the normed space itself. -/ + normedSpace : Expr + /-- The expression for the normed space's base field. -/ + baseField : Expr +deriving Inhabited + +/-- +Information about a model with corners found through `findModelInner`. +It includes the model with corners found, and, if this model is the trivial model with corners on a +normed space, information about that normed space. (Knowing this is important for forming products +of models.) + +Most search results are not a model with corners for a normed space, so an `Expr` representing the +model with corners may be coerced directly to this type. +-/ +structure FindModelResult where + /-- Expression describing the model with corners found. -/ + model : Expr + /-- Information on the underlying normed space, + if this model is the trivial model with corners on a normed space. -/ + normedSpaceInfo? : Option NormedSpaceInfo := none +deriving Inhabited + +instance : Coe Expr FindModelResult where + coe model := { model } + +/-- Try a strategy `x : TermElabM` which either successfully finds a `ModelWithCorners` or fails. +On failure in `x`, exceptions are caught, traced (`trace.Elab.DiffGeo.MDiff`), and `none` is successfully returned. We run `x` with `errToSorry == false` to convert elaboration errors into @@ -215,8 +269,8 @@ be caught. Trace messages produced during the execution of `x` are wrapped in a collapsible trace node titled with `strategyDescr` and an indicator of success. -/ -private def tryStrategy (strategyDescr : MessageData) (x : TermElabM Expr) : - TermElabM (Option Expr) := do +private def tryStrategy (strategyDescr : MessageData) (x : TermElabM FindModelResult) : + TermElabM (Option FindModelResult) := do let s ← saveState try withTraceNode `Elab.DiffGeo.MDiff (fun e => pure m!"{e.emoji} {strategyDescr}") do @@ -228,7 +282,10 @@ private def tryStrategy (strategyDescr : MessageData) (x : TermElabM Expr) : catch ex => trace[Elab.DiffGeo.MDiff] "Failed with error:\n{ex.toMessageData}" throw ex - trace[Elab.DiffGeo.MDiff] "Found model: `{e}`" + trace[Elab.DiffGeo.MDiff] "Found model: `{e.model}`" + if let some { normedSpace, baseField } := e.normedSpaceInfo? then + trace[Elab.DiffGeo.MDiff] "This is the trivial model with corners for the normed space \ + `{normedSpace}` over the base field `{baseField}`." return e catch _ => -- Restore infotrees to prevent any stale hovers, code actions, etc. @@ -236,24 +293,6 @@ private def tryStrategy (strategyDescr : MessageData) (x : TermElabM Expr) : s.restore true return none -/-- Check if an expression `e` is a `ContinuousLinearMap` over an identity ring homomorphism where -the coefficient rings of the domain and codomain are reducibly definitionally equal. If so, we -return `(k, E, F)`, where `k` is the coefficient ring, `E` is the domain, and `F` is the codomain -of the continuous linear maps. Otherwise, we error. - -Assumes that `e` is already in `whnf` and has had metavariables instantiated. -/ -private def isCLMReduciblyDefeqCoefficients (e : Expr) : TermElabM <| Expr × Expr × Expr := do - match_expr e with - | ContinuousLinearMap k S _ _ σ E _ _ F _ _ _ _ => - trace[Elab.DiffGeo.MDiff] "`{e}` is a space of continuous (semi-)linear maps" - unless ← withReducible <| pureIsDefEq k S do - throwError "Coefficients `{k}` and `{S}` of `{e}` are not reducibly definitionally equal" - match_expr ← whnfR σ with - | RingHom.id _ _ => return (k, E, F) - | _ => throwError "`{e}` is a space of continuous (semi-)linear maps over `{σ}`, \ - which is not the identity" - | _ => throwError "`{e}` is not a space of continuous linear maps" - set_option linter.style.emptyLine false in -- linter false positive /-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), using the local context to infer the appropriate instance. This supports the following cases: @@ -271,8 +310,12 @@ using the local context to infer the appropriate instance. This supports the fol and if successful, return `𝓘(𝕜)`. Further cases can be added as necessary. +This method intentionally handles **neither** sums (disjoint unions) nor products of spaces, +nor an open subset of an existing manifold. These are handled in `findModel`. -Return an expression describing the found model with corners. +Return an expression describing the found model with corners, together with information about +whether the model is the trivial model with corners on a normed space. (This is important for +forming products of models.) `baseInfo` is only used for the first case, a model with corners on the total space of the vector bundle. In this case, it contains a pair of expressions `(e, i)` describing the type of the base @@ -287,34 +330,30 @@ This implementation is not maximally robust yet. -/ -- TODO: better error messages when all strategies fail -- TODO: consider lowering monad to `MetaM` -def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do - trace[Elab.DiffGeo.MDiff] "Finding a model for: {e}" - if let some m ← tryStrategy m!"TotalSpace" fromTotalSpace then return m - if let some m ← tryStrategy m!"TangentBundle" fromTangentBundle then return m - if let some m ← tryStrategy m!"NormedSpace" fromNormedSpace then return m - if let some m ← tryStrategy m!"Manifold" fromManifold then return m - if let some m ← tryStrategy m!"ContinuousLinearMap" fromCLM then return m - if let some m ← tryStrategy m!"RealInterval" fromRealInterval then return m - if let some m ← tryStrategy m!"EuclideanSpace" fromEuclideanSpace then return m - if let some m ← tryStrategy m!"UpperHalfPlane" fromUpperHalfPlane then return m - if let some m ← tryStrategy m!"Units of algebra" fromUnitsOfAlgebra then return m - if let some m ← tryStrategy m!"Complex unit circle" fromCircle then return m - if let some m ← tryStrategy m!"Sphere" fromSphere then return m - if let some m ← tryStrategy m!"NormedField" fromNormedField then return m - if let some m ← tryStrategy m!"InnerProductSpace" fromInnerProductSpace then return m - if ← isTracingEnabledFor `Elab.DiffGeo.MDiff then - throwError m!"Could not find a model with corners for `{e}`." - else - throwError m!"Could not find a model with corners for `{e}`. - -Hint: failures to find a model with corners can be debugged with the command \ -`set_option trace.Elab.DiffGeo.MDiff true`." +def findModelInner (e : Expr) (baseInfo : Option (Expr × Expr) := none) : + TermElabM (Option FindModelResult) := do + if let some m ← tryStrategy "TotalSpace" fromTotalSpace then return some m + if let some m ← tryStrategy "TangentBundle" fromTangentBundle then return some m + if let some m ← tryStrategy "NormedSpace" fromNormedSpace then return some m + if let some m ← tryStrategy "Manifold" fromManifold then return some m + if let some m ← tryStrategy "ContinuousLinearMap" fromCLM then return some m + if let some m ← tryStrategy "RealInterval" fromRealInterval then return some m + if let some m ← tryStrategy "EuclideanSpace" fromEuclideanSpace then return some m + if let some m ← tryStrategy "UpperHalfPlane" fromUpperHalfPlane then return some m + if let some m ← tryStrategy "Units of algebra" fromUnitsOfAlgebra then return some m + if let some m ← tryStrategy "Complex unit circle" fromCircle then return some m + if let some m ← tryStrategy "Sphere" fromSphere then return some m + if let some m ← tryStrategy "NormedField" fromNormedField then return some m + -- We run this strategy last, as it is the least likely to succeed. + -- More commonly, we have a normed space on the nose, and `fromNormedSpace` should succeed. + if let some m ← tryStrategy "InnerProductSpace" fromInnerProductSpace then return some m + return none where /- Note that errors thrown in the following are caught by `tryStrategy` and converted to trace messages. -/ /-- Attempt to find a model from a `TotalSpace` first by attempting to use any provided `baseInfo`, then by seeing if it is the total space of a tangent bundle. -/ - fromTotalSpace : TermElabM Expr := do + fromTotalSpace : TermElabM FindModelResult := do match_expr e with | Bundle.TotalSpace _ F V => do if let some m ← tryStrategy m!"From base info" (fromTotalSpace.fromBaseInfo F) then return m @@ -359,7 +398,7 @@ where Term.elabTerm resTerm none | _ => throwError "`{e}` is not a `TangentBundle`" /-- Attempt to find the trivial model on a normed space. -/ - fromNormedSpace : TermElabM Expr := do + fromNormedSpace : TermElabM FindModelResult := do let some (inst, K) ← findSomeLocalInstanceOf? ``NormedSpace fun inst type ↦ do match_expr type with | NormedSpace K E _ _ => @@ -368,9 +407,12 @@ where | _ => return none | throwError "Couldn't find a `NormedSpace` structure on `{e}` among local instances." trace[Elab.DiffGeo.MDiff] "`{e}` is a normed space over the field `{K}`" - mkAppOptM ``modelWithCornersSelf #[K, none, e, none, inst] + return { + model := ← mkAppOptM ``modelWithCornersSelf #[K, none, e, none, inst] + normedSpaceInfo? := some { normedSpace := e, baseField := K } + } /-- Attempt to find the trivial model on an inner product space. -/ - fromInnerProductSpace : TermElabM Expr := do + fromInnerProductSpace : TermElabM FindModelResult := do let some (inst, K) ← findSomeLocalInstanceOf? `InnerProductSpace fun inst type ↦ do -- We don't use `match_expr` here to avoid importing `InnerProductSpace`. match (← instantiateMVars type).cleanupAnnotations with @@ -382,7 +424,10 @@ where trace[Elab.DiffGeo.MDiff] "`{e}` is an inner product space over the field `{K}`" -- Convert the InnerProductSpace to a NormedSpace instance. let inst' ← mkAppOptM `InnerProductSpace.toNormedSpace #[K, e, none, none, inst] - mkAppOptM ``modelWithCornersSelf #[K, none, e, none, inst'] + return { + model := ← mkAppOptM ``modelWithCornersSelf #[K, none, e, none, inst'] + normedSpaceInfo? := some { normedSpace := e, baseField := K } + } /-- Attempt to find a model with corners on a manifold, or on the charted space of a manifold. -/ fromManifold : TermElabM Expr := do -- Return an expression for a type `H` (if any) such that `e` is a ChartedSpace over `H`, @@ -501,7 +546,7 @@ where -- so it suffices to check at reducible transparency. if ← withReducible <| isDefEq V W then trace[Elab.DiffGeo.MDiff] "`{α}` is a space of continuous `{k}`-linear maps on `{V}`" - let searchNormedSpace := findSomeLocalInstanceOf? ``NormedSpace fun inst type ↦ do + let normedSpace? ← findSomeLocalInstanceOf? ``NormedSpace fun inst type ↦ do trace[Elab.DiffGeo.MDiff] "considering instances of type `{type}`" match_expr type with | NormedSpace k R _ _ => @@ -512,7 +557,7 @@ where return some (k, R) else return none | _ => return none - match ← searchNormedSpace with + match normedSpace? with | some (k, _R) => trace[Elab.DiffGeo.MDiff] "found a normed space: `{V}` is a normed space over `{k}`" let eK : Term ← Term.exprToSyntax k @@ -611,6 +656,91 @@ where let iTerm : Term ← ``(𝓘($eT, $eT)) Term.elabTerm iTerm none +set_option linter.style.emptyLine false in -- linter false positive +/-- Try to find a `ModelWithCorners` instance on a type (represented by an expression `e`), +using the local context to infer the appropriate instance. +TODO not yet: This supports all `ModelWithCorners` +instances that are currently defined in mathlib. Further cases can be added as necessary. + +Return an expression describing the found model with corners. + +`baseInfo` is only used for the first case, a model with corners on the total space of the vector +bundle. In this case, it contains a pair of expressions `(e, i)` describing the type of the base +and the model with corners on the base: these are required to construct the right model with +corners. + +Note that the matching on `e` does not see through reducibility (e.g. we distinguish the `abbrev` +`TangentBundle` from its definition), so `whnfR` should not be run on `e` prior to calling +`findModel` on it. + +This implementation is not maximally robust yet. +-/ +-- TODO: better error messages when all strategies fail +-- TODO: consider lowering monad to `MetaM` + +-- This function calls itself, which is why it is partial for now. +-- This should not be an issue in practice. +-- FIXME: can one prove this terminates w.r.t. a suitable measure? This is only recursing into +-- subexpressions (at least, after match_expr), right? +partial def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do + trace[Elab.DiffGeo.MDiff] "Finding a model with corners for: `{e}`" + if let some { model .. } ← go e baseInfo then + return model + else + let hint := if (← isTracingEnabledFor `Elab.DiffGeo.MDiff) then m!"" else + .hint' "failures to find a model with corners can be debugged with the \ + command `set_option trace.Elab.DiffGeo.MDiff true`." + throwError "Could not find a model with corners for `{e}`.{hint}" +where + go (e : Expr) (baseInfo : Option (Expr × Expr)) : TermElabM (Option FindModelResult) := do + -- At first, try finding a model with corners on the space itself. + if let some m ← findModelInner e baseInfo then return some m + -- Otherwise, we recurse into the expression, + -- depending whether we have an open subset of a space, a product, or a direct sum of spaces. + match_expr e with + -- Check if `e` is an open subset of `M`, i.e. a `TopologicalSpace.Opens`. + -- Because `e` is the result of coercing an actual `s : TopologicalSpace.Opens M` to a `Sort` + -- via `Subtype`, the resulting expression `e` has a somewhat complicated form: + -- `Subtype fun (x : M) => x ∈ s`. + | Subtype _M p => + match (← instantiateMVars p).cleanupAnnotations with + | .lam _x _ body _ => + match_expr body with + | Membership.mem _ sType inst _ b => + unless b matches .bvar 0 do return none + match_expr inst with + | SetLike.instMembership _ _ _ => + match_expr sType with + | TopologicalSpace.Opens M _ => + trace[Elab.DiffGeo.MDiff] "`{e}` is an open set of `{M}`, finding a model on `{M}`" + -- `M` is not a open set of another manifold, as `Opens X` is (currently) not a + -- topological space (and this would be strange). Therefore, do not recurse into `M`. + go M baseInfo + | _ => return none + | _ => return none + | _ => return none + | _ => return none + | Prod E F => + trace[Elab.DiffGeo.MDiff] "Expression `{e}` is a product, recursing into each factor" + let some { model := srcE, normedSpaceInfo? := normedSpaceE } ← go E baseInfo + | throwError "Found no model with corners on first factor `{E}`" + let some { model := srcF, normedSpaceInfo? := normedSpaceF } ← go F baseInfo + | throwError "Found no model with corners on second factor `{F}`" + -- If both E and F are normed spaces, we have ambiguity: warn and exit. + if normedSpaceE.isSome && normedSpaceF.isSome then + throwError "`{e}` is a product of normed spaces, so there are two potential models with \ + corners\nFor now, please specify the model by hand." + -- Otherwise, we are not a normed space, and normally form the product model. + let eTerm : Term ← Term.exprToSyntax srcE + let fTerm : Term ← Term.exprToSyntax srcF + let iTerm : Term ← ``(ModelWithCorners.prod $eTerm $fTerm) + return some { model := ← Term.elabTerm iTerm none } + | Sum E F => + trace[Elab.DiffGeo.MDiff] "Expression `{e}` is a direct sum of `{E}` and `{F}`\n\ + We assume the models match, and only look into the first summand" + go E baseInfo + | _ => return none + /-- If the type of `e` is a non-dependent function between spaces `src` and `tgt`, try to find a model with corners on both `src` and `tgt`. If successful, return both models. From 7dadbfdc3e1a18b78e143e3982a190b5e2c1b188 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 17:22:29 +0100 Subject: [PATCH 408/601] Fix three proofs --- .../VectorBundle/CovariantDerivative/Basic.lean | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index ac590d944e4546..b3265575def734 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -452,10 +452,9 @@ lemma zeroX (hf : IsCovariantDerivativeOn F f s) {x : M} (hx : x ∈ s := by trivial) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : f 0 σ x = 0 := by -- TODO: writing MDiffAt here yields an error! - have : MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (T% (fun x ↦ (0 : TangentSpace I x))) x := by - apply ContMDiff.mdifferentiableAt (n := 1) --(le_refl 1) - swap; · simp_all - sorry -- zero section is smooth! + have : MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (T% (fun x ↦ (0 : TangentSpace I x))) x := + -- TODO: add mdifferentiable{,At}_zeroSection + (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero simpa using IsCovariantDerivativeOn.addX f hf (X := 0) this this hσ @[simp] @@ -492,8 +491,8 @@ def convexCombination {f' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : IsCovariantDerivativeOn F (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where - addX {_X _X' _σ} _ hx hX hX' hσ := by sorry -- simp [hf.addX, hf'.addX]; module - smulX {_X _σ _φ} _ hx hX hσ hφ := by sorry -- simp [hf.smulX, hf'.smulX]; module + addX {X X' σ} x hX hX' hσ hx := by simp [hf.addX hX hX' hσ, hf'.addX hX hX' hσ]; module + smulX {_X _σ _φ} x hX hσ hφ hx := by simp [hf.smulX hX hσ hφ, hf'.smulX hX hσ hφ]; module addσ {_X _σ _σ' x} hX hσ hσ' hx := by simp [hf.addσ hX hσ hσ', hf'.addσ hX hσ hσ'] module From 7cf8cb23de7d4460e2779dfc4ea7667ec1d21eb5 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Sun, 22 Feb 2026 17:56:15 +0100 Subject: [PATCH 409/601] Missing module --- .../Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean index 93f1e495a30f9d..5dac18d1b9c710 100644 --- a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean +++ b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean @@ -3,6 +3,8 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Michael Rothgang -/ +module + import Mathlib.Geometry.Manifold.PartitionOfUnity import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame import Mathlib.Geometry.Manifold.VectorBundle.Riemannian From dc41b5b47b316c7c5777ce3ba72f9bba89100619 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Sun, 22 Feb 2026 17:29:56 +0100 Subject: [PATCH 410/601] Resume work on projections --- .../CovariantDerivative/Basic.lean | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index b3265575def734..e3c7b30348de41 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1122,6 +1122,7 @@ noncomputable def Trivialization.covDeriv (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (x : M) : V x := e.symm x (mfderiv I 𝓘(ℝ, F) (fun x' ↦ (e (σ x')).2) x (X x)) +-- The following is probably not on the critical path lemma Trivialization.covDeriv_isCovariantDerivativeOn [IsManifold I 1 M] : IsCovariantDerivativeOn (I := I) F e.covDeriv e.baseSet where addX {_X _X' _σ _x} hX hX' hσ hx := by sorry @@ -1132,15 +1133,49 @@ lemma Trivialization.covDeriv_isCovariantDerivativeOn [IsManifold I 1 M] : end from_trivialization +section to_trivialization + +variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] + +noncomputable +def Trivialization.pushCovDer + (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) : + (Π x : M, TangentSpace I x) → (M → F) → (M → F) := + fun X σ x ↦ e (cov X (fun x' ↦ e.symm x' <| σ x') x) |>.2 + +variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + +lemma Trivialization.pushCovDer_isCovariantDerivativeOn + (hcov : IsCovariantDerivativeOn F cov e.baseSet) : + IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := + sorry +end to_trivialization section horiz namespace CovariantDerivative -variable [IsManifold I 1 M] +variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + [VectorBundle ℝ F V] + +local notation "TM" => TangentSpace I +-- FIXME the statement of CovariantDerivative.isCovariantDerivativeOn should work on any set + +-- Note: The definition below (ab)uses definitional +-- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` +-- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` +-- which is $T_{π(v)} M × F$. +noncomputable def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := by - sorry + TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + letI tproj := d_covDerOn.projection v.proj (t v).2 + letI Tvt := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t v + t.symmL ℝ v.proj |>.comp <| tproj.comp Tvt noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := From 64f28cb21e268bd92d1e5a146a833c91ea1dfc77 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Sun, 22 Feb 2026 22:08:55 +0100 Subject: [PATCH 411/601] Horizontal and vertical bundle are complementary --- .../CovariantDerivative/Basic.lean | 80 ++++++++++++++++--- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index e3c7b30348de41..6795778cf3a62d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1137,6 +1137,35 @@ section to_trivialization variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] +-- Note: The definition below (ab)uses definitional +-- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` +-- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` +-- which is $T_{π(v)} M × F$. +variable (I) in +noncomputable +def Trivialization.derivEquiv (v : TotalSpace F V) : + TangentSpace (I.prod 𝓘(ℝ, F)) v ≃L[ℝ] TangentSpace I v.proj × F where + toFun := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v + map_add' := by simp + map_smul' := by simp + invFun := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (e v) + left_inv := sorry + right_inv := sorry + continuous_toFun := ContinuousLinearMap.continuous _ + continuous_invFun := ContinuousLinearMap.continuous _ + +noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := + (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker + +lemma Trivialization.comap_vert (v : TotalSpace F V) (hv : v.proj ∈ e.baseSet) : + Bundle.vert v = Submodule.comap (e.derivEquiv I v).toLinearMap + (Submodule.prod ⊥ ⊤) := by + ext x + simp [vert] + sorry + + noncomputable def Trivialization.pushCovDer (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) : @@ -1163,10 +1192,6 @@ local notation "TM" => TangentSpace I -- FIXME the statement of CovariantDerivative.isCovariantDerivativeOn should work on any set --- Note: The definition below (ab)uses definitional --- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` --- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` --- which is $T_{π(v)} M × F$. noncomputable def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := @@ -1174,20 +1199,55 @@ def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) letI tproj := d_covDerOn.projection v.proj (t v).2 - letI Tvt := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t v - t.symmL ℝ v.proj |>.comp <| tproj.comp Tvt + letI Tvt := t.derivEquiv I v + t.symmL ℝ v.proj ∘L tproj ∘L Tvt.toContinuousLinearMap noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (cov.proj v).ker -noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := - (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker +lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + horiz cov v = Submodule.comap (t.derivEquiv I v).toLinearMap + (d_covDerOn.horiz v.proj (t v).2) := by + -- FIXME: needing all those lets and the change is awful + let t := trivializationAt F V v.proj + let Tvt := t.derivEquiv I v + have hcov := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + let tproj := hcov.projection v.proj (t v).2 + let t' := t.continuousLinearEquivAt ℝ v.proj (mem_baseSet_trivializationAt F V v.proj) + ext u + change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 + simp + +lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} + [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] + {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] + [AddCommMonoid M₂] [Module R₂ M₂] + (f : M ≃ₛₗ[σ₁₂] M₂) {p q : Submodule R₂ M₂} (h : IsCompl p q) : + IsCompl (Submodule.comap f.toLinearMap p) (Submodule.comap f.toLinearMap q) := by + rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * + constructor + · rw [← Submodule.comap_inf, h.1] + simp + · rw [← Submodule.comap_sup_of_injective, h.2] + · exact Submodule.comap_top f.toLinearMap + · exact f.injective + · simp + · simp lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (v : TotalSpace F V) : IsCompl (cov.horiz v) (vert v) := by - sorry + let t := trivializationAt F V v.proj + let Tvt := t.derivEquiv I v + have hcov := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + rw [t.comap_vert _ (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] + apply LinearEquiv.comap_isCompl + apply hcov.horiz_vert_direct_sum variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} From 063ebeba5c87547bbbc16cd116989e74fe13e4ba Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 22 Feb 2026 22:51:12 +0100 Subject: [PATCH 412/601] chore: fill a few more sorries; correct local existence statements for projection --- .../CovariantDerivative/Basic.lean | 94 +++++++++---------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 6795778cf3a62d..198269213931c9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -473,10 +473,8 @@ lemma sum_X (hf : IsCovariantDerivativeOn F f s) induction u using Finset.induction_on with | empty => simp [hf.zeroX hx hσ] | insert a u ha h => - have : MDiffAt (T% (∑ i ∈ u, X i)) x := sorry - simp [Finset.sum_insert ha, ← h] -- hf.addX (hX a) this hσ hx] - have := hf.addX (hX a) this hσ hx - sorry -- simp only [hf.addX (hX a) this hσ hx] + have : MDiffAt (T% (∑ i ∈ u, X i)) x := by simpa using MDifferentiableAt.sum_section (s := u) hX + simp [Finset.sum_insert ha, ← h, hf.addX (hX a) this hσ hx] end computational_properties @@ -687,23 +685,23 @@ lemma contMDiffCovariantDerivativeOn_univ_iff {cov : CovariantDerivative I F V} section computational_properties @[simp] -lemma zeroX (cov : CovariantDerivative I F V) (σ : Π x : M, V x) : cov 0 σ = 0 := by +lemma zeroX (cov : CovariantDerivative I F V) {σ : Π x : M, V x} (hσ : MDiff (T% σ)) : + cov 0 σ = 0 := by ext x - apply cov.isCovariantDerivativeOn.zeroX - sorry + exact cov.isCovariantDerivativeOn.zeroX (by trivial) (hσ x) @[simp] lemma zeroσ [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) - (X : Π x : M, TangentSpace I x) : cov X 0 = 0 := by + {X : Π x : M, TangentSpace I x} (hX : MDiff (T% X)) : cov X 0 = 0 := by ext x - apply cov.isCovariantDerivativeOn.zeroσ - sorry -- misisng hypothesis! + exact cov.isCovariantDerivativeOn.zeroσ (hX x) lemma sum_X (cov : CovariantDerivative I F V) - {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} : + {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} + (hX : ∀ i, MDiff (T% (X i))) (hσ : MDiff (T% σ)): cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by ext x - sorry -- simpa using cov.isCovariantDerivativeOn.sum_X + simpa using cov.isCovariantDerivativeOn.sum_X trivial (fun i ↦ hX i x) (hσ x) end computational_properties @@ -888,8 +886,8 @@ lemma differenceAux_smul_eq' (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) : differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by - sorry -- TODO: need extra smoothness hypotheses! - -- simp [differenceAux, hcov.smulX, hcov'.smulX, smul_sub] + sorry -- TODO: need to assume X, σ and f are differentiable! + -- simp only [differenceAux, Pi.apply, hcov.smulX, hcov'.smulX, smul_sub] /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial @@ -899,6 +897,7 @@ lemma differenceAux_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} + (hX : MDiffAt (T% X) x₀) -- TODO: is this hypotheses truly necessary? (hX' : MDiffAt (T% X') x₀) (hσ : MDiffAt (T% σ) x₀) (hσ' : MDiffAt (T% σ') x₀) @@ -907,13 +906,14 @@ lemma differenceAux_tensorial trans differenceAux cov cov' X' σ x₀ · let φ : (Π x : M, TangentSpace I x) → (Π x, V x) := fun X ↦ differenceAux cov cov' X σ change φ X x₀ = φ X' x₀ - apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' - · intro f X - apply hcov.differenceAux_smul_eq' hcov' - · intro X X' + -- TODO: is there a version of `tensoriality_criterion` which does not require `hX`? + apply tensoriality_criterion (E := E) (I := I) E (TangentSpace I) F V hX hX' hXX' + · intro f X hf hX + exact hcov.differenceAux_smul_eq' hcov' .. + · intro X X' hX hX' unfold φ differenceAux - sorry --simp only [Pi.sub_apply, hcov.addX, hcov'.addX] - --abel + simp only [Pi.sub_apply, hcov.addX hX hX' hσ, hcov'.addX hX hX' hσ] + abel · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ differenceAux cov cov' X' σ change φ σ x₀ = φ σ' x₀ apply tensoriality_criterion (E := E) (I := I) F V F V hσ hσ' hσσ' @@ -933,25 +933,21 @@ lemma isBilinearMap_differenceAux IsBilinearMap ℝ (fun (X₀ : TangentSpace I x) (σ₀ : V x) ↦ differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x) where add_left u v w := by - sorry --simp only [differenceAux, extend_add, Pi.sub_apply, hcov.addX, hcov'.addX] - --abel + simp only [differenceAux, extend_add, Pi.sub_apply] + rw [hcov.addX, hcov'.addX]; · abel + all_goals apply mdifferentiable_extend add_right u v w := by - have hv := mdifferentiable_extend I F v x - have hw := mdifferentiable_extend I F w x simp only [differenceAux, extend_add, Pi.sub_apply] - rw [hcov.addσ _ hv hw, hcov'.addσ _ hv hw] - abel - repeat sorry -- missing smoothness hypotheses + rw [hcov.addσ, hcov'.addσ]; · abel + all_goals apply mdifferentiable_extend smul_left a u v := by - unfold differenceAux - -- need extra smoothness hypotheses! - -- simp only [extend_smul, Pi.sub_apply, hcov.smul_const_X, hcov'.smul_const_X] - sorry -- module + simp only [differenceAux, extend_smul, Pi.sub_apply] + rw [hcov.smul_const_X, hcov'.smul_const_X]; · module + all_goals apply mdifferentiable_extend smul_right a u v := by - unfold differenceAux - -- need extra smoothness hypotheses! - sorry -- simp only [extend_smul, Pi.sub_apply, hcov.smul_const_σ, hcov'.smul_const_σ] - -- module + simp only [differenceAux, extend_smul, Pi.sub_apply] + rw [hcov.smul_const_σ, hcov'.smul_const_σ]; · module + all_goals apply mdifferentiable_extend variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -995,8 +991,8 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x difference hcov hcov' x (X x) (σ x) = cov X σ x - cov' X σ x := by simp only [difference, hx, reduceDIte] - exact hcov.differenceAux_tensorial hcov' hX (mdifferentiable_extend ..) hσ (extend_apply_self _) - (extend_apply_self _) hx + exact hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hX + (mdifferentiable_extend ..) hσ (extend_apply_self _) (extend_apply_self _) hx -- The classification of real connections over a trivial bundle section classification @@ -1010,15 +1006,13 @@ lemma exists_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x ∈ s, - MDiffAt (T% σ) x → + MDiffAt (T% X) x → MDiffAt (T% σ) x → letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) cov X σ x = d + A x (X x) (σ x) := by use fun x ↦ hcov.difference (trivial I M F |>.mono <| subset_univ s) x - intro X σ x hx hσ - rw [difference_apply] - · module - · sorry -- TODO: missing smoothness hypothesis, right? - · assumption + intro X σ x hx hX hσ + rw [hcov.difference_apply _ (by trivial) hX hσ] + module noncomputable def one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : @@ -1028,16 +1022,16 @@ noncomputable def one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → lemma eq_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {X : (x : M) → TangentSpace I x} {σ : M → F} - {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + {x : M} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) cov X σ x = d + hcov.one_form x (X x) (σ x) := - hcov.exists_one_form.choose_spec X σ x hx hσ + hcov.exists_one_form.choose_spec X σ x hx hX hσ lemma _root_.CovariantDerivative.exists_one_form (cov : CovariantDerivative I F (Bundle.Trivial M F)) : ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x, - MDiffAt (T% σ) x → + MDiffAt (T% X) x → MDiffAt (T% σ) x → letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) cov X σ x = d + A x (X x) (σ x) := by simpa using cov.isCovariantDerivativeOn.exists_one_form @@ -1065,9 +1059,9 @@ lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) hcov.projection x f (v, w) = w + hcov.one_form x v f := rfl lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (X : Π x : M, TM x) (σ : M → F) - {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + {x : M} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : cov X σ x = hcov.projection x (σ x) (X x, mfderiv I 𝓘(ℝ, F) σ x (X x)) := by - simpa using hcov.eq_one_form hσ + simpa using hcov.eq_one_form hX hσ noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : Submodule ℝ (TM x × F) := @@ -1102,13 +1096,13 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : simp [hcov.zeroX, mdifferentiableAt_section, mdifferentiableAt_const] rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ use map_of_one_jet u w, ?_, h, h'' - · rw [hcov.eq_one_form] + · rw [hcov.eq_one_form (mdifferentiable_extend ..)] · simp [w, h'', h, huv] · rwa [mdifferentiableAt_section] · rwa [mdifferentiableAt_section] · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covσ] - rw [hcov.eq_one_form σ_diff, extend_apply_self] + rw [hcov.eq_one_form (mdifferentiable_extend ..) σ_diff, extend_apply_self] end projection_trivial_bundle From 77a61d9b1867ac404e0a2d39ed11b773846a29f1 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 23 Feb 2026 14:12:59 +0100 Subject: [PATCH 413/601] Progress on projection --- .../CovariantDerivative/Basic.lean | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 198269213931c9..a5ec633db5a8b0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -843,6 +843,14 @@ lemma congr_X_at [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [Vec rw [hcov.addX] all_goals sorry +lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] + {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} (hxu : s ∈ 𝓝 x) + (hσσ' : ∀ x ∈ s, σ x = σ' x) : + cov X σ x = cov X σ' x := by + sorry -- Note there is a commented out version of this lemma at the bottom + -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. @@ -1159,6 +1167,19 @@ lemma Trivialization.comap_vert (v : TotalSpace F V) (hv : v.proj ∈ e.baseSet) simp [vert] sorry +-- FIXME: is this really missing?? +lemma Trivialization.eq_of {x : M} {v v' : V x} + (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : + v = v' := by + have := e.symm_proj_apply v hx + rw [hvv'] at this + grind [e.symm_proj_apply v' hx] + +lemma Trivialization.derivEquiv_mfderiv {σ : Π x : M, V x} (hσ : MDiffAt T%σ x) + (u : TangentSpace I x) (v : V x) : + letI s := fun x ↦ (e (σ x)).2 + e.derivEquiv I v ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by + sorry noncomputable def Trivialization.pushCovDer @@ -1166,6 +1187,21 @@ def Trivialization.pushCovDer (Π x : M, TangentSpace I x) → (M → F) → (M → F) := fun X σ x ↦ e (cov X (fun x' ↦ e.symm x' <| σ x') x) |>.2 +lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + [VectorBundle ℝ F V] + {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + (hcov : IsCovariantDerivativeOn F cov e.baseSet) + (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) {x : M} + (hx : x ∈ e.baseSet := by assumption) : + (e.pushCovDer cov) X (fun x ↦ (e (σ x)).2) x = (e (cov X σ x)).2 := by + have : cov X (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov X σ x := by + apply hcov.congr_σ_of_eqOn + · exact e.open_baseSet.mem_nhds_iff.mpr hx + · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? + unfold pushCovDer + rw [this] + variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -1196,6 +1232,17 @@ def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : letI Tvt := t.derivEquiv I v t.symmL ℝ v.proj ∘L tproj ∘L Tvt.toContinuousLinearMap +lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod + 𝓘(ℝ, F)) v) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + letI tproj := d_covDerOn.projection v.proj (t v).2 + letI Tvt := t.derivEquiv I v + (t <| cov.proj v u).2 = tproj (Tvt u) := by + simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] + + noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (cov.proj v).ker @@ -1246,12 +1293,37 @@ lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (v : TotalSpace F variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} -lemma proj_mderiv {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) +lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] + {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) : cov X σ x = cov.proj (σ x) (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x (X x)) := by - sorry + let t := trivializationAt F V x + let s := fun x ↦ (t (σ x)).2 + let Tσx := mfderiv% (T% σ) x + -- FIXME `mfderiv%` fails in next line + let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) + change cov X σ x = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) (X x)) + -- have der_eq : mfderiv% s x = ContinuousLinearMap.snd ℝ _ _ ∘L Ttσx ∘L Tσx := by + -- rw [show s = Prod.snd ∘ t ∘ (T% σ) from rfl] + -- have mdifft : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) := sorry + -- have mdiffsnd : MDifferentiableAt (I.prod 𝓘(ℝ, F)) 𝓘(ℝ, F) Prod.snd (t <| σ x) := + -- mdifferentiableAt_snd + -- rw [mfderiv_comp x mdiffsnd] + -- · rw [mfderiv_comp x mdifft hσ, mfderiv_snd] + -- rfl + -- · exact (mdifft.comp x hσ) + have hcov := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + have hx := mem_baseSet_trivializationAt F V x + have hs : MDiffAt (T% s) x := by + rw [t.mdifferentiableAt_section_iff I σ hx] at hσ + exact (mdifferentiableAt_section I s).mpr hσ + apply t.eq_of hx + rw [cov.snd_triv_proj (T% σ x), + ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) X σ, + hcov.cov_eq_proj X s hX hs, t.derivEquiv_mfderiv hσ] end CovariantDerivative end horiz From f8fa466ea66c0e969b57a74882e1ce52537d20ca Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Mon, 23 Feb 2026 22:52:33 +0100 Subject: [PATCH 414/601] proj_mfderiv modulo Trivialization.pushCovDer_isCovariantDerivativeOn --- .../CovariantDerivative/Basic.lean | 109 ++++++++++++++---- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index a5ec633db5a8b0..91b456bb1546c9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1156,18 +1156,59 @@ def Trivialization.derivEquiv (v : TotalSpace F V) : continuous_toFun := ContinuousLinearMap.continuous _ continuous_invFun := ContinuousLinearMap.continuous _ +variable (I) in +omit [MemTrivializationAtlas e] [IsManifold I 1 M] in +lemma Trivialization.fst_comp_eventuallyEq + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := by + have : TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := by + apply FiberBundle.continuous_proj F V |>.continuousAt + exact e.open_baseSet.mem_nhds_iff.mpr hv + filter_upwards [this] with y hy + exact coe_fst' e hy + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` +open Lean PrettyPrinter Delaborator SubExpr in +@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +lemma Trivialization.mdifferentiableAt + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) (v : V x) : +MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by + have : ⟨x, v⟩ ∈ e.source := (coe_mem_source e).mpr hx + have foo := e.contMDiffOn (IB := I) (n := 1) v this + have := foo.contMDiffAt (e.open_source.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker -lemma Trivialization.comap_vert (v : TotalSpace F V) (hv : v.proj ∈ e.baseSet) : +lemma Trivialization.comap_vert + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : Bundle.vert v = Submodule.comap (e.derivEquiv I v).toLinearMap (Submodule.prod ⊥ ⊤) := by ext x - simp [vert] - sorry + have : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := e.fst_comp_eventuallyEq I hv + unfold vert + rw [← this.mfderiv_eq] + have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := + e.mdifferentiableAt hv _ + rw [mfderiv_comp v mdifferentiableAt_fst mdiffe] + simp + rfl -- FIXME: is this really missing?? +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] + [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [MemTrivializationAtlas e] in lemma Trivialization.eq_of {x : M} {v v' : V x} (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : v = v' := by @@ -1175,11 +1216,38 @@ lemma Trivialization.eq_of {x : M} {v v' : V x} rw [hvv'] at this grind [e.symm_proj_apply v' hx] -lemma Trivialization.derivEquiv_mfderiv {σ : Π x : M, V x} (hσ : MDiffAt T%σ x) - (u : TangentSpace I x) (v : V x) : +lemma Trivialization.derivEquiv_mfderiv + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) + (u : TangentSpace I x) (hx : x ∈ e.baseSet) : letI s := fun x ↦ (e (σ x)).2 - e.derivEquiv I v ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by - sorry + e.derivEquiv I (σ x) ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by + have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e (σ x) := + e.mdifferentiableAt hx _ + have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x = + (derivEquiv I e (σ x)).toContinuousLinearMap ∘L + (mfderiv% T%σ x) := + mfderiv_comp x mdiffe hσ + have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = + e.derivEquiv I (σ x) ((mfderiv% T%σ x) u) := by + rw [this] + rfl + rw [← this] + let s := fun x ↦ (e (σ x)).2 + change mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = (u, mfderiv I 𝓘(ℝ, F) s x u) + -- FIXME extract lemma + have : e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by + have : e.baseSet ∈ 𝓝 x := e.open_baseSet.mem_nhds_iff.mpr hx + filter_upwards [this] with y hy + ext + · exact coe_coe_fst e hy + · simp + rw [this.mfderiv_eq] + erw [mfderiv_prodMk, mfderiv_id] + · change (ContinuousLinearMap.id _ _).prod (mfderiv% s x) u = _ + simp + · apply mdifferentiableAt_id + · exact (mdifferentiableAt_section_iff I e σ hx).mp hσ noncomputable def Trivialization.pushCovDer @@ -1207,8 +1275,13 @@ variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, lemma Trivialization.pushCovDer_isCovariantDerivativeOn (hcov : IsCovariantDerivativeOn F cov e.baseSet) : - IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := - sorry + IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet where + addX := sorry + smulX := sorry + addσ := sorry + leibniz := sorry + smul_const_σ := sorry + end to_trivialization section horiz @@ -1280,13 +1353,14 @@ lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} · simp · simp -lemma horiz_vert_direct_sum (cov : CovariantDerivative I F V) (v : TotalSpace F V) : +lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] + (cov : CovariantDerivative I F V) (v : TotalSpace F V) : IsCompl (cov.horiz v) (vert v) := by let t := trivializationAt F V v.proj let Tvt := t.derivEquiv I v have hcov := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - rw [t.comap_vert _ (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] + rw [t.comap_vert (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] apply LinearEquiv.comap_isCompl apply hcov.horiz_vert_direct_sum @@ -1302,18 +1376,9 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] let t := trivializationAt F V x let s := fun x ↦ (t (σ x)).2 let Tσx := mfderiv% (T% σ) x - -- FIXME `mfderiv%` fails in next line + -- FIXME `mfderiv%` fails in next line (fixed on master?) let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) change cov X σ x = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) (X x)) - -- have der_eq : mfderiv% s x = ContinuousLinearMap.snd ℝ _ _ ∘L Ttσx ∘L Tσx := by - -- rw [show s = Prod.snd ∘ t ∘ (T% σ) from rfl] - -- have mdifft : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) := sorry - -- have mdiffsnd : MDifferentiableAt (I.prod 𝓘(ℝ, F)) 𝓘(ℝ, F) Prod.snd (t <| σ x) := - -- mdifferentiableAt_snd - -- rw [mfderiv_comp x mdiffsnd] - -- · rw [mfderiv_comp x mdifft hσ, mfderiv_snd] - -- rfl - -- · exact (mdifft.comp x hσ) have hcov := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) have hx := mem_baseSet_trivializationAt F V x @@ -1323,7 +1388,7 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] apply t.eq_of hx rw [cov.snd_triv_proj (T% σ x), ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) X σ, - hcov.cov_eq_proj X s hX hs, t.derivEquiv_mfderiv hσ] + hcov.cov_eq_proj X s hX hs, t.derivEquiv_mfderiv hσ _ hx] end CovariantDerivative end horiz From b1af2dda51bbc677603d7d1d0f387bd15d4a0baa Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Feb 2026 10:33:50 +0100 Subject: [PATCH 415/601] Fix build --- .../VectorBundle/CovariantDerivative/Torsion.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 15628d5d192bfa..75ec9921d70510 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -147,15 +147,15 @@ variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) -- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! -variable (f X) in +variable (f) in @[simp] -lemma torsion_zero : torsion cov 0 X = 0 := by - ext x - simp [torsion] +lemma torsion_zero (hX : MDiff T% X) : torsion cov 0 X = 0 := by + simp [torsion, cov.zeroX hX, cov.zeroσ hX] + -variable (X) in @[simp] -lemma torsion_zero' : torsion cov X 0 = 0 := by rw [torsion_antisymm, torsion_zero]; simp +lemma torsion_zero' (hX : MDiff T% X) : torsion cov X 0 = 0 := by + rw [torsion_antisymm, torsion_zero hX]; simp variable (Y) in lemma torsion_add_left [CompleteSpace E] From bc506c75ff3396643e63ca0724dd7111d037f6af Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Feb 2026 14:11:09 +0100 Subject: [PATCH 416/601] Remove some refactor sorries --- .../CovariantDerivative/Basic.lean | 222 +++++++++--------- 1 file changed, 107 insertions(+), 115 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 91b456bb1546c9..450d97d1cb3a52 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -27,6 +27,43 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff +@[expose] public section delaborators + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` +open Lean PrettyPrinter Delaborator SubExpr + +@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do + whenPPOption getPPNotation do + let args := (← getExpr).getAppArgs + if args.size < 22 then failure + let pt : Term ← withNaryArg 21 <| delab + let f := args[20]! + try + if let .lam _ _ b _ := f then + if b.isAppOf ``Bundle.TotalSpace.mk' then + let s := b.getAppArgs[4]!.getAppFn + let ss ← PrettyPrinter.delab s + return ← `(MDiffAt (T% $ss) $pt) + -- if let .const name _ := s then + -- let i := mkIdent name + -- return ← `(MDiffAt (T% $i) $pt) + -- else + -- failure + failure + catch _ => + let x : Term ← withNaryArg 20 <| delab + return ← `(MDiffAt $x $pt) + +end delaborators + variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! @@ -188,6 +225,7 @@ lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) simp rfl +set_option linter.flexible false in -- FIXME lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) (hs : MDiffAt s x) (v : TangentSpace I x) : letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v @@ -833,25 +871,68 @@ namespace IsCovariantDerivativeOn lemma congr_X_at [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) - (X X' : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} (hx : x ∈ u) (hXX' : X x = X' x) : + {X X' : Π x : M, TangentSpace I x} + {σ : Π x : M, V x} {x : M} + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hσ : MDiffAt (T% σ) x) + (hx : x ∈ u) (hXX' : X x = X' x) : cov X σ x = cov X' σ x := by - apply tensoriality_criterion' (E := E) (I := I) E (TangentSpace I) F V hXX' - · intro f X - rw [hcov.smulX] - repeat sorry -- TODO: need to assume X, σ, f are C^k at x - · intro X X' - rw [hcov.addX] - all_goals sorry + refine tensoriality_criterion I E (TangentSpace I) (φ := fun X ↦ cov X σ) F V hX hX' hXX' ?_ ?_ + · intro f X hf hX + exact hcov.smulX hX hσ hf hx + · intro X X' hX hX' + exact hcov.addX hX hX' hσ hx + +lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] + [FiniteDimensional ℝ E] + {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} + (hX : MDiffAt (T% X) x) + (hσ : MDiffAt (T% σ) x) + (f : SmoothBumpFunction I x) + (hx : x ∈ u) : + cov X ((f : M → ℝ) • σ) x = cov X σ x := by + have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) + have := hcov.leibniz hX hσ hf hx + rw [hcov.leibniz hX hσ _ hx] + swap; · apply f.contMDiff.mdifferentiable (by norm_num) + calc _ + _ = cov X σ x + 0 := ?_ + _ = cov X σ x := by rw [add_zero] + suffices mfderiv% (1 : M → ℝ) x (X x) = 0 ∨ σ x = 0 by + simpa [f.eq_one, f.eventuallyEq_one.mfderiv_eq] + rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] + left + rfl lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) - (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} (hxu : s ∈ 𝓝 x) + {X : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} + (hX : MDiffAt (T% X) x) + (hσ : MDiffAt (T% σ) x) + (hσ' : MDiffAt (T% σ') x) + (hxs : s ∈ 𝓝 x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : cov X σ x = cov X σ' x := by - sorry -- Note there is a commented out version of this lemma at the bottom + -- Choose a smooth bump function ψ with support around `x` contained in `s` + obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hxs).mem_iff.1 hxs + -- Observe that `ψ • σ = ψ • σ'` as dependent functions. + have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by + by_cases h : x ∈ s + · simp [hσσ' x h] + · simp [Function.notMem_support.mp fun a ↦ h (hψ a)] + -- Then, it's a chain of (dependent) equalities. + calc cov X σ x + _ = cov X ((ψ : M → ℝ) • σ) x := by + rw [hcov.congr_σ_smoothBumpFunction X hX hσ ψ (mem_of_mem_nhds hxs)] + _ = cov X ((ψ : M → ℝ) • σ') x := by rw [funext this] + _ = cov X σ' x := by + rw [hcov.congr_σ_smoothBumpFunction X hX hσ' ψ (mem_of_mem_nhds hxs)] -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x +-- this should be easy using the projection formula below. /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ @@ -891,11 +972,13 @@ lemma differenceAux_smul_eq' {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) (hcov' : IsCovariantDerivativeOn F cov' u) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) (f : M → ℝ) - {x : M} (hx : x ∈ u := by trivial) : + {X : Π x : M, TangentSpace I x} + (hX : MDiffAt (T% X) x) + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) + {f : M → ℝ} (hf : MDiffAt f x) + (hx : x ∈ u := by trivial) : differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by - sorry -- TODO: need to assume X, σ and f are differentiable! - -- simp only [differenceAux, Pi.apply, hcov.smulX, hcov'.smulX, smul_sub] + simp [differenceAux, hcov.smulX hX hσ hf, hcov'.smulX hX hσ hf, smul_sub] /-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ lemma differenceAux_tensorial @@ -917,7 +1000,7 @@ lemma differenceAux_tensorial -- TODO: is there a version of `tensoriality_criterion` which does not require `hX`? apply tensoriality_criterion (E := E) (I := I) E (TangentSpace I) F V hX hX' hXX' · intro f X hf hX - exact hcov.differenceAux_smul_eq' hcov' .. + exact hcov.differenceAux_smul_eq' hcov' hX hσ hf · intro X X' hX hX' unfold φ differenceAux simp only [Pi.sub_apply, hcov.addX hX hX' hσ, hcov'.addX hX hX' hσ] @@ -1168,16 +1251,7 @@ lemma Trivialization.fst_comp_eventuallyEq filter_upwards [this] with y hy exact coe_fst' e hy --- TODO: decide whether we want this and move --- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` -open Lean PrettyPrinter Delaborator SubExpr in -@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do - whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - +omit [IsManifold I 1 M] in lemma Trivialization.mdifferentiableAt [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {x : M} (hx : x ∈ e.baseSet) (v : V x) : @@ -1187,10 +1261,12 @@ MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by have := foo.contMDiffAt (e.open_source.mem_nhds this) exact this.mdifferentiableAt zero_ne_one.symm +omit [IsManifold I 1 M] in noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker +omit [IsManifold I 1 M] in lemma Trivialization.comap_vert [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : @@ -1216,6 +1292,7 @@ lemma Trivialization.eq_of {x : M} {v v' : V x} rw [hvv'] at this grind [e.symm_proj_apply v' hx] +omit [IsManifold I 1 M] in lemma Trivialization.derivEquiv_mfderiv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) @@ -1260,13 +1337,15 @@ lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensio [VectorBundle ℝ F V] {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hcov : IsCovariantDerivativeOn F cov e.baseSet) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) {x : M} + {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} + (hX : MDiffAt T%X x) (hσ : MDiffAt T%σ x) (hx : x ∈ e.baseSet := by assumption) : (e.pushCovDer cov) X (fun x ↦ (e (σ x)).2) x = (e (cov X σ x)).2 := by have : cov X (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov X σ x := by - apply hcov.congr_σ_of_eqOn + apply hcov.congr_σ_of_eqOn hX _ hσ · exact e.open_baseSet.mem_nhds_iff.mpr hx · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? + · sorry unfold pushCovDer rw [this] @@ -1387,7 +1466,7 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] exact (mdifferentiableAt_section I s).mpr hσ apply t.eq_of hx rw [cov.snd_triv_proj (T% σ x), - ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) X σ, + ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hX hσ, hcov.cov_eq_proj X s hX hs, t.derivEquiv_mfderiv hσ _ hx] end CovariantDerivative @@ -1396,93 +1475,6 @@ end horiz end real -/- the following lemmas are subsubmed by tensoriality_criterion - XXX should they be extracted as separate lemmas (stated twice)? -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -/-- If `X` and `X'` agree in a neighbourhood of `p`, then `∇_X σ` and `∇_X' σ` agree at `p`. -/ -lemma congr_X_of_eventuallyEq (cov : CovariantDerivative I F V) [T2Space M] - {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσσ' : ∀ x ∈ s, X x = X' x) : - cov X σ x = cov X' σ x := by - -- Choose a smooth bump function ψ with support around `x` contained in `s` - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs - -- Observe that `ψ • X = ψ • X'` as dependent functions. - have (x : M) : ((ψ : M → ℝ) • X) x = ((ψ : M → ℝ) • X') x := by - by_cases h : x ∈ s - · simp [hσσ' x h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - -- Then, it's a chain of (dependent) equalities. - calc cov X σ x - _ = cov ((ψ : M → ℝ) • X) σ x := by simp [cov.smulX] - _ = cov ((ψ : M → ℝ) • X') σ x := by rw [funext this] - _ = cov X' σ x := by simp [cov.smulX] - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_X_at_aux (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} {x : M} - (hX : X x = 0) : cov X σ x = 0 := by - -- Consider the local frame {Xⁱ} on TangentSpace I x induced by chartAt H x. - -- To do so, choose a basis of TangentSpace I x = E. - let n : ℕ := Module.finrank ℝ E - let b : Basis (Fin n) ℝ E := Module.finBasis ℝ E - let e := trivializationAt E (TangentSpace I) x - let Xi (i : Fin n) := b.localFrame e i - -- Write X in coordinates: X = ∑ i, a i • Xi i near `x`. - let a := fun i ↦ b.localFrame_coeff e i X - have : x ∈ e.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have aux : ∀ᶠ (x' : M) in 𝓝 x, X x' = ∑ i, a i x' • Xi i x' := b.localFrame_eventually_eq_sum_coeff_smul this X - have (i : Fin n) : a i x = 0 := b.localFrame_coeff_apply_zero_at hX i - calc cov X σ x - _ = cov (∑ i, a i • Xi i) σ x := cov.congr_X_of_eventuallyEq aux (by simp) - _ = ∑ i, cov (a i • Xi i) σ x := by rw [cov.sum_X]; simp - _ = ∑ i, a i x • cov (Xi i) σ x := by - congr; ext i; simp [cov.smulX (Xi i) σ (a i)] - _ = 0 := by simp [this] -/ - -/- TODO: are these lemmas still useful after the general tensoriality lemma? -are they worth extracting separately? -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_σ_smoothBumpFunction (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} - (hσ : MDiffAt (T% σ) x) - (f : SmoothBumpFunction I x) : - cov X ((f : M → ℝ) • σ) x = cov X σ x := by - rw [cov.leibniz _ _ _ _ hσ] - swap; · apply f.contMDiff.mdifferentiable (by norm_num) - calc _ - _ = cov X σ x + 0 := ?_ - _ = cov X σ x := by rw [add_zero] - simp [f.eq_one, f.eventuallyEq_one.mfderiv_eq] - rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] - left - rfl - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] in -lemma congr_σ_of_eventuallyEq - (cov : CovariantDerivative I F V) [T2Space M] [IsManifold I ∞ M] - (X : Π x : M, TangentSpace I x) {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) - (hσ : MDiffAt (T% σ) x) - (hσσ' : ∀ x ∈ s, σ x = σ' x) : - cov X σ x = cov X σ' x := by - -- Choose a smooth bump function ψ with support around `x` contained in `s` - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hs).mem_iff.1 hs - -- Observe that `ψ • σ = ψ • σ'` as dependent functions. - have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by - by_cases h : x ∈ s - · simp [hσσ' x h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - -- Then, it's a chain of (dependent) equalities. - calc cov X σ x - _ = cov X ((ψ : M → ℝ) • σ) x := by rw [cov.congr_σ_smoothBumpFunction _ hσ] - _ = cov X ((ψ : M → ℝ) • σ') x := sorry -- use simp [funext hσ] and (by simp [this]) - _ = cov X σ' x := by - simp [cov.congr_σ_smoothBumpFunction, mdifferentiableAt_dependent_congr hs hσ hσσ'] --/ - -- variable (E E') in -- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ -- @[simps] From 15fb9784ecb69f8986e2cd421d440bfc8817413a Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Feb 2026 19:11:36 +0100 Subject: [PATCH 417/601] Remove more sorries --- .../CovariantDerivative/Basic.lean | 255 ++++++++++++------ 1 file changed, 176 insertions(+), 79 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 450d97d1cb3a52..fc9e4a3678d60a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -27,6 +27,44 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff +@[expose] public section mfderiv + +open Function + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +lemma injective_mfderiv_of_eventually_leftInverse + {f : M → M'} (x : M) {g : M' → M} + (hg : MDifferentiableAt I' I g (f x)) (hf : MDifferentiableAt I I' f x) + (hfg : g ∘ f =ᶠ[𝓝 x] id) : Injective (mfderiv I I' f x) := by + have := mfderiv_comp x hg hf + rw [hfg.mfderiv_eq] at this + have : LeftInverse (mfderiv I' I g (f x)) (mfderiv I I' f x) := by + intro u + simpa using congr($this u).symm + exact LeftInverse.injective this + +lemma surjective_mfderiv_of_eventually_rightInverse + {f : M → M'} {x : M} {y : M'} (hxy : y = f x) {g : M' → M} + (hg : MDifferentiableAt I' I g y) (hf : MDifferentiableAt I I' f x) + (hfg : g ∘ f =ᶠ[𝓝 x] id) : Surjective (mfderiv I' I g y) := by + rw [hxy] at hg + have := mfderiv_comp x hg hf + rw [hfg.mfderiv_eq] at this + have : RightInverse (mfderiv I I' f x) (mfderiv I' I g (f x)) := by + intro u + simpa using congr($this u).symm + rw [← hxy] at this + exact RightInverse.surjective this + +end mfderiv + @[expose] public section delaborators -- TODO: decide whether we want this and move @@ -50,14 +88,10 @@ open Lean PrettyPrinter Delaborator SubExpr if let .lam _ _ b _ := f then if b.isAppOf ``Bundle.TotalSpace.mk' then let s := b.getAppArgs[4]!.getAppFn - let ss ← PrettyPrinter.delab s - return ← `(MDiffAt (T% $ss) $pt) - -- if let .const name _ := s then - -- let i := mkIdent name - -- return ← `(MDiffAt (T% $i) $pt) - -- else - -- failure - failure + if s matches .fvar .. then + let ss ← PrettyPrinter.delab s + return ← `(MDiffAt (T% $ss) $pt) + throwError "nope" catch _ => let x : Term ← withNaryArg 20 <| delab return ← `(MDiffAt $x $pt) @@ -320,7 +354,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% (extend I F σ₀)) := by letI t := trivializationAt F V x letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - have hx : x ∈ t.baseSet := by exact FiberBundle.mem_baseSet_trivializationAt' x + have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht @@ -1199,45 +1233,42 @@ end projection_trivial_bundle end IsCovariantDerivativeOn -section from_trivialization - -variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] - -noncomputable -def Trivialization.covDeriv (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) - (x : M) : V x := e.symm x (mfderiv I 𝓘(ℝ, F) (fun x' ↦ (e (σ x')).2) x (X x)) - --- The following is probably not on the critical path -lemma Trivialization.covDeriv_isCovariantDerivativeOn [IsManifold I 1 M] : - IsCovariantDerivativeOn (I := I) F e.covDeriv e.baseSet where - addX {_X _X' _σ _x} hX hX' hσ hx := by sorry - smulX {_X _σ} c' x hX hσ hx := by sorry - addσ {_X _σ _σ' _x} hX hσ hσ' hx := by sorry - smul_const_σ {_X _σ _x} a hX hσ hx := by sorry - leibniz {X σ f x} hX hσ hf hx := by sorry - -end from_trivialization - section to_trivialization variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] --- Note: The definition below (ab)uses definitional --- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` --- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` --- which is $T_{π(v)} M × F$. -variable (I) in -noncomputable -def Trivialization.derivEquiv (v : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) v ≃L[ℝ] TangentSpace I v.proj × F where - toFun := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v - map_add' := by simp - map_smul' := by simp - invFun := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (e v) - left_inv := sorry - right_inv := sorry - continuous_toFun := ContinuousLinearMap.continuous _ - continuous_invFun := ContinuousLinearMap.continuous _ +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] + [(x : M) → AddCommGroup (V x)] + [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] in +lemma Trivialization.baseSet_mem_nhds {x : M} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := + e.open_baseSet.mem_nhds_iff.mpr hx + +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] + [(x : M) → AddCommGroup (V x)] in +lemma Trivialization.preimage_baseSet_mem_nhds {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := + FiberBundle.continuous_proj F V |>.continuousAt <| e.baseSet_mem_nhds hv + +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] + [(x : M) → AddCommGroup (V x)] [(x : M) → TopologicalSpace (V x)] in +lemma Trivialization.baseSet_prod_univ_mem_nhds {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + e.baseSet ×ˢ univ ∈ 𝓝 (e v) := by + rw [← mk_proj_snd' e hv] + exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem + +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] + [FiberBundle F V] [MemTrivializationAtlas e] [(x : M) → AddCommGroup (V x)] in +lemma Trivialization.comp_invFun_eventuallyEq + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : e ∘ e.invFun =ᶠ[𝓝 (e v)] id := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp using + apply_symm_apply e <| (mem_target e).2 hp.1 + +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] + [(x : M) → AddCommGroup (V x)] in +lemma Trivialization.invFun_comp_eventuallyEq + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : e.invFun ∘ e =ᶠ[𝓝 v] id := by + filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw using + symm_apply_apply e <| (mem_source e).mpr hw variable (I) in omit [MemTrivializationAtlas e] [IsManifold I 1 M] in @@ -1245,11 +1276,7 @@ lemma Trivialization.fst_comp_eventuallyEq [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := by - have : TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := by - apply FiberBundle.continuous_proj F V |>.continuousAt - exact e.open_baseSet.mem_nhds_iff.mpr hv - filter_upwards [this] with y hy - exact coe_fst' e hy + filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using coe_fst' e hy omit [IsManifold I 1 M] in lemma Trivialization.mdifferentiableAt @@ -1261,6 +1288,62 @@ MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by have := foo.contMDiffAt (e.open_source.mem_nhds this) exact this.mdifferentiableAt zero_ne_one.symm +omit [IsManifold I 1 M] in +lemma Trivialization.mdifferentiableAt_invFun + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) (f : F) : + MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (x, f) := by + have : ⟨x, f⟩ ∈ e.target := (mk_mem_target e).mpr hx + have foo := e.contMDiffOn_symm (IB := I) (n := 1) _ this + have := foo.contMDiffAt (e.open_target.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +-- Note: The definition below (ab)uses definitional +-- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` +-- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` +-- which is $T_{π(v)} M × F$. +variable (I) in +noncomputable +def Trivialization.deriv (v : TotalSpace F V) : + TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] TangentSpace I v.proj × F := + mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v + +omit [IsManifold I 1 M] in +lemma Trivialization.bijective_deriv + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Function.Bijective (e.deriv I v) := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [mk_proj_snd' e hv] at D₁ + have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + constructor + · apply injective_mfderiv_of_eventually_leftInverse v D₁ D₂ + apply e.invFun_comp_eventuallyEq hv + · have : v = e.invFun (e v) := + (Eventually.self_of_nhds <| e.invFun_comp_eventuallyEq hv).symm + apply surjective_mfderiv_of_eventually_rightInverse this D₂ D₁ + (e.comp_invFun_eventuallyEq hv) + +omit [NormedSpace ℝ F] + [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] + [FiberBundle F V] [MemTrivializationAtlas e] in +lemma Trivialization.symm_apply_apply_mk_eventuallyEq + {x : M} (hx : x ∈ e.baseSet) (σ : Π x, V x) : + (T% fun x' ↦ e.symm x' (e (T% σ x')).2) =ᶠ[𝓝 x] T% σ := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [symm_apply_apply_mk e hy (σ y)] + +omit [NormedSpace ℝ F] [(x : M) → AddCommGroup (V x)] + [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] + [FiberBundle F V] [MemTrivializationAtlas e] in +lemma Trivialization.apply_section_eventuallyEq + {x : M} (hx : x ∈ e.baseSet) (σ : Π x, V x) : + e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + ext + · exact coe_coe_fst e hy + · simp + omit [IsManifold I 1 M] in noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := @@ -1270,7 +1353,7 @@ omit [IsManifold I 1 M] in lemma Trivialization.comap_vert [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Bundle.vert v = Submodule.comap (e.derivEquiv I v).toLinearMap + Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap (Submodule.prod ⊥ ⊤) := by ext x have : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := e.fst_comp_eventuallyEq I hv @@ -1293,33 +1376,25 @@ lemma Trivialization.eq_of {x : M} {v v' : V x} grind [e.symm_proj_apply v' hx] omit [IsManifold I 1 M] in -lemma Trivialization.derivEquiv_mfderiv +lemma Trivialization.mfderiv_comp_section [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) (u : TangentSpace I x) (hx : x ∈ e.baseSet) : letI s := fun x ↦ (e (σ x)).2 - e.derivEquiv I (σ x) ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by + (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e (σ x) := e.mdifferentiableAt hx _ have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x = - (derivEquiv I e (σ x)).toContinuousLinearMap ∘L - (mfderiv% T%σ x) := + (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := mfderiv_comp x mdiffe hσ have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = - e.derivEquiv I (σ x) ((mfderiv% T%σ x) u) := by + e.deriv I (σ x) ((mfderiv% T%σ x) u) := by rw [this] rfl - rw [← this] + erw [← this] let s := fun x ↦ (e (σ x)).2 - change mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = (u, mfderiv I 𝓘(ℝ, F) s x u) - -- FIXME extract lemma - have : e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by - have : e.baseSet ∈ 𝓝 x := e.open_baseSet.mem_nhds_iff.mpr hx - filter_upwards [this] with y hy - ext - · exact coe_coe_fst e hy - · simp - rw [this.mfderiv_eq] + change mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = (u, mfderiv% s x u) + rw [(e.apply_section_eventuallyEq hx _).mfderiv_eq] erw [mfderiv_prodMk, mfderiv_id] · change (ContinuousLinearMap.id _ _).prod (mfderiv% s x) u = _ simp @@ -1332,9 +1407,10 @@ def Trivialization.pushCovDer (Π x : M, TangentSpace I x) → (M → F) → (M → F) := fun X σ x ↦ e (cov X (fun x' ↦ e.symm x' <| σ x') x) |>.2 +omit [MemTrivializationAtlas e] in lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - [VectorBundle ℝ F V] + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hcov : IsCovariantDerivativeOn F cov e.baseSet) {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} @@ -1342,10 +1418,10 @@ lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensio (hx : x ∈ e.baseSet := by assumption) : (e.pushCovDer cov) X (fun x ↦ (e (σ x)).2) x = (e (cov X σ x)).2 := by have : cov X (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov X σ x := by - apply hcov.congr_σ_of_eqOn hX _ hσ - · exact e.open_baseSet.mem_nhds_iff.mpr hx + apply hcov.congr_σ_of_eqOn hX _ hσ (e.baseSet_mem_nhds hx) · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? - · sorry + · rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] + exact hσ unfold pushCovDer rw [this] @@ -1381,8 +1457,8 @@ def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) letI tproj := d_covDerOn.projection v.proj (t v).2 - letI Tvt := t.derivEquiv I v - t.symmL ℝ v.proj ∘L tproj ∘L Tvt.toContinuousLinearMap + letI Tvt := t.deriv I v + t.symmL ℝ v.proj ∘L tproj ∘L Tvt lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : @@ -1390,7 +1466,7 @@ lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) letI tproj := d_covDerOn.projection v.proj (t v).2 - letI Tvt := t.derivEquiv I v + letI Tvt := t.deriv I v (t <| cov.proj v u).2 = tproj (Tvt u) := by simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] @@ -1403,11 +1479,11 @@ lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalS letI t := trivializationAt F V v.proj haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - horiz cov v = Submodule.comap (t.derivEquiv I v).toLinearMap + horiz cov v = Submodule.comap (t.deriv I v).toLinearMap (d_covDerOn.horiz v.proj (t v).2) := by -- FIXME: needing all those lets and the change is awful let t := trivializationAt F V v.proj - let Tvt := t.derivEquiv I v + let Tvt := t.deriv I v have hcov := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) let tproj := hcov.projection v.proj (t v).2 @@ -1416,6 +1492,25 @@ lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalS change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 simp +lemma LinearMap.comap_isCompl {R R₂ M M₂ : Type*} + [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] + {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] + [AddCommMonoid M₂] [Module R₂ M₂] + {f : M →ₛₗ[σ₁₂] M₂} (hf : Function.Bijective f) + {p q : Submodule R₂ M₂} (h : IsCompl p q) : + IsCompl (Submodule.comap f p) (Submodule.comap f q) := by + rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * + constructor + · rw [← Submodule.comap_inf, h.1] + simp [LinearMap.ker_eq_bot_of_injective hf.1] + · rw [← Submodule.comap_sup_of_injective, h.2] + · exact Submodule.comap_top f + · exact hf.1 + · intro x hx + exact hf.2 x + · intro x hx + exact hf.2 x + lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] @@ -1436,12 +1531,14 @@ lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] (cov : CovariantDerivative I F V) (v : TotalSpace F V) : IsCompl (cov.horiz v) (vert v) := by let t := trivializationAt F V v.proj - let Tvt := t.derivEquiv I v + let Tvt := t.deriv I v have hcov := t.pushCovDer_isCovariantDerivativeOn (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) rw [t.comap_vert (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] - apply LinearEquiv.comap_isCompl - apply hcov.horiz_vert_direct_sum + apply LinearMap.comap_isCompl + · apply t.bijective_deriv + exact FiberBundle.mem_baseSet_trivializationAt' v.proj + · apply hcov.horiz_vert_direct_sum variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} @@ -1465,9 +1562,9 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] rw [t.mdifferentiableAt_section_iff I σ hx] at hσ exact (mdifferentiableAt_section I s).mpr hσ apply t.eq_of hx - rw [cov.snd_triv_proj (T% σ x), + erw [cov.snd_triv_proj (T% σ x), ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hX hσ, - hcov.cov_eq_proj X s hX hs, t.derivEquiv_mfderiv hσ _ hx] + hcov.cov_eq_proj X s hX hs, t.mfderiv_comp_section hσ _ hx] end CovariantDerivative end horiz From 4b5162f0642f89e9d5361a4dce4829ff4fee0e2c Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 24 Feb 2026 22:00:56 +0100 Subject: [PATCH 418/601] More painful trivial proofs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only `trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞)` remains sorry in `CovariantDerivative.Basic`. --- .../CovariantDerivative/Basic.lean | 105 +++++++++++++++++- 1 file changed, 99 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index fc9e4a3678d60a..44c57156733447 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1237,6 +1237,26 @@ section to_trivialization variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] +lemma Trivialization.map_add + [VectorBundle ℝ F V] + {x : M} (hx : x ∈ e.baseSet) (v v' : V x) : + (e ⟨x, v + v'⟩).2 = (e ⟨x, v⟩).2 + (e ⟨x, v'⟩).2 := + e.linear ℝ hx |>.map_add v v' + +lemma Trivialization.symm_map_add [VectorBundle ℝ F V] {x : M} (f f' : F) : + e.symm x (f + f') = e.symm x f + e.symm x f' := + (symmL ℝ e x).map_add f f' + +lemma Trivialization.symm_map_smul [VectorBundle ℝ F V] {x : M} (a : ℝ) (f : F) : + e.symm x (a • f) = a • e.symm x f := + (symmL ℝ e x).map_smul a f + +lemma Trivialization.map_smul + [VectorBundle ℝ F V] + {x : M} (hx : x ∈ e.baseSet) (a : ℝ) (v : V x) : + (e ⟨x, a • v⟩).2 = a • (e ⟨x, v⟩).2 := + e.linear ℝ hx |>.map_smul a v + omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] [(x : M) → AddCommGroup (V x)] [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] in @@ -1344,6 +1364,24 @@ lemma Trivialization.apply_section_eventuallyEq · exact coe_coe_fst e hy · simp +omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] +[(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [MemTrivializationAtlas e] in +@[simp] +lemma Trivialization.apply_symm_eventuallyEq {x : M} (hx : x ∈ e.baseSet) (s : M → F) : + (fun x ↦ (e ⟨x, e.symm x (s x)⟩).2) =ᶠ[𝓝 x] s := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + rw [e.apply_mk_symm hy] + +omit [IsManifold I 1 M] in +lemma Trivialization.mdifferentiableAt_section_of_function + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) {s : M → F} + (hs : MDiffAt s x) : + MDiffAt ((fun x' ↦ (⟨x', e.symm x' (s x')⟩ : TotalSpace F V))) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] + have := e.apply_symm_eventuallyEq hx s + exact hs.congr_of_eventuallyEq this + omit [IsManifold I 1 M] in noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := @@ -1425,17 +1463,70 @@ lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensio unfold pushCovDer rw [this] +omit [IsManifold I 1 M] in +@[simp] +lemma mdifferentiableAt_section_trivial_iff {s : M → F} {x : M} : + MDiffAt (T% s) x ↔ MDiffAt s x := by + rw [mdifferentiableAt_section I] + simp + variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) lemma Trivialization.pushCovDer_isCovariantDerivativeOn + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov e.baseSet) : IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet where - addX := sorry - smulX := sorry - addσ := sorry - leibniz := sorry - smul_const_σ := sorry + addX {X X' σ x} hX hX' hσ hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + unfold Trivialization.pushCovDer + rw [hcov.addX hX hX' hs, e.map_add hx] + smulX {X σ g x} hX hσ hg hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + unfold Trivialization.pushCovDer + rw [hcov.smulX hX hs hg, e.map_smul hx] + smul_const_σ {X σ x} a hX hσ hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + unfold Trivialization.pushCovDer + rw [← e.map_smul hx, ← hcov.smul_const_σ a hX hs hx] + congr + ext y + simp [e.symm_map_smul, s] + addσ {X σ σ' x} hX hσ hσ' hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + set s' := (fun x' ↦ e.symm x' (σ' x')) + have hs' : MDiffAt (T% s') x := + e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 + hσ' + unfold Trivialization.pushCovDer + rw [← e.map_add hx] + congr + rw [← hcov.addσ hX hs hs' hx] + congr + ext y + simp [e.symm_map_add, s, s'] + leibniz {X σ g x} hX hσ hg hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + unfold Trivialization.pushCovDer + have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by + ext y + simp [s, e.symm_map_smul] + rw [this, hcov.leibniz hX hs hg hx] + suffices g x • (e ⟨x, cov X s x⟩).2 + (bar (g x)) ((mfderiv% g x) (X x)) • (e ⟨x, s x⟩).2 = + g x • (e ⟨x, cov X (fun x' ↦ e.symm x' (σ x')) x⟩).2 + + (bar (g x)) ((mfderiv% g x) (X x)) • σ x by simpa [e.map_add hx, e.map_smul hx] + congr + rw [e.apply_mk_symm hx] end to_trivialization @@ -1444,7 +1535,7 @@ namespace CovariantDerivative variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - [VectorBundle ℝ F V] + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] local notation "TM" => TangentSpace I @@ -1527,6 +1618,7 @@ lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} · simp · simp +omit [ContMDiffVectorBundle 1 F V I] in lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] (cov : CovariantDerivative I F V) (v : TotalSpace F V) : IsCompl (cov.horiz v) (vert v) := by @@ -1543,6 +1635,7 @@ lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} +omit [ContMDiffVectorBundle 1 F V I] in lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) (hX : MDiffAt (T% X) x) From f0c381546e6218ca3f2e091140363201b5f1ed5a Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 25 Feb 2026 15:18:08 +0100 Subject: [PATCH 419/601] Split off preliminaries for covariant derivative and remove all omit from those preliminaries except for two weird elaborator bugs --- Mathlib.lean | 1 + .../CovariantDerivative/Basic.lean | 597 +--------------- .../CovariantDerivative/Prelim.lean | 675 ++++++++++++++++++ 3 files changed, 681 insertions(+), 592 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean diff --git a/Mathlib.lean b/Mathlib.lean index d1d11c2c99098d..d9444601ef47d7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4378,6 +4378,7 @@ public import Mathlib.Geometry.Manifold.SmoothApprox public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 44c57156733447..b1828f4f6cf939 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -15,6 +15,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim /-! # Covariant derivatives @@ -27,356 +28,12 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff -@[expose] public section mfderiv -open Function - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - -lemma injective_mfderiv_of_eventually_leftInverse - {f : M → M'} (x : M) {g : M' → M} - (hg : MDifferentiableAt I' I g (f x)) (hf : MDifferentiableAt I I' f x) - (hfg : g ∘ f =ᶠ[𝓝 x] id) : Injective (mfderiv I I' f x) := by - have := mfderiv_comp x hg hf - rw [hfg.mfderiv_eq] at this - have : LeftInverse (mfderiv I' I g (f x)) (mfderiv I I' f x) := by - intro u - simpa using congr($this u).symm - exact LeftInverse.injective this - -lemma surjective_mfderiv_of_eventually_rightInverse - {f : M → M'} {x : M} {y : M'} (hxy : y = f x) {g : M' → M} - (hg : MDifferentiableAt I' I g y) (hf : MDifferentiableAt I I' f x) - (hfg : g ∘ f =ᶠ[𝓝 x] id) : Surjective (mfderiv I' I g y) := by - rw [hxy] at hg - have := mfderiv_comp x hg hf - rw [hfg.mfderiv_eq] at this - have : RightInverse (mfderiv I I' f x) (mfderiv I' I g (f x)) := by - intro u - simpa using congr($this u).symm - rw [← hxy] at this - exact RightInverse.surjective this - -end mfderiv - -@[expose] public section delaborators - --- TODO: decide whether we want this and move --- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` -open Lean PrettyPrinter Delaborator SubExpr - -@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do - whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - -@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do - whenPPOption getPPNotation do - let args := (← getExpr).getAppArgs - if args.size < 22 then failure - let pt : Term ← withNaryArg 21 <| delab - let f := args[20]! - try - if let .lam _ _ b _ := f then - if b.isAppOf ``Bundle.TotalSpace.mk' then - let s := b.getAppArgs[4]!.getAppFn - if s matches .fvar .. then - let ss ← PrettyPrinter.delab s - return ← `(MDiffAt (T% $ss) $pt) - throwError "nope" - catch _ => - let x : Term ← withNaryArg 20 <| delab - return ← `(MDiffAt $x $pt) - -end delaborators variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! -section general_lemmas -- those lemmas should move - -section linear_algebra -variable (𝕜 : Type*) [Field 𝕜] - {E : Type*} [AddCommGroup E] [Module 𝕜 E] - {E' : Type*} [AddCommGroup E'] [Module 𝕜 E'] - -lemma exists_map_of (u : E) (u' : E') : - ∃ φ : E →ₗ[𝕜] E', (u = 0 → u' = 0) → φ u = u' := by - by_cases h : u = 0 - · simp [h] - tauto - · have indep : LinearIndepOn 𝕜 id {u} := LinearIndepOn.singleton h - let s := indep.extend (subset_univ _) - have hus : u ∈ s := singleton_subset_iff.mp <| indep.subset_extend (subset_univ _) - use (Basis.extend indep).constr (M' := E') (S := 𝕜) fun _ ↦ u' - simpa [h, Basis.extend_apply_self] using (Basis.extend indep).constr_basis _ _ ⟨u, hus⟩ - -open Classical in -noncomputable def map_of (u : E) (u' : E') : E →ₗ[𝕜] E' := (exists_map_of 𝕜 u u').choose - -variable {𝕜} -lemma map_of_spec (u : E) (u' : E') (h : u = 0 → u' = 0) : map_of 𝕜 u u' u = u' := - (exists_map_of 𝕜 u u').choose_spec h -end linear_algebra - -variable - {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] - -section -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} - {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - - -variable (𝕜) in -noncomputable def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := - fun x ↦ e' + map_of 𝕜 u u' (x - e) - -lemma map_of_loc_one_jet_spec [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] - (e u : E) (e' u' : E') (hu : u = 0 → u' = 0) : - map_of_loc_one_jet 𝕜 e u e' u' e = e' ∧ - DifferentiableAt 𝕜 (map_of_loc_one_jet 𝕜 e u e' u') e ∧ - fderiv 𝕜 (map_of_loc_one_jet 𝕜 e u e' u') e u = u' := by - unfold map_of_loc_one_jet - let φ := (map_of 𝕜 u u').toContinuousLinearMap - have diff : Differentiable 𝕜 (map_of 𝕜 u u') := - (map_of 𝕜 u u').toContinuousLinearMap.differentiable - refine ⟨by simp, ?_, ?_⟩ - · apply (differentiableAt_const e').add - apply diff.differentiableAt.comp - fun_prop - · simp only [map_sub, fderiv_const_add] - rw [fderiv_sub_const] - change (fderiv 𝕜 φ e) u = _ - rw [φ.hasFDerivAt.fderiv] - exact map_of_spec u u' hu - -noncomputable -def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : - M → M' := - letI ψ := extChartAt I' x' - letI φ := extChartAt I x - ψ.symm ∘ - (map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ - φ - --- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. - -/-- For any `(x, u) ∈ TM` and `(x', u') ∈ TM'`, `map_of_one_jet u u'` sends `x` to `x'` and -its derivative sends `u` to `u'`. We need to assume the target manifold `M'` has no boundary -since we cannot hope the result is `x` and `x'` are boundary points and `u` is inward -while `u'` is outward. --/ -lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] - [BoundarylessManifold I' M'] - [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] - {x : M} (u : TangentSpace I x) {x' : M'} - (u' : TangentSpace I' x') (hu : u = 0 → u' = 0) : - map_of_one_jet u u' x = x' ∧ - MDiffAt (map_of_one_jet u u') x ∧ - mfderiv I I' (map_of_one_jet u u') x u = u' := by - let ψ := extChartAt I' x' - let φ := extChartAt I x - let g := map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') - let Ψ : M' → E' := ψ -- FIXME: this is working around a limitation of MDiffAt elaborator - have hψ : MDiffAt Ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') - let Φ : M → E := φ -- FIXME: this is working around a limitation of MDiffAt elaborator - have hφ : MDiffAt Φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) - replace hu : mfderiv I 𝓘(𝕜, E) φ x u = 0 → mfderiv I' 𝓘(𝕜, E') ψ x' u' = 0 := by - have : Function.Injective (mfderiv I 𝓘(𝕜, E) φ x) := - (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x)).injective - rw [injective_iff_map_eq_zero] at this - have := map_zero (mfderiv I' 𝓘(𝕜, E') ψ x') - grind - rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) - (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') hu with - ⟨h : g (φ x) = ψ x', h', h''⟩ - have hg : MDiffAt g (φ x) := mdifferentiableAt_iff_differentiableAt.mpr h' - have hgφ : MDiffAt (g ∘ φ) x := h'.comp_mdifferentiableAt hφ - let Ψi : E' → M' := ψ.symm -- FIXME: this is working around a limitation of MDiffAt elaborator - have hψi : MDiffAt Ψi (g (φ x)) := by - rw [h] - have := mdifferentiableWithinAt_extChartAt_symm (I := I') (mem_extChartAt_target x') - exact this.mdifferentiableAt (range_mem_nhds_isInteriorPoint <| - BoundarylessManifold.isInteriorPoint' x') - unfold map_of_one_jet - refold_let g φ ψ at * - refine ⟨by simp [h, ψ], hψi.comp x hgφ, ?_⟩ - rw [mfderiv_comp x hψi hgφ, mfderiv_comp x hg hφ, mfderiv_eq_fderiv] - change (mfderiv 𝓘(𝕜, E') I' Ψi (g (φ x))) (fderiv 𝕜 g (φ x) <| mfderiv I 𝓘(𝕜, E) φ x u) = u' - rw [h] at hψi - rw [h'', h, ← mfderiv_comp_apply x' hψi hψ] - have : Ψi ∘ ψ =ᶠ[𝓝 x'] id := by - have : ∀ᶠ z in 𝓝 x', z ∈ ψ.source := extChartAt_source_mem_nhds x' - filter_upwards [this] with z hz - exact ψ.left_inv hz - simp [this.mfderiv_eq] - rfl -end - -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -- `F` model fiber - (n : WithTop ℕ∞) - (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul 𝕜 (V x)] - [FiberBundle F V] [VectorBundle 𝕜 F V] - -- `V` vector bundle - -lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : - mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by - by_cases hs : MDiffAt s x - · have hs' := hs.const_smul a - suffices - (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = - a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) - (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] - change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ - rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] - rfl - · by_cases ha : a = 0 - · have : a • s = 0 := by ext; simp [ha] - rw [this, ha] - change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ - simp - have hs' : ¬ MDifferentiableAt I 𝓘(𝕜, F) (a • s) x := - fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) - rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] - simp - rfl - -set_option linter.flexible false in -- FIXME -lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) - (hs : MDiffAt s x) (v : TangentSpace I x) : - letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v - letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v - mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by - set φ := chartAt H x - -- TODO: the next two have should be special cases of the same lemma - have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x - rw [← this] at hs - have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this - have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x - rw [← this] at hf - have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this - have hsf : MDiffAt (s • f) x := hs.smul hf - simp [mfderiv, hsf, hs, hf] - have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := - ModelWithCorners.uniqueDiffWithinAt_image I - erw [fderivWithin_smul uniq hs' hf'] - simp [φ.left_inv (ChartedSpace.mem_chart_source x)] - rfl - -end general_lemmas - -section extend -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] - -- `F` model fiber - (n : WithTop ℕ∞) - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] - -- `V` vector bundle - --- TODO: either change `localFrame` to make sure it is everywhere smooth --- or introduce a cut-off here. First option is probaly better. --- TODO: comment why we chose the second option in the end, and adapt the definition accordingly --- new definition: smooth a bump function, then smul with localExtensionOn -/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. -The details of the extension are mostly unspecified: for covariant derivatives, the value of -`s` at points other than `x` will not matter (except for shorter proofs). -Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. --/ -noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - (x' : M) → V x' := - letI b := Basis.ofVectorSpace ℝ F - letI t := trivializationAt F V x - -- Choose a smooth bump function ψ near `x`, supported within t.baseSet - -- and return ψ • V₀ instead. - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - ψ.toFun • localExtensionOn b t v - -variable {I F} - --- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for --- *well-chosen* extensions (such as ours). --- so, one may argue this is mathematically wrong, but it encodes the "choice some extension --- with this and that property" nicely --- a different proof would be to argue only the value at a point matters for cov -@[simp] -lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : - extend I F (v + v') = extend I F v + extend I F v' := by - simp [extend, localExtensionOn_add] - -@[simp] -lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : - extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module - -@[simp] -lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : - extend I F (0 : V x) = 0 := by simp [extend, localExtensionOn_zero] - -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - extend I F v x = v := by - simpa [extend] using - localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v - -variable (I F) - -lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% (extend I F σ₀)) := by - letI t := trivializationAt F V x - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - let hψ := - Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - exact .smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 - (contMDiffOn_localExtensionOn _ hx _) - -lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDiff (T% (extend I F σ₀)) := - contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) - -theorem contDiff_extend - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] - (x : E) (y : E') : ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by - rw [contDiff_iff_contDiffAt] - intro x' - rw [← contMDiffAt_iff_contDiffAt] - simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' - -end extend - section any_field variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -- [FiniteDimensional 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} @@ -1170,9 +827,6 @@ variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] local notation "TM" => TangentSpace I -instance (f : F) : CoeOut (TangentSpace 𝓘(ℝ, F) f) F := - ⟨fun x ↦ x⟩ - variable {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} noncomputable @@ -1237,207 +891,6 @@ section to_trivialization variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] -lemma Trivialization.map_add - [VectorBundle ℝ F V] - {x : M} (hx : x ∈ e.baseSet) (v v' : V x) : - (e ⟨x, v + v'⟩).2 = (e ⟨x, v⟩).2 + (e ⟨x, v'⟩).2 := - e.linear ℝ hx |>.map_add v v' - -lemma Trivialization.symm_map_add [VectorBundle ℝ F V] {x : M} (f f' : F) : - e.symm x (f + f') = e.symm x f + e.symm x f' := - (symmL ℝ e x).map_add f f' - -lemma Trivialization.symm_map_smul [VectorBundle ℝ F V] {x : M} (a : ℝ) (f : F) : - e.symm x (a • f) = a • e.symm x f := - (symmL ℝ e x).map_smul a f - -lemma Trivialization.map_smul - [VectorBundle ℝ F V] - {x : M} (hx : x ∈ e.baseSet) (a : ℝ) (v : V x) : - (e ⟨x, a • v⟩).2 = a • (e ⟨x, v⟩).2 := - e.linear ℝ hx |>.map_smul a v - -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] - [(x : M) → AddCommGroup (V x)] - [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] in -lemma Trivialization.baseSet_mem_nhds {x : M} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := - e.open_baseSet.mem_nhds_iff.mpr hx - -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] - [(x : M) → AddCommGroup (V x)] in -lemma Trivialization.preimage_baseSet_mem_nhds {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := - FiberBundle.continuous_proj F V |>.continuousAt <| e.baseSet_mem_nhds hv - -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] - [(x : M) → AddCommGroup (V x)] [(x : M) → TopologicalSpace (V x)] in -lemma Trivialization.baseSet_prod_univ_mem_nhds {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - e.baseSet ×ˢ univ ∈ 𝓝 (e v) := by - rw [← mk_proj_snd' e hv] - exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem - -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] - [FiberBundle F V] [MemTrivializationAtlas e] [(x : M) → AddCommGroup (V x)] in -lemma Trivialization.comp_invFun_eventuallyEq - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : e ∘ e.invFun =ᶠ[𝓝 (e v)] id := by - filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp using - apply_symm_apply e <| (mem_target e).2 hp.1 - -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] [MemTrivializationAtlas e] - [(x : M) → AddCommGroup (V x)] in -lemma Trivialization.invFun_comp_eventuallyEq - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : e.invFun ∘ e =ᶠ[𝓝 v] id := by - filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw using - symm_apply_apply e <| (mem_source e).mpr hw - -variable (I) in -omit [MemTrivializationAtlas e] [IsManifold I 1 M] in -lemma Trivialization.fst_comp_eventuallyEq - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := by - filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using coe_fst' e hy - -omit [IsManifold I 1 M] in -lemma Trivialization.mdifferentiableAt - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {x : M} (hx : x ∈ e.baseSet) (v : V x) : -MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by - have : ⟨x, v⟩ ∈ e.source := (coe_mem_source e).mpr hx - have foo := e.contMDiffOn (IB := I) (n := 1) v this - have := foo.contMDiffAt (e.open_source.mem_nhds this) - exact this.mdifferentiableAt zero_ne_one.symm - -omit [IsManifold I 1 M] in -lemma Trivialization.mdifferentiableAt_invFun - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {x : M} (hx : x ∈ e.baseSet) (f : F) : - MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (x, f) := by - have : ⟨x, f⟩ ∈ e.target := (mk_mem_target e).mpr hx - have foo := e.contMDiffOn_symm (IB := I) (n := 1) _ this - have := foo.contMDiffAt (e.open_target.mem_nhds this) - exact this.mdifferentiableAt zero_ne_one.symm - --- Note: The definition below (ab)uses definitional --- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` --- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` --- which is $T_{π(v)} M × F$. -variable (I) in -noncomputable -def Trivialization.deriv (v : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] TangentSpace I v.proj × F := - mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v - -omit [IsManifold I 1 M] in -lemma Trivialization.bijective_deriv - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Function.Bijective (e.deriv I v) := by - have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 - rw [mk_proj_snd' e hv] at D₁ - have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 - constructor - · apply injective_mfderiv_of_eventually_leftInverse v D₁ D₂ - apply e.invFun_comp_eventuallyEq hv - · have : v = e.invFun (e v) := - (Eventually.self_of_nhds <| e.invFun_comp_eventuallyEq hv).symm - apply surjective_mfderiv_of_eventually_rightInverse this D₂ D₁ - (e.comp_invFun_eventuallyEq hv) - -omit [NormedSpace ℝ F] - [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] - [FiberBundle F V] [MemTrivializationAtlas e] in -lemma Trivialization.symm_apply_apply_mk_eventuallyEq - {x : M} (hx : x ∈ e.baseSet) (σ : Π x, V x) : - (T% fun x' ↦ e.symm x' (e (T% σ x')).2) =ᶠ[𝓝 x] T% σ := by - filter_upwards [e.baseSet_mem_nhds hx] with y hy - simp [symm_apply_apply_mk e hy (σ y)] - -omit [NormedSpace ℝ F] [(x : M) → AddCommGroup (V x)] - [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] - [FiberBundle F V] [MemTrivializationAtlas e] in -lemma Trivialization.apply_section_eventuallyEq - {x : M} (hx : x ∈ e.baseSet) (σ : Π x, V x) : - e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by - filter_upwards [e.baseSet_mem_nhds hx] with y hy - ext - · exact coe_coe_fst e hy - · simp - -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] -[(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [MemTrivializationAtlas e] in -@[simp] -lemma Trivialization.apply_symm_eventuallyEq {x : M} (hx : x ∈ e.baseSet) (s : M → F) : - (fun x ↦ (e ⟨x, e.symm x (s x)⟩).2) =ᶠ[𝓝 x] s := by - filter_upwards [e.baseSet_mem_nhds hx] with y hy - rw [e.apply_mk_symm hy] - -omit [IsManifold I 1 M] in -lemma Trivialization.mdifferentiableAt_section_of_function - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {x : M} (hx : x ∈ e.baseSet) {s : M → F} - (hs : MDiffAt s x) : - MDiffAt ((fun x' ↦ (⟨x', e.symm x' (s x')⟩ : TotalSpace F V))) x := by - rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] - have := e.apply_symm_eventuallyEq hx s - exact hs.congr_of_eventuallyEq this - -omit [IsManifold I 1 M] in -noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := - (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker - -omit [IsManifold I 1 M] in -lemma Trivialization.comap_vert - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap - (Submodule.prod ⊥ ⊤) := by - ext x - have : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := e.fst_comp_eventuallyEq I hv - unfold vert - rw [← this.mfderiv_eq] - have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := - e.mdifferentiableAt hv _ - rw [mfderiv_comp v mdifferentiableAt_fst mdiffe] - simp - rfl - --- FIXME: is this really missing?? -omit [NormedSpace ℝ F] [(x : M) → Module ℝ (V x)] - [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [MemTrivializationAtlas e] in -lemma Trivialization.eq_of {x : M} {v v' : V x} - (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : - v = v' := by - have := e.symm_proj_apply v hx - rw [hvv'] at this - grind [e.symm_proj_apply v' hx] - -omit [IsManifold I 1 M] in -lemma Trivialization.mfderiv_comp_section - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) - (u : TangentSpace I x) (hx : x ∈ e.baseSet) : - letI s := fun x ↦ (e (σ x)).2 - (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by - have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e (σ x) := - e.mdifferentiableAt hx _ - have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x = - (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := - mfderiv_comp x mdiffe hσ - have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = - e.deriv I (σ x) ((mfderiv% T%σ x) u) := by - rw [this] - rfl - erw [← this] - let s := fun x ↦ (e (σ x)).2 - change mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = (u, mfderiv% s x u) - rw [(e.apply_section_eventuallyEq hx _).mfderiv_eq] - erw [mfderiv_prodMk, mfderiv_id] - · change (ContinuousLinearMap.id _ _).prod (mfderiv% s x) u = _ - simp - · apply mdifferentiableAt_id - · exact (mdifferentiableAt_section_iff I e σ hx).mp hσ noncomputable def Trivialization.pushCovDer @@ -1463,12 +916,6 @@ lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensio unfold pushCovDer rw [this] -omit [IsManifold I 1 M] in -@[simp] -lemma mdifferentiableAt_section_trivial_iff {s : M → F} {x : M} : - MDiffAt (T% s) x ↔ MDiffAt s x := by - rw [mdifferentiableAt_section I] - simp variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -1482,7 +929,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn have hs : MDiffAt (T% s) x := e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer - rw [hcov.addX hX hX' hs, e.map_add hx] + rw [hcov.addX hX hX' hs, e.map_add ℝ hx] smulX {X σ g x} hX hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := @@ -1507,12 +954,12 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ' unfold Trivialization.pushCovDer - rw [← e.map_add hx] + rw [← e.map_add ℝ hx] congr rw [← hcov.addσ hX hs hs' hx] congr ext y - simp [e.symm_map_add, s, s'] + simp [e.symm_map_add ℝ, s, s'] leibniz {X σ g x} hX hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := @@ -1524,7 +971,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn rw [this, hcov.leibniz hX hs hg hx] suffices g x • (e ⟨x, cov X s x⟩).2 + (bar (g x)) ((mfderiv% g x) (X x)) • (e ⟨x, s x⟩).2 = g x • (e ⟨x, cov X (fun x' ↦ e.symm x' (σ x')) x⟩).2 + - (bar (g x)) ((mfderiv% g x) (X x)) • σ x by simpa [e.map_add hx, e.map_smul hx] + (bar (g x)) ((mfderiv% g x) (X x)) • σ x by simpa [e.map_add ℝ hx, e.map_smul hx] congr rw [e.apply_mk_symm hx] @@ -1583,40 +1030,6 @@ lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalS change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 simp -lemma LinearMap.comap_isCompl {R R₂ M M₂ : Type*} - [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] - {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] - [AddCommMonoid M₂] [Module R₂ M₂] - {f : M →ₛₗ[σ₁₂] M₂} (hf : Function.Bijective f) - {p q : Submodule R₂ M₂} (h : IsCompl p q) : - IsCompl (Submodule.comap f p) (Submodule.comap f q) := by - rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * - constructor - · rw [← Submodule.comap_inf, h.1] - simp [LinearMap.ker_eq_bot_of_injective hf.1] - · rw [← Submodule.comap_sup_of_injective, h.2] - · exact Submodule.comap_top f - · exact hf.1 - · intro x hx - exact hf.2 x - · intro x hx - exact hf.2 x - -lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} - [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] - {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] - [AddCommMonoid M₂] [Module R₂ M₂] - (f : M ≃ₛₗ[σ₁₂] M₂) {p q : Submodule R₂ M₂} (h : IsCompl p q) : - IsCompl (Submodule.comap f.toLinearMap p) (Submodule.comap f.toLinearMap q) := by - rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * - constructor - · rw [← Submodule.comap_inf, h.1] - simp - · rw [← Submodule.comap_sup_of_injective, h.2] - · exact Submodule.comap_top f.toLinearMap - · exact f.injective - · simp - · simp omit [ContMDiffVectorBundle 1 F V I] in lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean new file mode 100644 index 00000000000000..7fe8d0aa948a0d --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -0,0 +1,675 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary + +/-! +# Supporting lemmas for CovariantDerivative.Basic + +TODO: PR all this to appropriate places. + +-/ + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +@[expose] public section delaborators + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` +open Lean PrettyPrinter Delaborator SubExpr + +@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do + whenPPOption getPPNotation do + let args := (← getExpr).getAppArgs + if args.size < 22 then failure + let pt : Term ← withNaryArg 21 <| delab + let f := args[20]! + try + if let .lam _ _ b _ := f then + if b.isAppOf ``Bundle.TotalSpace.mk' then + let s := b.getAppArgs[4]!.getAppFn + if s matches .fvar .. then + let ss ← PrettyPrinter.delab s + return ← `(MDiffAt (T% $ss) $pt) + throwError "nope" + catch _ => + let x : Term ← withNaryArg 20 <| delab + return ← `(MDiffAt $x $pt) + +end delaborators + +@[expose] public section tangent_bundle_normedSpace + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + +instance (f : F) : CoeOut (TangentSpace 𝓘(ℝ, F) f) F := + ⟨fun x ↦ x⟩ + +end tangent_bundle_normedSpace + +@[expose] public section mfderiv + +open Function + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +lemma injective_mfderiv_of_eventually_leftInverse + {f : M → M'} (x : M) {g : M' → M} + (hg : MDifferentiableAt I' I g (f x)) (hf : MDifferentiableAt I I' f x) + (hfg : g ∘ f =ᶠ[𝓝 x] id) : Injective (mfderiv I I' f x) := by + have := mfderiv_comp x hg hf + rw [hfg.mfderiv_eq] at this + have : LeftInverse (mfderiv I' I g (f x)) (mfderiv I I' f x) := by + intro u + simpa using congr($this u).symm + exact LeftInverse.injective this + +lemma surjective_mfderiv_of_eventually_rightInverse + {f : M → M'} {x : M} {y : M'} (hxy : y = f x) {g : M' → M} + (hg : MDifferentiableAt I' I g y) (hf : MDifferentiableAt I I' f x) + (hfg : g ∘ f =ᶠ[𝓝 x] id) : Surjective (mfderiv I' I g y) := by + rw [hxy] at hg + have := mfderiv_comp x hg hf + rw [hfg.mfderiv_eq] at this + have : RightInverse (mfderiv I I' f x) (mfderiv I' I g (f x)) := by + intro u + simpa using congr($this u).symm + rw [← hxy] at this + exact RightInverse.surjective this + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + +lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : + mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by + by_cases hs : MDiffAt s x + · have hs' := hs.const_smul a + suffices + (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = + a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) + (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] + change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ + rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] + rfl + · by_cases ha : a = 0 + · have : a • s = 0 := by ext; simp [ha] + rw [this, ha] + change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ + simp + have hs' : ¬ MDifferentiableAt I 𝓘(𝕜, F) (a • s) x := + fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) + rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] + simp + rfl + +set_option linter.flexible false in -- FIXME +lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) + (hs : MDiffAt s x) (v : TangentSpace I x) : + letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v + letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v + mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by + set φ := chartAt H x + -- TODO: the next two have should be special cases of the same lemma + have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [← this] at hs + have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [← this] at hf + have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hsf : MDiffAt (s • f) x := hs.smul hf + simp [mfderiv, hsf, hs, hf] + have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := + ModelWithCorners.uniqueDiffWithinAt_image I + erw [fderivWithin_smul uniq hs' hf'] + simp [φ.left_inv (ChartedSpace.mem_chart_source x)] + rfl +end mfderiv + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section general_lemmas -- those lemmas should move + +section linear_algebra +variable (𝕜 : Type*) [Field 𝕜] + {E : Type*} [AddCommGroup E] [Module 𝕜 E] + {E' : Type*} [AddCommGroup E'] [Module 𝕜 E'] + +lemma exists_map_of (u : E) (u' : E') : + ∃ φ : E →ₗ[𝕜] E', (u = 0 → u' = 0) → φ u = u' := by + by_cases h : u = 0 + · simp [h] + tauto + · have indep : LinearIndepOn 𝕜 id {u} := LinearIndepOn.singleton h + let s := indep.extend (subset_univ _) + have hus : u ∈ s := singleton_subset_iff.mp <| indep.subset_extend (subset_univ _) + use (Basis.extend indep).constr (M' := E') (S := 𝕜) fun _ ↦ u' + simpa [h, Basis.extend_apply_self] using (Basis.extend indep).constr_basis _ _ ⟨u, hus⟩ + +open Classical in +noncomputable def map_of (u : E) (u' : E') : E →ₗ[𝕜] E' := (exists_map_of 𝕜 u u').choose + +variable {𝕜} +lemma map_of_spec (u : E) (u' : E') (h : u = 0 → u' = 0) : map_of 𝕜 u u' u = u' := + (exists_map_of 𝕜 u u').choose_spec h +end linear_algebra + + +section +variable + {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + + +variable (𝕜) in +noncomputable def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := + fun x ↦ e' + map_of 𝕜 u u' (x - e) + +lemma map_of_loc_one_jet_spec [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] + (e u : E) (e' u' : E') (hu : u = 0 → u' = 0) : + map_of_loc_one_jet 𝕜 e u e' u' e = e' ∧ + DifferentiableAt 𝕜 (map_of_loc_one_jet 𝕜 e u e' u') e ∧ + fderiv 𝕜 (map_of_loc_one_jet 𝕜 e u e' u') e u = u' := by + unfold map_of_loc_one_jet + let φ := (map_of 𝕜 u u').toContinuousLinearMap + have diff : Differentiable 𝕜 (map_of 𝕜 u u') := + (map_of 𝕜 u u').toContinuousLinearMap.differentiable + refine ⟨by simp, ?_, ?_⟩ + · apply (differentiableAt_const e').add + apply diff.differentiableAt.comp + fun_prop + · simp only [map_sub, fderiv_const_add] + rw [fderiv_sub_const] + change (fderiv 𝕜 φ e) u = _ + rw [φ.hasFDerivAt.fderiv] + exact map_of_spec u u' hu + +noncomputable +def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : + M → M' := + letI ψ := extChartAt I' x' + letI φ := extChartAt I x + ψ.symm ∘ + (map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ + φ + +-- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. + +/-- For any `(x, u) ∈ TM` and `(x', u') ∈ TM'`, `map_of_one_jet u u'` sends `x` to `x'` and +its derivative sends `u` to `u'`. We need to assume the target manifold `M'` has no boundary +since we cannot hope the result is `x` and `x'` are boundary points and `u` is inward +while `u'` is outward. +-/ +lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] + [BoundarylessManifold I' M'] + [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] + {x : M} (u : TangentSpace I x) {x' : M'} + (u' : TangentSpace I' x') (hu : u = 0 → u' = 0) : + map_of_one_jet u u' x = x' ∧ + MDiffAt (map_of_one_jet u u') x ∧ + mfderiv I I' (map_of_one_jet u u') x u = u' := by + let ψ := extChartAt I' x' + let φ := extChartAt I x + let g := map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') + let Ψ : M' → E' := ψ -- FIXME: this is working around a limitation of MDiffAt elaborator + have hψ : MDiffAt Ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') + let Φ : M → E := φ -- FIXME: this is working around a limitation of MDiffAt elaborator + have hφ : MDiffAt Φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) + replace hu : mfderiv I 𝓘(𝕜, E) φ x u = 0 → mfderiv I' 𝓘(𝕜, E') ψ x' u' = 0 := by + have : Function.Injective (mfderiv I 𝓘(𝕜, E) φ x) := + (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x)).injective + rw [injective_iff_map_eq_zero] at this + have := map_zero (mfderiv I' 𝓘(𝕜, E') ψ x') + grind + rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) + (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') hu with + ⟨h : g (φ x) = ψ x', h', h''⟩ + have hg : MDiffAt g (φ x) := mdifferentiableAt_iff_differentiableAt.mpr h' + have hgφ : MDiffAt (g ∘ φ) x := h'.comp_mdifferentiableAt hφ + let Ψi : E' → M' := ψ.symm -- FIXME: this is working around a limitation of MDiffAt elaborator + have hψi : MDiffAt Ψi (g (φ x)) := by + rw [h] + have := mdifferentiableWithinAt_extChartAt_symm (I := I') (mem_extChartAt_target x') + exact this.mdifferentiableAt (range_mem_nhds_isInteriorPoint <| + BoundarylessManifold.isInteriorPoint' x') + unfold map_of_one_jet + refold_let g φ ψ at * + refine ⟨by simp [h, ψ], hψi.comp x hgφ, ?_⟩ + rw [mfderiv_comp x hψi hgφ, mfderiv_comp x hg hφ, mfderiv_eq_fderiv] + change (mfderiv 𝓘(𝕜, E') I' Ψi (g (φ x))) (fderiv 𝕜 g (φ x) <| mfderiv I 𝓘(𝕜, E) φ x u) = u' + rw [h] at hψi + rw [h'', h, ← mfderiv_comp_apply x' hψi hψ] + have : Ψi ∘ ψ =ᶠ[𝓝 x'] id := by + have : ∀ᶠ z in 𝓝 x', z ∈ ψ.source := extChartAt_source_mem_nhds x' + filter_upwards [this] with z hz + exact ψ.left_inv hz + simp [this.mfderiv_eq] + rfl +end + +end general_lemmas + +section extend +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] + -- `V` vector bundle + +-- TODO: either change `localFrame` to make sure it is everywhere smooth +-- or introduce a cut-off here. First option is probaly better. +-- TODO: comment why we chose the second option in the end, and adapt the definition accordingly +-- new definition: smooth a bump function, then smul with localExtensionOn +/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ +noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + (x' : M) → V x' := + letI b := Basis.ofVectorSpace ℝ F + letI t := trivializationAt F V x + -- Choose a smooth bump function ψ near `x`, supported within t.baseSet + -- and return ψ • V₀ instead. + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + ψ.toFun • localExtensionOn b t v + +variable {I F} + +-- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for +-- *well-chosen* extensions (such as ours). +-- so, one may argue this is mathematically wrong, but it encodes the "choice some extension +-- with this and that property" nicely +-- a different proof would be to argue only the value at a point matters for cov +@[simp] +lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : + extend I F (v + v') = extend I F v + extend I F v' := by + simp [extend, localExtensionOn_add] + +@[simp] +lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : + extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module + +@[simp] +lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : + extend I F (0 : V x) = 0 := by simp [extend, localExtensionOn_zero] + +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + extend I F v x = v := by + simpa [extend] using + localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v + +variable (I F) + +lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% (extend I F σ₀)) := by + letI t := trivializationAt F V x + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + let hψ := + Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + exact .smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 + (contMDiffOn_localExtensionOn _ hx _) + +lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + MDiff (T% (extend I F σ₀)) := + contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) + +theorem contDiff_extend + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] + (x : E) (y : E') : ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by + rw [contDiff_iff_contDiffAt] + intro x' + rw [← contMDiffAt_iff_contDiffAt] + simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' + +end extend + +section trivilization_topology + +variable {B F Z : Type*} [TopologicalSpace B] + [TopologicalSpace F] + +section any_proj +variable [TopologicalSpace Z] {proj : Z → B} (e : Trivialization F proj) +lemma Trivialization.baseSet_mem_nhds {x : B} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := + e.open_baseSet.mem_nhds_iff.mpr hx + +lemma Trivialization.baseSet_prod_univ_mem_nhds {v : Z} + (hv : proj v ∈ e.baseSet) : e.baseSet ×ˢ univ ∈ 𝓝 (e v) := by + rw [← mk_proj_snd' e hv] + exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem + +lemma Trivialization.comp_invFun_eventuallyEq + {v : Z} (hv : proj v ∈ e.baseSet) : e ∘ e.invFun =ᶠ[𝓝 (e v)] id := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp using + apply_symm_apply e <| (mem_target e).2 hp.1 + +end any_proj + +section fiber_bundle +variable {E : B → Type*} [TopologicalSpace (TotalSpace F E)] + (e : Trivialization F (π F E)) + [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] + +lemma Trivialization.preimage_baseSet_mem_nhds + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := + FiberBundle.continuous_proj F E |>.continuousAt <| e.baseSet_mem_nhds hv + +lemma Trivialization.fst_comp_eventuallyEq + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Prod.fst ∘ e =ᶠ[𝓝 v] (π F E) := by + filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using coe_fst' e hy + +lemma Trivialization.invFun_comp_eventuallyEq + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + e.invFun ∘ e =ᶠ[𝓝 v] id := by + filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw using + symm_apply_apply e <| (mem_source e).mpr hw + +end fiber_bundle + +section +variable {B F : Type*} {E : B → Type*} [TopologicalSpace B] + [TopologicalSpace F] [TopologicalSpace (TotalSpace F E)] + [(x : B) → Zero (E x)] + (e : Trivialization F (π F E)) + +lemma Trivialization.eq_of {x : B} {v v' : E x} + (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : + v = v' := by + have := e.symm_proj_apply v hx + rw [hvv'] at this + grind [e.symm_proj_apply v' hx] + +@[simp] +lemma Trivialization.apply_symm_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + (fun x ↦ (e ⟨x, e.symm x (s x)⟩).2) =ᶠ[𝓝 x] s := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + rw [e.apply_mk_symm hy] + +variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] + +-- FIXME super weird elaborator bug: removing the +-- omitted assumption from the variable line breaks the lemma +omit [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in +lemma Trivialization.symm_apply_apply_mk_eventuallyEq + {b : B} (hb : b ∈ e.baseSet) (σ : Π x, E x) : + (T% fun x' ↦ e.symm x' (e (T% σ x')).2) =ᶠ[𝓝 b] T% σ := by + filter_upwards [e.baseSet_mem_nhds hb] with y hy + simp [symm_apply_apply_mk e hy (σ y)] + +-- FIXME super weird elaborator bug: removing the +-- omitted assumption from the variable line breaks the lemma +omit [(x : B) → Zero (E x)] [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in +lemma Trivialization.apply_section_eventuallyEq + {x : B} (hx : x ∈ e.baseSet) (σ : Π x, E x) : + e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + ext + · exact coe_coe_fst e hy + · simp + +end + +end trivilization_topology + +section topological_vector_bundle + +section +variable {R B F : Type*} {E : B → Type*} [Semiring R] + [TopologicalSpace F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + (e : Trivialization F (π F E)) + [AddCommMonoid F] [Module R F] [(x : B) → AddCommMonoid (E x)] [(x : B) → Module R (E x)] + +lemma Trivialization.map_smul [Trivialization.IsLinear R e] + {b : B} (hb : b ∈ e.baseSet) (a : R) (v : E b) : + (e ⟨b, a • v⟩).2 = a • (e ⟨b, v⟩).2 := + e.linear R hb |>.map_smul a v + +variable (R) + +lemma Trivialization.map_add [Trivialization.IsLinear R e] + {b : B} (hb : b ∈ e.baseSet) (v v' : E b) : + (e ⟨b, v + v'⟩).2 = (e ⟨b, v⟩).2 + (e ⟨b, v'⟩).2 := + e.linear R hb |>.map_add v v' + +end + +section + +variable (R : Type*) {B F : Type*} {E : B → Type*} + [NontriviallyNormedField R] [(x : B) → AddCommMonoid (E x)] + [(x : B) → Module R (E x)] [NormedAddCommGroup F] + [NormedSpace R F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + [(x : B) → TopologicalSpace (E x)] + [FiberBundle F E] (e : Trivialization F (π F E)) + +lemma Trivialization.symm_map_add [Trivialization.IsLinear R e] {x : B} + (f f' : F) : + e.symm x (f + f') = e.symm x f + e.symm x f' := + (symmL R e x).map_add f f' + +variable {R} + +lemma Trivialization.symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : + e.symm x (a • f) = a • e.symm x f := + (symmL R e x).map_smul a f + +end + +end topological_vector_bundle + +section to_trivialization +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] + +variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] + + +lemma Trivialization.mdifferentiableAt + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) (v : V x) : +MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by + have : ⟨x, v⟩ ∈ e.source := (coe_mem_source e).mpr hx + have foo := e.contMDiffOn (IB := I) (n := 1) v this + have := foo.contMDiffAt (e.open_source.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +lemma Trivialization.mdifferentiableAt_invFun + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) (f : F) : + MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (x, f) := by + have : ⟨x, f⟩ ∈ e.target := (mk_mem_target e).mpr hx + have foo := e.contMDiffOn_symm (IB := I) (n := 1) _ this + have := foo.contMDiffAt (e.open_target.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +-- Note: The definition below (ab)uses definitional +-- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` +-- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` +-- which is $T_{π(v)} M × F$. +variable (I) in +noncomputable +def Trivialization.deriv (v : TotalSpace F V) : + TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] TangentSpace I v.proj × F := + mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v + +lemma Trivialization.bijective_deriv + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Function.Bijective (e.deriv I v) := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [mk_proj_snd' e hv] at D₁ + have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + constructor + · apply injective_mfderiv_of_eventually_leftInverse v D₁ D₂ + apply e.invFun_comp_eventuallyEq hv + · have : v = e.invFun (e v) := + (Eventually.self_of_nhds <| e.invFun_comp_eventuallyEq hv).symm + apply surjective_mfderiv_of_eventually_rightInverse this D₂ D₁ + (e.comp_invFun_eventuallyEq hv) + + +lemma Trivialization.mdifferentiableAt_section_of_function + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) {s : M → F} + (hs : MDiffAt s x) : + MDiffAt ((fun x' ↦ (⟨x', e.symm x' (s x')⟩ : TotalSpace F V))) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] + have := e.apply_symm_eventuallyEq hx s + exact hs.congr_of_eventuallyEq this + +noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := + (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker + +lemma Trivialization.comap_vert + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap + (Submodule.prod ⊥ ⊤) := by + ext x + have : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := e.fst_comp_eventuallyEq hv + unfold vert + rw [← this.mfderiv_eq] + have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := + e.mdifferentiableAt hv _ + rw [mfderiv_comp v mdifferentiableAt_fst mdiffe] + simp + rfl + +lemma Trivialization.mfderiv_comp_section + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) + (u : TangentSpace I x) (hx : x ∈ e.baseSet) : + letI s := fun x ↦ (e (σ x)).2 + (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by + have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e (σ x) := + e.mdifferentiableAt hx _ + have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x = + (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := + mfderiv_comp x mdiffe hσ + have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = + e.deriv I (σ x) ((mfderiv% T%σ x) u) := by + rw [this] + rfl + erw [← this] + let s := fun x ↦ (e (σ x)).2 + change mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = (u, mfderiv% s x u) + rw [(e.apply_section_eventuallyEq hx _).mfderiv_eq] + erw [mfderiv_prodMk, mfderiv_id] + · change (ContinuousLinearMap.id _ _).prod (mfderiv% s x) u = _ + simp + · apply mdifferentiableAt_id + · exact (mdifferentiableAt_section_iff I e σ hx).mp hσ + +@[simp] +lemma mdifferentiableAt_section_trivial_iff {s : M → F} {x : M} : + MDiffAt (T% s) x ↔ MDiffAt s x := by + rw [mdifferentiableAt_section I] + simp + + +end to_trivialization + + +section linear_algebra_isCompl +lemma LinearMap.comap_isCompl {R R₂ M M₂ : Type*} + [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] + {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] + [AddCommMonoid M₂] [Module R₂ M₂] + {f : M →ₛₗ[σ₁₂] M₂} (hf : Function.Bijective f) + {p q : Submodule R₂ M₂} (h : IsCompl p q) : + IsCompl (Submodule.comap f p) (Submodule.comap f q) := by + rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * + constructor + · rw [← Submodule.comap_inf, h.1] + simp [LinearMap.ker_eq_bot_of_injective hf.1] + · rw [← Submodule.comap_sup_of_injective, h.2] + · exact Submodule.comap_top f + · exact hf.1 + · intro x hx + exact hf.2 x + · intro x hx + exact hf.2 x + +lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} + [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] + {σ₁₂ : R →+* R₂} {σ₂₁ : R₂ →+* R} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] + [AddCommMonoid M₂] [Module R₂ M₂] + (f : M ≃ₛₗ[σ₁₂] M₂) {p q : Submodule R₂ M₂} (h : IsCompl p q) : + IsCompl (Submodule.comap f.toLinearMap p) (Submodule.comap f.toLinearMap q) := by + rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * + constructor + · rw [← Submodule.comap_inf, h.1] + simp + · rw [← Submodule.comap_sup_of_injective, h.2] + · exact Submodule.comap_top f.toLinearMap + · exact f.injective + · simp + · simp + +end linear_algebra_isCompl + + + From 9b420549a1a4f48ab1feda951cba8cb3df9b3b9b Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 25 Feb 2026 18:35:06 +0100 Subject: [PATCH 420/601] Start lifting vectors --- Mathlib.lean | 3 +- .../CovariantDerivative/Lift.lean | 87 +++++++++++++++++++ .../CovariantDerivative/Prelim.lean | 63 ++++++++++++-- 3 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean diff --git a/Mathlib.lean b/Mathlib.lean index d9444601ef47d7..a970be344c6180 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4378,9 +4378,10 @@ public import Mathlib.Geometry.Manifold.SmoothApprox public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic -public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean new file mode 100644 index 00000000000000..85f7b5006df93b --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -0,0 +1,87 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic + +/-! +# Lifting vectors using covariant derivatives + +TODO: add a more complete doc-string + +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +section +variable {B : Type*} (E : B → Type*) {F : Type*} + +/-- Given a bundle `π : E → B`, the diagonal section of `π^*E → E`. -/ +def Bundle.pullback_diag (e : TotalSpace F E) : (TotalSpace.proj *ᵖ E) e := + e.2 +end + + +section +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] + {cov : ((x : M) → TangentSpace I x) → (M → F) → M → F} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + + +noncomputable +def IsCovariantDerivativeOn.lift_vec (x : M) (f : F) : + TangentSpace I x →L[ℝ] TangentSpace I x × F := + .prod (.id ℝ _) (-evalL ℝ F F f ∘L hcov.one_form x) + +@[simp] +lemma IsCovariantDerivativeOn.lift_vec_apply (x : M) (f : F) (u : TangentSpace I x) : + hcov.lift_vec x f u = (u , -hcov.one_form x u f) := + rfl + +@[simp] +lemma IsCovariantDerivativeOn.fst_comp_lift_vec (x : M) (f : F) : + .fst ℝ _ _ ∘L hcov.lift_vec x f = .id ℝ _ := by + ext u + simp + +@[simp] +lemma IsCovariantDerivativeOn.projection_lift_vec (x : M) (f : F) : + (hcov.projection x f) ∘L (hcov.lift_vec x f) = 0 := by + ext u + simp + +end + +section +variable +{E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] {V : M → Type*} + [TopologicalSpace (TotalSpace F V)] [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] + [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [FiniteDimensional ℝ E] + [FiniteDimensional ℝ F] [T2Space M] + [IsManifold I ∞ M] [VectorBundle ℝ F V] {cov : CovariantDerivative I F V} + [ContMDiffVectorBundle 1 F V I] + +/-- Horizontal lift of a vector tangent to the base at a point in the corresponding fiber. -/ +noncomputable +def CovariantDerivative.lift_vec (v : TotalSpace F V) : + TangentSpace I v.proj →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, F)) v := + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + letI tlift := d_covDerOn.lift_vec v.proj (t v).2 + t.derivInv I v ∘L tlift +end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 7fe8d0aa948a0d..12a1155d0c9756 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -81,6 +81,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] +-- Note: this lemma is no longer used, but still pretty nice lemma injective_mfderiv_of_eventually_leftInverse {f : M → M'} (x : M) {g : M' → M} (hg : MDifferentiableAt I' I g (f x)) (hf : MDifferentiableAt I I' f x) @@ -92,6 +93,7 @@ lemma injective_mfderiv_of_eventually_leftInverse simpa using congr($this u).symm exact LeftInverse.injective this +-- Note: this lemma is no longer used, but still pretty nice lemma surjective_mfderiv_of_eventually_rightInverse {f : M → M'} {x : M} {y : M'} (hxy : y = f x) {g : M' → M} (hg : MDifferentiableAt I' I g y) (hf : MDifferentiableAt I I' f x) @@ -554,21 +556,64 @@ def Trivialization.deriv (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] TangentSpace I v.proj × F := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v -lemma Trivialization.bijective_deriv +variable (I) in +noncomputable +def Trivialization.derivInv (v : TotalSpace F V) : + TangentSpace I v.proj × F →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, F)) v := + mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (e v) + +@[simp] +lemma Trivialization.derivInv_deriv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Function.Bijective (e.deriv I v) := by + (e.derivInv I v) ∘L (e.deriv I v) = .id ℝ _ := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + rw [mk_proj_snd' e hv] at D₁ + have comp := mfderiv_comp v D₁ D₂ + rw [(invFun_comp_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp + simp [deriv, derivInv, comp] + +@[simp] +lemma Trivialization.derivInv_deriv_apply + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + (e.derivInv I v (e.deriv I v u)) = u := + show ((e.derivInv I v) ∘L (e.deriv I v)) u = u by simp [hv] + +@[simp] +lemma Trivialization.deriv_derivInv + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + (e.deriv I v) ∘L (e.derivInv I v) = .id ℝ _ := by have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 rw [mk_proj_snd' e hv] at D₁ have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 - constructor - · apply injective_mfderiv_of_eventually_leftInverse v D₁ D₂ - apply e.invFun_comp_eventuallyEq hv - · have : v = e.invFun (e v) := - (Eventually.self_of_nhds <| e.invFun_comp_eventuallyEq hv).symm - apply surjective_mfderiv_of_eventually_rightInverse this D₂ D₁ - (e.comp_invFun_eventuallyEq hv) + have : e.invFun (e v) = v := by + simp [symm_apply_apply e ((mem_source e).mpr hv)] + rw [← this] at D₂ + have comp := mfderiv_comp (e v) D₂ D₁ + rw [(comp_invFun_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp + symm + convert comp <;> rw [this] + +@[simp] +lemma Trivialization.deriv_derivInv_apply + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace I v.proj × F) : + e.deriv I v (e.derivInv I v u) = u := + show ((e.deriv I v) ∘L (e.derivInv I v)) u = u by simp [hv] +lemma Trivialization.bijective_deriv + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Function.Bijective (e.deriv I v) := by + refine Function.bijective_iff_has_inverse.mpr ?_ + use e.derivInv I v + constructor + all_goals { intro u; simp [hv] } lemma Trivialization.mdifferentiableAt_section_of_function [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] From 7e62c69fedf265658796ea328a2e3903ba12eb11 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 25 Feb 2026 22:21:15 +0100 Subject: [PATCH 421/601] Define geodesics and state some lemmas --- .../CovariantDerivative/Lift.lean | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 85f7b5006df93b..7faa1b38d87e2e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -6,7 +6,7 @@ Authors: Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic - +public import Mathlib.Geometry.Manifold.IntegralCurve.Basic /-! # Lifting vectors using covariant derivatives @@ -84,4 +84,124 @@ def CovariantDerivative.lift_vec (v : TotalSpace F V) : (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) letI tlift := d_covDerOn.lift_vec v.proj (t v).2 t.derivInv I v ∘L tlift + +lemma CovariantDerivative.lift_vec_apply {v : TotalSpace F V} (u : TangentSpace I v.proj) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + letI tlift := d_covDerOn.lift_vec v.proj (t v).2 + cov.lift_vec v u = t.derivInv I v (tlift u) := rfl + + +lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace I v.proj) + (w : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + cov.lift_vec v u = w ↔ + cov.proj v w = 0 ∧ + mfderiv (I.prod 𝓘(ℝ, F)) I (TotalSpace.proj : TotalSpace F V → M) v w = u := by + constructor + · rintro rfl + constructor -- TODO: write two lemmas to apply here + · sorry + · sorry + · rintro ⟨h, h'⟩ + sorry + +-- noncomputable +-- def CovariantDerivative.lift_vec' +-- (p : TotalSpace E ((TotalSpace.proj : (TotalSpace F V → M)) *ᵖ (TangentSpace I))) : +-- TangentSpace (I.prod 𝓘(ℝ, F)) p.1 := +-- letI t := trivializationAt F V p.1.proj +-- haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn +-- (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) +-- letI tlift := d_covDerOn.lift_vec p.1.proj (t p.1).2 +-- t.derivInv I p.1 (tlift p.2) end + +section integralCurve +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} + [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} + [TopologicalSpace M] [ChartedSpace H M] (γ : ℝ → M) + (v : (x : M) → TangentSpace I x) (t₀ : ℝ) + +lemma IsMIntegralCurveAt.mdifferentiableAt (h : IsMIntegralCurveAt γ v t₀) : + ∀ᶠ t in 𝓝 t₀, MDiffAt γ t := by + filter_upwards [h] with t ht + exact ht.mdifferentiableAt + +-- Is this really missing?? +lemma IsMIntegralCurveAt_iff_mfderiv (hγ : ∀ᶠ t in 𝓝 t₀, MDiffAt γ t) : + IsMIntegralCurveAt γ v t₀ ↔ ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by + refine eventually_congr ?_ + filter_upwards [hγ] with t ht + constructor + · intro h + rw [h.mfderiv] + rw [ContinuousLinearMap.smulRight_apply] + change 1 • v (γ t) = v (γ t) + simp + · intro h + convert ht.hasMFDerivAt + ext + simp [← h] + rfl + +variable (I) in +noncomputable +def velocity (γ : ℝ → M) (t : ℝ) : TangentBundle I M := ⟨γ t, mfderiv% γ t (1 : ℝ)⟩ + + +variable [IsManifold I ∞ M] + +lemma IsMIntegralCurveAt.acceleration {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) + (hγX : IsMIntegralCurveAt γ X t₀) : + velocity I.tangent (velocity I γ) t₀ = mfderiv% (T% X) (γ t₀) (X (γ t₀)) := by + sorry +end integralCurve + +section geodesics + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] [T2Space M] + [IsManifold I ∞ M] + (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) + + +noncomputable +def CovariantDerivative.geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : + TangentSpace (I.prod 𝓘(ℝ, E)) v := cov.lift_vec v v.2 + +/-- A curve `γ : ℝ → M` is a geodesic for `cov` at `t` if it is an integral +curve of the geodesic vector field of `cov` near `t`. +Remember: `IsMIntegralCurveAt` is local, not pointwise. -/ +def CovariantDerivative.isGeodAt (γ : ℝ → M) (t : ℝ) := + IsMIntegralCurveAt (velocity I γ) cov.geodVF t + +def CovariantDerivative.isGeod (γ : ℝ → M) := ∀ t, cov.isGeodAt γ t + +-- May still need to tweak the assumption (maybe `X` should be smoother for instance). +lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) + (hγX : IsMIntegralCurveAt γ X t₀) : + cov.isGeodAt γ t₀ ↔ ∀ᶠ t in 𝓝 t₀, cov X X (γ t) = 0 := by + have := hγX.mdifferentiableAt + unfold CovariantDerivative.isGeodAt + rw [IsMIntegralCurveAt_iff_mfderiv _ _ _ hγ] + constructor + · intro h + filter_upwards [h] with t ht + replace ht : velocity I.tangent (velocity I γ) t = cov.geodVF (velocity I γ t) := by + rw [← ht] + simp [velocity] + have := hγX.acceleration hX hγ + sorry + · intro h + rw [← eventually_eventually_nhds] at h + filter_upwards [h] with t ht + sorry + +end geodesics From f866e7902df7ae1abed48b1bd60427a823d63c27 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 26 Feb 2026 21:13:55 +0100 Subject: [PATCH 422/601] Finish defining geodesics. Note: we still need to prove the geodesic vector field of a smooth connection is smooth. --- .../CovariantDerivative/Basic.lean | 4 + .../CovariantDerivative/Lift.lean | 242 +++++++++++++++--- .../CovariantDerivative/Prelim.lean | 68 ++++- 3 files changed, 273 insertions(+), 41 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index b1828f4f6cf939..0edd5bc470af1a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1013,6 +1013,10 @@ noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (cov.proj v).ker +lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + u ∈ cov.horiz v ↔ cov.proj v u = 0 := by + simp [horiz] + lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : letI t := trivializationAt F V v.proj haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 7faa1b38d87e2e..fccea63bd54f76 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -16,6 +16,41 @@ TODO: add a more complete doc-string @[expose] public section +@[expose] public section delaborators + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` +open Lean PrettyPrinter Delaborator SubExpr + +@[app_delab mfderiv] meta def delab_mfderiv : Delab := do + whenPPOption getPPNotation do + let args := (← getExpr).getAppArgs + if args.size < 22 then failure + let pt : Term ← withNaryArg 21 <| delab + let f := args[20]! + let m := mkIdent (.mkSimple "mfderiv%") + let T := mkIdent (.mkSimple "T%") + try + if let .lam _ _ b _ := f then + if b.isAppOf ``Bundle.TotalSpace.mk' then + let s := b.getAppArgs[4]!.getAppFn + if s matches .fvar .. then + let ss ← PrettyPrinter.delab s + return ← `($m ($T $ss) $pt) + throwError "nope" + catch _ => + let x : Term ← withNaryArg 20 <| delab + return ← `($m $x $pt) + +@[app_delab Bundle.TotalSpace.mk'] meta def delabTotalSpace_mk' : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +end delaborators + open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff @@ -62,6 +97,17 @@ lemma IsCovariantDerivativeOn.projection_lift_vec (x : M) (f : F) : ext u simp +lemma IsCovariantDerivativeOn.lift_vec_eq_iff + {x : M} {f : F} {u : TangentSpace I x} {w : TangentSpace I x × F} : + hcov.lift_vec x f u = w ↔ hcov.projection x f w = 0 ∧ w.1 = u := by + constructor + · intro rfl + simp + · rcases w with ⟨a, b⟩ + rintro ⟨h, rfl⟩ + simp_all + grind + end section @@ -92,6 +138,33 @@ lemma CovariantDerivative.lift_vec_apply {v : TotalSpace F V} (u : TangentSpace letI tlift := d_covDerOn.lift_vec v.proj (t v).2 cov.lift_vec v u = t.derivInv I v (tlift u) := rfl +@[simp] +lemma CovariantDerivative.lift_vec_horiz {v : TotalSpace F V} (u : TangentSpace I v.proj) : + cov.lift_vec v u ∈ cov.horiz v := by + let t := trivializationAt F V v.proj + have d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + let tlift := d_covDerOn.lift_vec v.proj (t v).2 + rw [lift_vec_apply, CovariantDerivative.mem_horiz_iff_proj] + -- TODO: cleanup + simp only [proj, IsCovariantDerivativeOn.lift_vec_apply, ContinuousLinearMap.coe_comp', + Trivialization.symmL_apply, Function.comp_apply] + rw [t.deriv_derivInv_apply (FiberBundle.mem_baseSet_trivializationAt' v.proj)] + suffices t.symm v.proj 0 = 0 by simpa + exact (t.symmL ℝ v.proj).map_zero + +@[simp] +lemma CovariantDerivative.proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : + cov.proj v (cov.lift_vec v u) = 0 := by + rw [← cov.mem_horiz_iff_proj] + exact lift_vec_horiz u + +@[simp] +lemma CovariantDerivative.mfderiv_proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : + mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v (cov.lift_vec v u) = u := by + unfold CovariantDerivative.lift_vec + simp [FiberBundle.mem_baseSet_trivializationAt' v.proj] + lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace I v.proj) (w : TangentSpace (I.prod 𝓘(ℝ, F)) v) : @@ -100,11 +173,23 @@ lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace mfderiv (I.prod 𝓘(ℝ, F)) I (TotalSpace.proj : TotalSpace F V → M) v w = u := by constructor · rintro rfl - constructor -- TODO: write two lemmas to apply here - · sorry - · sorry + simp · rintro ⟨h, h'⟩ - sorry + let t := trivializationAt F V v.proj + have hcov := t.pushCovDer_isCovariantDerivativeOn + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + have mem := FiberBundle.mem_baseSet_trivializationAt F V v.proj + apply (t.bijective_deriv mem).1 + unfold CovariantDerivative.lift_vec + simp only [ContinuousLinearMap.coe_comp', Function.comp_apply] + rw [t.deriv_derivInv_apply mem] + rw [hcov.lift_vec_eq_iff] + constructor + · change t.symm v.proj ((hcov.projection v.proj (t v).2) ((t.deriv I v) w)) = 0 at h + apply t.injective_symm mem + refold_let t + simp [h, t.symm_map_zero ℝ] + · rw [← h', t.mfderiv_proj_fst_deriv mem] -- noncomputable -- def CovariantDerivative.lift_vec' @@ -123,41 +208,70 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace M] [ChartedSpace H M] (γ : ℝ → M) (v : (x : M) → TangentSpace I x) (t₀ : ℝ) +variable (I) in +noncomputable +def velocity (γ : ℝ → M) (t : ℝ) : TangentBundle I M := ⟨γ t, mfderiv% γ t (1 : ℝ)⟩ + +@[simp] +lemma proj_velocity (γ : ℝ → M) (t : ℝ) : (velocity I γ t).proj = γ t := rfl + lemma IsMIntegralCurveAt.mdifferentiableAt (h : IsMIntegralCurveAt γ v t₀) : ∀ᶠ t in 𝓝 t₀, MDiffAt γ t := by filter_upwards [h] with t ht exact ht.mdifferentiableAt +protected lemma IsMIntegralCurveAt.mfderiv (hγ : IsMIntegralCurveAt γ v t₀) : + ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by + filter_upwards [hγ] with t ht + rw [ht.mfderiv] + rw [ContinuousLinearMap.smulRight_apply] + change 1 • v (γ t) = v (γ t) + simp + +protected lemma IsMIntegralCurveAt.velocity_eventuallyEq + (hγ : IsMIntegralCurveAt γ v t₀) : velocity I γ =ᶠ[𝓝 t₀] T%v ∘ γ := by + filter_upwards [hγ.mfderiv] with t ht + simp [ht, velocity] + -- Is this really missing?? lemma IsMIntegralCurveAt_iff_mfderiv (hγ : ∀ᶠ t in 𝓝 t₀, MDiffAt γ t) : IsMIntegralCurveAt γ v t₀ ↔ ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by - refine eventually_congr ?_ - filter_upwards [hγ] with t ht - constructor - · intro h - rw [h.mfderiv] - rw [ContinuousLinearMap.smulRight_apply] - change 1 • v (γ t) = v (γ t) - simp - · intro h - convert ht.hasMFDerivAt - ext - simp [← h] - rfl - -variable (I) in -noncomputable -def velocity (γ : ℝ → M) (t : ℝ) : TangentBundle I M := ⟨γ t, mfderiv% γ t (1 : ℝ)⟩ + refine ⟨fun h ↦ h.mfderiv, fun h ↦ ?_⟩ + filter_upwards [hγ.and h] with t ⟨ht, ht'⟩ + rw [← ht'] + convert ht.hasMFDerivAt + ext + simp + rfl +lemma IsMIntegralCurveAt.eventually_isMIntegralCurveAt + {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} + (hγX : IsMIntegralCurveAt γ X t₀) : + ∀ᶠ t in 𝓝 t₀, IsMIntegralCurveAt γ X t := + eventually_eventually_nhds.2 hγX variable [IsManifold I ∞ M] +set_option linter.flexible false in --FIXME lemma IsMIntegralCurveAt.acceleration {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) - (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) (hγX : IsMIntegralCurveAt γ X t₀) : velocity I.tangent (velocity I γ) t₀ = mfderiv% (T% X) (γ t₀) (X (γ t₀)) := by - sorry + have : velocity I γ =ᶠ[𝓝 t₀] T%X ∘ γ := hγX.velocity_eventuallyEq + have := this.mfderiv_eq (I := 𝓘(ℝ, ℝ)) (I' := I.tangent) + have foo := EventuallyEq.eq_of_nhds hγX.mfderiv + simp [velocity, this, foo] + have := hγX.mdifferentiableAt.self_of_nhds + rw [mfderiv_comp t₀ hX this, ← foo] + rfl + +lemma IsMIntegralCurveAt.eventually_acceleration {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) + (hγX : IsMIntegralCurveAt γ X t₀) : + ∀ᶠ t in 𝓝 t₀, velocity I.tangent (velocity I γ) t = mfderiv% (T% X) (γ t) (X (γ t)) := by + filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t hXt hγXt + exact acceleration hXt hγXt + end integralCurve section geodesics @@ -169,39 +283,87 @@ variable [IsManifold I ∞ M] (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) +-- FIXME: bug in `mfderiv%`? +-- FIXME: missing elaborator support to find I.tangent +omit [FiniteDimensional ℝ E] [T2Space M] in +variable (I) in +@[simp] +lemma proj_acceleration {γ : ℝ → M} {t : ℝ} (h : MDiffAt (velocity I γ) t) : + mfderiv I.tangent I (TotalSpace.proj : TangentBundle I M → M) + (velocity I γ t) (velocity I.tangent (velocity I γ) t).2 = (velocity +I γ t).2 := by + have comp_eq: (TotalSpace.proj : TangentBundle I M → M) ∘ (velocity I γ) = γ := by + ext t + simp + have diff : MDifferentiableAt I.tangent I (TotalSpace.proj : TangentBundle I M → M) + (velocity I γ t) := by + exact mdifferentiableAt_proj (TangentSpace I) + have := mfderiv_comp t diff h + rw [comp_eq] at this + exact congr($this (1 : ℝ)).symm + +lemma IsMIntegralCurveAt.proj_acceleration {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) + (hγX : IsMIntegralCurveAt γ X t₀) : + cov.proj _ (velocity I.tangent (velocity I γ) t₀).2 = cov X X (γ t₀) := by + rw [hγX.acceleration hX, cov.proj_mderiv _ hX hX] noncomputable def CovariantDerivative.geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : TangentSpace (I.prod 𝓘(ℝ, E)) v := cov.lift_vec v v.2 +@[simp] +lemma CovariantDerivative.geodVF_horiz (v : TotalSpace E (TangentSpace I : M → Type _)) : + cov.geodVF v ∈ cov.horiz v := by + simp [CovariantDerivative.geodVF] + +@[simp] +lemma CovariantDerivative.proj_geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : + cov.proj v (cov.geodVF v) = 0 := by + simp [CovariantDerivative.geodVF] + /-- A curve `γ : ℝ → M` is a geodesic for `cov` at `t` if it is an integral curve of the geodesic vector field of `cov` near `t`. Remember: `IsMIntegralCurveAt` is local, not pointwise. -/ def CovariantDerivative.isGeodAt (γ : ℝ → M) (t : ℝ) := IsMIntegralCurveAt (velocity I γ) cov.geodVF t +lemma CovariantDerivative.isGeodAt_iff_horiz {γ : ℝ → M} {t₀ : ℝ} + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : + cov.isGeodAt γ t₀ ↔ + ∀ᶠ (t : ℝ) in 𝓝 t₀, (velocity I.tangent (velocity I γ) t).2 ∈ cov.horiz _ := by + unfold CovariantDerivative.isGeodAt CovariantDerivative.geodVF + rw [IsMIntegralCurveAt_iff_mfderiv _ _ _ hγ] + refine eventually_congr ?_ + filter_upwards [hγ] with t ht + conv_lhs => rw [Eq.comm, cov.lift_vec_eq_iff (velocity I γ t).2] + rw [← cov.mem_horiz_iff_proj, proj_velocity, + show mfderiv% (velocity I γ) t (1 : ℝ) = (velocity I.tangent (velocity I γ) t).2 from + rfl, -- TODO need a simp lemma here? + ] + -- TODO: understand why + -- simp [proj_velocity, proj_acceleration I ht] + -- doesn’t close the goal + simp only [proj_velocity, and_iff_left_iff_imp] + exact fun _ ↦ proj_acceleration I ht + +lemma CovariantDerivative.isGeodAt_iff_proj {γ : ℝ → M} {t₀ : ℝ} + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : + cov.isGeodAt γ t₀ ↔ + ∀ᶠ (t : ℝ) in 𝓝 t₀, cov.proj _ (velocity I.tangent (velocity I γ) t).2 = 0 := + cov.isGeodAt_iff_horiz hγ + def CovariantDerivative.isGeod (γ : ℝ → M) := ∀ t, cov.isGeodAt γ t --- May still need to tweak the assumption (maybe `X` should be smoother for instance). lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} - {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) + {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) (hγX : IsMIntegralCurveAt γ X t₀) : cov.isGeodAt γ t₀ ↔ ∀ᶠ t in 𝓝 t₀, cov X X (γ t) = 0 := by - have := hγX.mdifferentiableAt - unfold CovariantDerivative.isGeodAt - rw [IsMIntegralCurveAt_iff_mfderiv _ _ _ hγ] - constructor - · intro h - filter_upwards [h] with t ht - replace ht : velocity I.tangent (velocity I γ) t = cov.geodVF (velocity I γ t) := by - rw [← ht] - simp [velocity] - have := hγX.acceleration hX hγ - sorry - · intro h - rw [← eventually_eventually_nhds] at h - filter_upwards [h] with t ht - sorry + rw [cov.isGeodAt_iff_proj hγ] + refine eventually_congr ?_ + filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t ht ht' + rw [ht'.proj_acceleration cov ht] end geodesics + diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 12a1155d0c9756..c892eb43f4cd48 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -401,7 +401,30 @@ end any_proj section fiber_bundle variable {E : B → Type*} [TopologicalSpace (TotalSpace F E)] (e : Trivialization F (π F E)) - [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] + +lemma Trivialization.proj_invFun_eventuallyEq + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ + exact symm_coe_proj e hx + +lemma Trivialization.injective_symm [(x : B) → Zero (E x)] + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Function.Injective (e.symm v.proj) := by + intro f f' hff' + simpa [hv] using congr(e $hff') + +lemma Trivialization.surjective_symm [(x : B) → Zero (E x)] + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Function.Surjective (e.symm v.proj) := + fun u ↦ ⟨(e u).2, symm_apply_apply_mk e hv u⟩ + +lemma Trivialization.bijective_symm [(x : B) → Zero (E x)] + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Function.Bijective (e.symm v.proj) := + ⟨e.injective_symm hv, e.surjective_symm hv⟩ + +variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] lemma Trivialization.preimage_baseSet_mem_nhds {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : @@ -502,6 +525,11 @@ lemma Trivialization.symm_map_add [Trivialization.IsLinear R e] {x : B} e.symm x (f + f') = e.symm x f + e.symm x f' := (symmL R e x).map_add f f' +@[simp] +lemma Trivialization.symm_map_zero [Trivialization.IsLinear R e] {x : B} : + e.symm x 0 = 0 := + (symmL R e x).map_zero + variable {R} lemma Trivialization.symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : @@ -582,6 +610,44 @@ lemma Trivialization.derivInv_deriv_apply (e.derivInv I v (e.deriv I v u)) = u := show ((e.derivInv I v) ∘L (e.deriv I v)) u = u by simp [hv] +@[simp] +lemma Trivialization.mfderiv_proj_fst_deriv + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v u = (e.deriv I v u).1 := by + have := e.fst_comp_eventuallyEq hv + rw [← this.mfderiv_eq, mfderiv_comp v mdifferentiableAt_fst (e.mdifferentiableAt (I := I) hv v.2)] + simp + rfl -- TODO: understand why `simp` does not handle `ContinuousLinearMap.fst` + +@[simp] +lemma Trivialization.mfderiv_proj_derivInv_apply + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v (e.derivInv I v u) = u.1 := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [mk_proj_snd' e hv] at D₁ + have diff : MDifferentiableAt (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v := + mdifferentiableAt_proj _ + have eq : e.invFun (e v) = v := by + simp [symm_apply_apply e ((mem_source e).mpr hv)] + rw [← eq] at diff + have := mfderiv_comp (e v) diff D₁ + have C : (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ + exact symm_coe_proj e hx + rw [C.mfderiv_eq, eq] at this + have := congr($this u).symm + change mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v _ = _ at this + -- Why all this pain?? + convert this + ext x + simp + rfl + + @[simp] lemma Trivialization.deriv_derivInv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] From 765253621dea6ee5dc1a43da22c0ee45ffbc51d7 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Feb 2026 18:57:35 +0100 Subject: [PATCH 423/601] Start change of trivialization lemmas --- .../CovariantDerivative/Basic.lean | 181 +++++++++++++++--- .../CovariantDerivative/Lift.lean | 35 ++-- 2 files changed, 179 insertions(+), 37 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 0edd5bc470af1a..50793210d131b6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -922,39 +922,40 @@ variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, lemma Trivialization.pushCovDer_isCovariantDerivativeOn [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov e.baseSet) : - IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet where + {u : Set M} (hu : u ⊆ e.baseSet) + (hcov : IsCovariantDerivativeOn F cov u) : + IsCovariantDerivativeOn F (e.pushCovDer cov) u where addX {X X' σ x} hX hX' hσ hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer - rw [hcov.addX hX hX' hs, e.map_add ℝ hx] + rw [hcov.addX hX hX' hs, e.map_add ℝ (hu hx)] smulX {X σ g x} hX hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer - rw [hcov.smulX hX hs hg, e.map_smul hx] + rw [hcov.smulX hX hs hg, e.map_smul (hu hx)] smul_const_σ {X σ x} a hX hσ hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer - rw [← e.map_smul hx, ← hcov.smul_const_σ a hX hs hx] + rw [← e.map_smul (hu hx), ← hcov.smul_const_σ a hX hs hx] congr ext y simp [e.symm_map_smul, s] addσ {X σ σ' x} hX hσ hσ' hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ set s' := (fun x' ↦ e.symm x' (σ' x')) have hs' : MDiffAt (T% s') x := - e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' unfold Trivialization.pushCovDer - rw [← e.map_add ℝ hx] + rw [← e.map_add ℝ (hu hx)] congr rw [← hcov.addσ hX hs hs' hx] congr @@ -963,7 +964,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn leibniz {X σ g x} hX hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function hx <| mdifferentiableAt_section_trivial_iff.1 hσ + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by ext y @@ -971,9 +972,135 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn rw [this, hcov.leibniz hX hs hg hx] suffices g x • (e ⟨x, cov X s x⟩).2 + (bar (g x)) ((mfderiv% g x) (X x)) • (e ⟨x, s x⟩).2 = g x • (e ⟨x, cov X (fun x' ↦ e.symm x' (σ x')) x⟩).2 + - (bar (g x)) ((mfderiv% g x) (X x)) • σ x by simpa [e.map_add ℝ hx, e.map_smul hx] + (bar (g x)) ((mfderiv% g x) (X x)) • σ x by simpa [e.map_add ℝ (hu hx), e.map_smul (hu hx)] congr - rw [e.apply_mk_symm hx] + rw [e.apply_mk_symm (hu hx)] + +variable {e} in +lemma Trivialization.coordChangeL_pushCovDer + [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) + {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {s : M → F} (hs : MDiffAt s x) : + e.coordChangeL ℝ e' x (e.pushCovDer cov X s x) = + e'.pushCovDer cov X (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by + unfold Trivialization.pushCovDer + let σ := (fun x' ↦ e.symm x' (s x')) + rw [coordChangeL_apply e e' hx] + refold_let σ + have : e.symm x (e ⟨x, cov X σ x⟩).2 = cov X σ x := by + -- TODO fix `simp [hx.1]` not working + exact symm_apply_apply_mk e hx.1 (cov X σ x) + rw [this] + -- TODO: extract lemma? + have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = + e'.symm x' ((fun x ↦ (coordChangeL ℝ e e' x) (s x)) x') := by + rintro x' ⟨hx'e, hx'e'⟩ + simp only + rw [coordChangeL_apply e e' ⟨hx'e, hx'e'⟩] + -- simp [hx'e'] -- TODO doesn’t work + rw [symm_apply_apply_mk e' hx'e'] + have mem : e.baseSet ∩ e'.baseSet ∈ 𝓝 x := by + -- FIXME: make sure grind can do this proof + exact inter_mem (baseSet_mem_nhds e (mem_of_mem_inter_left hx)) + (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) + have hσ : MDiffAt (T% σ) x := + mdifferentiableAt_section_of_function e hx.1 hs + rw [hcov.congr_σ_of_eqOn hX hσ ?_ mem this] + -- TODO have automatation doing the next three lines… + apply mdifferentiableAt_section_of_function e' hx.2 + have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 + exact this.mdifferentiableAt (zero_ne_one.symm) |>.clm_apply hs + + +variable {e} in +lemma Trivialization.coordChangeL_mem_horiz + [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : + haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + (u, w) ∈ hcove.horiz x v → + (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by + have hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + have hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] + rintro ⟨s, sdiff, sxv, sxuw, covs⟩ + use fun x ↦ e.coordChangeL ℝ e' x (s x), ?_, ?_, ?_ + · let X := extend I E u + have hX : MDiffAt (T% X) x := by + -- TODO: extract as lemma? + exact (mdifferentiable_extend I E u).mdifferentiableAt + -- TODO: investigate whether the following line comes from inconsistent ways to + -- state assumptions + rw [mdifferentiableAt_section_trivial_iff] at sdiff + rw [← e.coordChangeL_pushCovDer hcov hx hX sdiff, covs] + simp + · sorry + · congr + · rw [← sxuw] + sorry + +-- This is PAIIIIINNNN +variable {e} in +lemma Trivialization.coordChangeL_coordChangeL + [VectorBundle ℝ F V] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : + e'.coordChangeL ℝ e x (e.coordChangeL ℝ e' x v) = v := by + have hx' := inter_comm _ _ ▸ hx + change ((coordChangeL ℝ e' e x) ∘ (coordChangeL ℝ e e' x)) v = v + rw [coe_coordChangeL _ _ hx] + rw [coe_coordChangeL _ _ hx'] + change + ((linearEquivAt ℝ e x hx'.2 ∘ (linearEquivAt ℝ e' x hx'.1).symm) ∘ + (linearEquivAt ℝ e' x hx'.1 ∘ (linearEquivAt ℝ e x hx'.2).symm)) + v = v + rw [Function.comp_assoc] + conv => + congr + congr + rfl + rw [← Function.comp_assoc] + change + ((linearEquivAt ℝ e x _) ∘ + (↑(linearEquivAt ℝ e' x hx'.1).symm ∘ₗ (linearEquivAt ℝ e' x hx'.1).toLinearMap) ∘ _) + v = v + rw [(linearEquivAt ℝ e' x hx'.1).symm_comp] + simp only [LinearMap.id_coe, CompTriple.comp_eq] + change (↑(linearEquivAt ℝ e x hx'.2) ∘ₗ (linearEquivAt ℝ e x _).symm.toLinearMap) v = v + rw [(linearEquivAt ℝ e x hx'.2).comp_symm] + simp + +variable {e} in +lemma Trivialization.coordChangeL_mem_horiz_iff + [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : + haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + (u, w) ∈ hcove.horiz x v ↔ + (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by + refine ⟨e.coordChangeL_mem_horiz hcov hx, fun hu ↦ ?_⟩ + let v' := e.coordChangeL ℝ e' x v + let w' := e.coordChangeL ℝ e' x w + rw [inter_comm] at hx hcov + have hx' := inter_comm _ _ ▸ hx + have hvv' : v = e'.coordChangeL ℝ e x v' := (coordChangeL_coordChangeL hx' v).symm + have hww' : w = e'.coordChangeL ℝ e x w' := (coordChangeL_coordChangeL hx' w).symm + have key := e'.coordChangeL_mem_horiz hcov hx (w := w') (u := u) (v := v') ?_ + · rw [← hvv', ← hww'] at key + convert key using 2 + apply inter_comm + · convert hu using 2 + apply inter_comm end to_trivialization @@ -992,17 +1119,25 @@ noncomputable def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := letI t := trivializationAt F V v.proj - haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (u := t.baseSet) subset_rfl (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) letI tproj := d_covDerOn.projection v.proj (t v).2 letI Tvt := t.deriv I v t.symmL ℝ v.proj ∘L tproj ∘L Tvt +omit [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] in +lemma isCovariantDerivativeOn_pushCovDer + (cov : CovariantDerivative I F V) (e : Trivialization F (π F V)) [MemTrivializationAtlas e] : + IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := + e.pushCovDer_isCovariantDerivativeOn subset_rfl + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + + + lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : letI t := trivializationAt F V v.proj - haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t letI tproj := d_covDerOn.projection v.proj (t v).2 letI Tvt := t.deriv I v (t <| cov.proj v u).2 = tproj (Tvt u) := by @@ -1019,15 +1154,13 @@ lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : letI t := trivializationAt F V v.proj - haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t horiz cov v = Submodule.comap (t.deriv I v).toLinearMap (d_covDerOn.horiz v.proj (t v).2) := by -- FIXME: needing all those lets and the change is awful let t := trivializationAt F V v.proj let Tvt := t.deriv I v - have hcov := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t let tproj := hcov.projection v.proj (t v).2 let t' := t.continuousLinearEquivAt ℝ v.proj (mem_baseSet_trivializationAt F V v.proj) ext u @@ -1041,8 +1174,7 @@ lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] IsCompl (cov.horiz v) (vert v) := by let t := trivializationAt F V v.proj let Tvt := t.deriv I v - have hcov := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + have hcov := cov.isCovariantDerivativeOn_pushCovDer t rw [t.comap_vert (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] apply LinearMap.comap_isCompl · apply t.bijective_deriv @@ -1065,8 +1197,7 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] -- FIXME `mfderiv%` fails in next line (fixed on master?) let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) change cov X σ x = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) (X x)) - have hcov := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + have hcov := cov.isCovariantDerivativeOn_pushCovDer t have hx := mem_baseSet_trivializationAt F V x have hs : MDiffAt (T% s) x := by rw [t.mdifferentiableAt_section_iff I σ hx] at hσ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index fccea63bd54f76..225d1df7e40e6c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -99,7 +99,7 @@ lemma IsCovariantDerivativeOn.projection_lift_vec (x : M) (f : F) : lemma IsCovariantDerivativeOn.lift_vec_eq_iff {x : M} {f : F} {u : TangentSpace I x} {w : TangentSpace I x × F} : - hcov.lift_vec x f u = w ↔ hcov.projection x f w = 0 ∧ w.1 = u := by + hcov.lift_vec x f u = w ↔ hcov.projection x f w = 0 ∧ w.1 = u := by constructor · intro rfl simp @@ -126,25 +126,37 @@ noncomputable def CovariantDerivative.lift_vec (v : TotalSpace F V) : TangentSpace I v.proj →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, F)) v := letI t := trivializationAt F V v.proj - haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - letI tlift := d_covDerOn.lift_vec v.proj (t v).2 + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + letI tlift := hcov.lift_vec v.proj (t v).2 t.derivInv I v ∘L tlift lemma CovariantDerivative.lift_vec_apply {v : TotalSpace F V} (u : TangentSpace I v.proj) : letI t := trivializationAt F V v.proj - haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - letI tlift := d_covDerOn.lift_vec v.proj (t v).2 + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t + letI tlift := hcov.lift_vec v.proj (t v).2 cov.lift_vec v u = t.derivInv I v (tlift u) := rfl +/-- We can compute `lift_vec v` using any trivialization whose +base set contains `v.proj`. This is crucial to prove smoothness +of `lift_vec`. -/ +lemma CovariantDerivative.lift_vec_eq {v : TotalSpace F V} + {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] + (hv : v.proj ∈ e.baseSet) + (u : TangentSpace I v.proj) : + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer e + cov.lift_vec v u = e.derivInv I v (hcov.lift_vec v.proj (e v).2 u) := by + rw [cov.lift_vec_apply] + set t := trivializationAt F V v.proj + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + refold_let t + sorry + @[simp] lemma CovariantDerivative.lift_vec_horiz {v : TotalSpace F V} (u : TangentSpace I v.proj) : cov.lift_vec v u ∈ cov.horiz v := by let t := trivializationAt F V v.proj - have d_covDerOn := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - let tlift := d_covDerOn.lift_vec v.proj (t v).2 + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + let tlift := hcov.lift_vec v.proj (t v).2 rw [lift_vec_apply, CovariantDerivative.mem_horiz_iff_proj] -- TODO: cleanup simp only [proj, IsCovariantDerivativeOn.lift_vec_apply, ContinuousLinearMap.coe_comp', @@ -176,8 +188,7 @@ lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace simp · rintro ⟨h, h'⟩ let t := trivializationAt F V v.proj - have hcov := t.pushCovDer_isCovariantDerivativeOn - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + have hcov := cov.isCovariantDerivativeOn_pushCovDer t have mem := FiberBundle.mem_baseSet_trivializationAt F V v.proj apply (t.bijective_deriv mem).1 unfold CovariantDerivative.lift_vec From 9508df80bddc43457ece68c74e1559fba27c418c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 11:52:58 +0100 Subject: [PATCH 424/601] chore: speak about affine combinations, as that is the correct terminology --- .../CovariantDerivative/Basic.lean | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 50793210d131b6..40ea18ae43651c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -80,7 +80,7 @@ This is a class so typeclass inference can deduce this automatically. -/ class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) - (u : Set M) where + (u : Set M) where contMDiff : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, CMDiff[u] (k + 1) (T% σ) → CMDiff[u] k (T% X) → CMDiff[u] k (T% (cov X σ)) @@ -212,9 +212,9 @@ section operations variable {s : Set M} {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} -/-- A convex combination of covariant derivatives is a covariant derivative. -/ +/-- An affine combination of covariant derivatives is a covariant derivative. -/ @[simps] -def convexCombination +def affineCombination {f' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : IsCovariantDerivativeOn F (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where @@ -230,8 +230,8 @@ def convexCombination simp [hf.leibniz hX hσ hφ, hf'.leibniz hX hσ hφ] module -/-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination +/-- An affine combination of two `C^k` connections is a `C^k` connection. -/ +lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination [VectorBundle 𝕜 F V] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) @@ -243,8 +243,8 @@ lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination · exact hf.smul_section <| Hcov.contMDiff hX hσ · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hσ -/-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +/-- A finite affine combination of covariant derivatives is a covariant derivative. -/ +def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where @@ -293,8 +293,8 @@ def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] rw [this, one_smul] simp -/-- A convex combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.convexCombination' {n : ℕ∞} +/-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ +lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : ℕ∞} [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) @@ -436,40 +436,40 @@ end computational_properties section operations -/-- A convex combination of covariant derivatives is a covariant derivative. -/ +/-- An affine combination of covariant derivatives is a covariant derivative. -/ @[simps] -def convexCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : +def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : CovariantDerivative I F V where toFun := fun X σ ↦ (g • (cov X σ)) + (1 - g) • (cov' X σ) isCovariantDerivativeOn := - cov.isCovariantDerivativeOn.convexCombination cov'.isCovariantDerivativeOn _ + cov.isCovariantDerivativeOn.affineCombination cov'.isCovariantDerivativeOn _ -/-- A finite convex combination of covariant derivatives is a covariant derivative. -/ -def convexCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +/-- A finite affine combination of covariant derivatives is a covariant derivative. -/ +def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where toFun X t x := ∑ i ∈ s, (f i x) • (cov i) X t x - isCovariantDerivativeOn := IsCovariantDerivativeOn.convexCombination' + isCovariantDerivativeOn := IsCovariantDerivativeOn.affineCombination' (fun i ↦ (cov i).isCovariantDerivativeOn) hf -/-- A convex combination of two `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.convexCombination [VectorBundle 𝕜 F V] +/-- An affine combination of two `C^k` connections is a `C^k` connection. -/ +lemma ContMDiffCovariantDerivative.affineCombination [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : - ContMDiffCovariantDerivative (convexCombination cov cov' f) n where + ContMDiffCovariantDerivative (affineCombination cov cov' f) n where contMDiff := - ContMDiffCovariantDerivativeOn.convexCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff + ContMDiffCovariantDerivativeOn.affineCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff -/-- A convex combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.convexCombination' [VectorBundle 𝕜 F V] +/-- An affine combination of finitely many `C^k` connections is a `C^k` connection. -/ +lemma ContMDiffCovariantDerivative.affineCombination' [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : - ContMDiffCovariantDerivative (convexCombination' cov hf) n where + ContMDiffCovariantDerivative (affineCombination' cov hf) n where contMDiff := - ContMDiffCovariantDerivativeOn.convexCombination' + ContMDiffCovariantDerivativeOn.affineCombination' (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) -- Future: prove a version with a locally finite sum, and deduce that C^k connections always From b0965362951b067fe9f6123b4b4f41a01210c8d5 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:49:13 +0000 Subject: [PATCH 425/601] bundle linearity in TM --- .../CovariantDerivative/Basic.lean | 681 ++++++++---------- 1 file changed, 297 insertions(+), 384 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 40ea18ae43651c..aaad9941c8695c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -47,31 +47,25 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] - -- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [FiberBundle F V] --[VectorBundle 𝕜 F V] -- `V` vector bundle structure IsCovariantDerivativeOn [IsManifold I 1 M] - (f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) + (f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (s : Set M := Set.univ) : Prop where -- All the same axioms as CovariantDerivative, but restricted to the set s. - addX (f) {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hσ : MDiffAt (T% σ) x) + addσ {σ σ' : Π x : M, V x} {x} + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : - f (X + X') σ x = f X σ x + f X' σ x - smulX {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {g : M → 𝕜} {x : M} - (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial) : - f (g • X) σ x = g x • f X σ x - addσ {X : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x} - (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) - (hx : x ∈ s := by trivial) : - f X (σ + σ') x = f X σ x + f X σ' x + f (σ + σ') x = f σ x + f σ' x leibniz {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {g : M → 𝕜} {x} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): - f X (g • σ) x = (g • f X σ) x + ((bar _).toFun (mfderiv I 𝓘(𝕜) g x (X x))) • σ x - smul_const_σ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x} (a : 𝕜) - (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - f X (a • σ) x = a • f X σ x + -- TODO phrase without `X` as an equality in `TangentSpace I x →L[𝕜] V x` + f (g • σ) x (X x) = g x • f σ x (X x) + ((bar _).toFun (mfderiv I 𝓘(𝕜) g x (X x))) • σ x + smul_const_σ {σ : Π x : M, V x} {x} (a : 𝕜) + (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + f (a • σ) x = a • f σ x /-- A covariant derivative ∇ is called of class `C^k` iff, @@ -79,11 +73,12 @@ whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X This is a class so typeclass inference can deduce this automatically. -/ class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) - (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) + (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (u : Set M) where contMDiff : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - CMDiff[u] (k + 1) (T% σ) → CMDiff[u] k (T% X) → - CMDiff[u] k (T% (cov X σ)) + CMDiff[u] (k + 1) (T% σ) → + -- TODO phrase this in terms of the smoothness of a section of the bundle Hom(TM, V) + CMDiff[u] k (T% X) → CMDiff[u] k (T% (fun x ↦ cov σ x (X x))) variable {F} @@ -92,24 +87,22 @@ namespace IsCovariantDerivativeOn variable [IsManifold I 1 M] variable (E) in -/-- If `E` is the trivial vector space, the axioms of a covariant derivative are vacuous. -/ -lemma of_subsingleton [hE : Subsingleton E] - (f : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → - ((x : M) → TangentSpace I x)) : +/-- If `E` is the trivial vector space, [HM: i.e. the manifold is zero-dimensional??] +the axioms of a covariant derivative are vacuous. -/ +lemma of_subsingleton [hE : Subsingleton E] [TopologicalSpace (TotalSpace E V)] [FiberBundle E V] + (f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : IsCovariantDerivativeOn E f Set.univ := by - have (X) (Y) (x) : f X Y x = 0 := by + have (Y) (x) : f Y x = 0 := by have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero _ exact { - addX {_X _X' _σ x} hX hX' hσ hx := by simp [this] - smulX {_X _σ _g _x} hX hσ hg hx := by simp [this] - smul_const_σ {X _σ x} a hX hσ hx := by simp [this] - addσ {X σ σ' x} hX hσ hσ' hx := by simp [this] + smul_const_σ {_σ x} a hσ hx := by simp [this] + addσ {σ σ' x} hσ hσ' hx := by simp [this] leibniz {X σ g x} hX hσ hg hx := by - have hσ : σ x = 0 := by + have H : (mfderiv I 𝓘(𝕜, 𝕜) g x) = 0 := have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - exact Subsingleton.eq_zero _ - simp [this, hσ] } + Subsingleton.eq_zero _ + simp [this, H] } section changing_set /-! Changing set @@ -118,113 +111,70 @@ In this changing we change `s` in `IsCovariantDerivativeOn F f s`. -/ lemma mono - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s t : Set M} + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s t : Set M} (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where - addX {_X _X' _σ} _x hX hX' hσ hx := hf.addX hX hX' hσ (hst hx) - smulX {_X _σ _g} _x hX hσ hg hx := hf.smulX hX hσ hg (hst hx) - addσ {_X _σ _σ' _x} hX hσ hσ' hx := hf.addσ hX hσ hσ' (hst hx) + addσ {_σ _σ' _x} hσ hσ' hx := hf.addσ hσ hσ' (hst hx) leibniz {_X _σ _f _x} hX hσ hf' hx := hf.leibniz hX hσ hf' (hst hx) - smul_const_σ {_X _σ _x} a hX hσ hx := hf.smul_const_σ a hX hσ (hst hx) + smul_const_σ {_σ _x} a hσ hx := hf.smul_const_σ a hσ (hst hx) lemma iUnion {ι : Type*} - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : ι → Set M} + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : ι → Set M} (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) : IsCovariantDerivativeOn F f (⋃ i, s i) where - addX {_X _X' _σ _x} hX hX' hσ hx := by - obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addX hX hX' hσ hxsi - smulX {_X _σ _g _x} hX hσ hg hx := by + addσ {_σ _σ' _x} hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smulX hX hσ hg hxsi - addσ {_X _σ _σ' _x} hX hσ hσ' hx := by - obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addσ hX hσ hσ' + exact (hf i).addσ hσ hσ' leibniz {X σ f x} hX hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).leibniz hX hσ hf' - smul_const_σ {_X _σ _x} a hX hσ hx := by + smul_const_σ {_σ _x} a hσ hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smul_const_σ _ hX hσ + exact (hf i).smul_const_σ _ hσ end changing_set /- Congruence properties -/ section -lemma congr {f g : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} +lemma congr {f g : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hf : IsCovariantDerivativeOn F f s) -- Is this too strong? Will see! - (hfg : ∀ {X : Π x : M, TangentSpace I x}, - ∀ {σ : Π x : M, V x}, ∀ {x}, x ∈ s → f X σ x = g X σ x) : + (hfg : ∀ {σ : Π x : M, V x}, ∀ {x}, x ∈ s → f σ x = g σ x) : IsCovariantDerivativeOn F g s where - addX hX hX' hσ hx := by simp [← hfg hx, hf.addX hX hX' hσ] - smulX hX hσ hg hx := by simp [← hfg hx, hf.smulX hX hσ hg] - addσ hX hσ hσ' hx := by simp [← hfg hx, hf.addσ hX hσ hσ'] + addσ hσ hσ' hx := by simp [← hfg hx, hf.addσ hσ hσ'] leibniz hX hσ hf' hx := by simp [← hfg hx, hf.leibniz hX hσ hf'] - smul_const_σ a hX hσ hx := by simp [← hfg hx, hf.smul_const_σ a hX hσ] + smul_const_σ a hσ hx := by simp [← hfg hx, hf.smul_const_σ a hσ] end section computational_properties -lemma smul_const_X - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {s : Set M} (h : IsCovariantDerivativeOn F f s) {x} (a : 𝕜) - {X : Π x, TangentSpace I x} {σ : Π x, V x} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) - (hx : x ∈ s := by trivial) : - f (a • X) σ x = a • f X σ x := - h.smulX hX hσ mdifferentiableAt_const - -variable {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} {s : Set M} - -@[simp] -lemma zeroX (hf : IsCovariantDerivativeOn F f s) - {x : M} (hx : x ∈ s := by trivial) - {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : f 0 σ x = 0 := by - -- TODO: writing MDiffAt here yields an error! - have : MDifferentiableAt I (I.prod 𝓘(𝕜, E)) (T% (fun x ↦ (0 : TangentSpace I x))) x := - -- TODO: add mdifferentiable{,At}_zeroSection - (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero - simpa using IsCovariantDerivativeOn.addX f hf (X := 0) this this hσ +variable {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} @[simp] lemma zeroσ [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) - {X : Π x : M, TangentSpace I x} {x} (hX : MDiffAt (T% X) x) (hx : x ∈ s := by trivial) : - f X 0 x = 0 := by - simpa using (hf.addσ hX (mdifferentiableAt_zeroSection ..) - (mdifferentiableAt_zeroSection ..) : f X (0 + 0) x = _) - -lemma sum_X (hf : IsCovariantDerivativeOn F f s) - {ι : Type*} {u : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} - {x} (hx : x ∈ s) (hX : ∀ i, MDiffAt (T% (X i)) x) (hσ : MDiffAt (T% σ) x) : - f (∑ i ∈ u, X i) σ x = ∑ i ∈ u, f (X i) σ x := by - classical - have := hf.zeroX hx hσ - induction u using Finset.induction_on with - | empty => simp [hf.zeroX hx hσ] - | insert a u ha h => - have : MDiffAt (T% (∑ i ∈ u, X i)) x := by simpa using MDifferentiableAt.sum_section (s := u) hX - simp [Finset.sum_insert ha, ← h, hf.addX (hX a) this hσ hx] + {x} (hx : x ∈ s := by trivial) : + f 0 x = 0 := by + simpa using (hf.addσ (mdifferentiableAt_zeroSection ..) + (mdifferentiableAt_zeroSection ..) : f (0 + 0) x = _) end computational_properties section operations variable {s : Set M} - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} /-- An affine combination of covariant derivatives is a covariant derivative. -/ @[simps] def affineCombination - {f' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {f' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : - IsCovariantDerivativeOn F (fun X σ ↦ (g • (f X σ)) + (1 - g) • (f' X σ)) s where - addX {X X' σ} x hX hX' hσ hx := by simp [hf.addX hX hX' hσ, hf'.addX hX hX' hσ]; module - smulX {_X _σ _φ} x hX hσ hφ hx := by simp [hf.smulX hX hσ hφ, hf'.smulX hX hσ hφ]; module - addσ {_X _σ _σ' x} hX hσ hσ' hx := by - simp [hf.addσ hX hσ hσ', hf'.addσ hX hσ hσ'] + IsCovariantDerivativeOn F (fun σ ↦ (g • (f σ)) + (1 - g) • (f' σ)) s where + addσ {_σ _σ' x} hσ hσ' hx := by + simp [hf.addσ hσ hσ', hf'.addσ hσ hσ'] module - smul_const_σ {_X _σ _x} a hX hσ hx := by - simp [hf.smul_const_σ a hX hσ, hf'.smul_const_σ a hX hσ] + smul_const_σ {_σ _x} a hσ hx := by + simp [hf.smul_const_σ a hσ, hf'.smul_const_σ a hσ] module leibniz {X σ φ x} hX hσ hφ hx := by simp [hf.leibniz hX hσ hφ, hf'.leibniz hX hσ hφ] @@ -233,11 +183,11 @@ def affineCombination /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination [VectorBundle 𝕜 F V] - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : - ContMDiffCovariantDerivativeOn F n (fun X σ ↦ (f • (cov X σ)) + (1 - f) • (cov' X σ)) u where + ContMDiffCovariantDerivativeOn F n (fun σ ↦ (f • (cov σ)) + (1 - f) • (cov' σ)) u where contMDiff hX hσ := by apply ContMDiffOn.add_section · exact hf.smul_section <| Hcov.contMDiff hX hσ @@ -245,34 +195,24 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination /-- A finite affine combination of covariant derivatives is a covariant derivative. -/ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] - {u : Set M} {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {u : Set M} {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : - IsCovariantDerivativeOn F (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where - addX {_X _X' _σ} x hx hX hX' hσ := by + IsCovariantDerivativeOn F (fun σ x ↦ ∑ i ∈ s, (f i x) • (cov i) σ x) u where + addσ {_σ _σ' _x} hσ hσ' hx := by rw [← Finset.sum_add_distrib] congr ext i - simp [(h i).addX hx hX hX' hσ] - smulX {_X _σ _g} x hx hX hσ hg := by + rw [← smul_add, (h i).addσ hσ hσ' hx] + smul_const_σ {_σ _x} a hσ hx := by rw [Finset.smul_sum] congr ext i - simp [(h i).smulX hx hX hσ hg] - module - addσ {_X _σ _σ' _x} hX hσ hσ' hx := by - rw [← Finset.sum_add_distrib] - congr - ext i - rw [← smul_add, (h i).addσ hX hσ hσ' hx] - smul_const_σ {_X _σ _x} a hX hσ hx := by - rw [Finset.smul_sum] - congr - ext i - simp [(h i).smul_const_σ a hX hσ] + simp [(h i).smul_const_σ a hσ] module leibniz {X σ g x} hX hσ hg hx := by - calc ∑ i ∈ s, f i x • (cov i) X (g • σ) x - _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x + calc (∑ i ∈ s, f i x • (cov i) (g • σ) x) (X x) + _ = ∑ i ∈ s, f i x • (cov i) (g • σ) x (X x) := by simp + _ = ∑ i ∈ s, ((g • (f i • (cov i) σ)) x (X x) + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x) := by congr ext i @@ -280,12 +220,15 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] simp_rw [Pi.smul_apply', smul_add] dsimp rw [smul_comm] - _ = ∑ i ∈ s, ((g • (f i • (cov i) X σ)) x) + _ = ∑ i ∈ s, ((g • (f i • (cov i) σ)) x) (X x) + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by rw [Finset.sum_add_distrib] - _ = (g • ∑ i ∈ s, f i • (cov i) X σ) x + (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by + _ = (g • ∑ i ∈ s, f i • (cov i) σ) x (X x) + (bar (g x)) + ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by -- There has to be a shorter proof! - simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, add_right_inj] + simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, + ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.coe_sum', + Finset.sum_apply, add_right_inj] set B := (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x trans (∑ i ∈ s, f i x) • B · rw [Finset.sum_smul] @@ -296,29 +239,26 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] /-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : ℕ∞} [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} - {cov : ι → (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) {f : ι → M → 𝕜} (hf : ∀ i ∈ s, CMDiff[u] n (f i)) : - ContMDiffCovariantDerivativeOn F n (fun X σ x ↦ ∑ i ∈ s, (f i x) • (cov i) X σ x) u where - contMDiff hσ hX := - ContMDiffOn.sum_section (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ hX) + ContMDiffCovariantDerivativeOn F n (fun σ x ↦ ∑ i ∈ s, (f i x) • (cov i) σ x) u where + contMDiff {X} σ hσ hX := by + simpa using ContMDiffOn.sum_section + (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ hX) variable {s : Set M} - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] (hf : IsCovariantDerivativeOn F f s) - (A : Π x : M, TangentSpace I x →L[𝕜] V x →L[𝕜] V x) : - IsCovariantDerivativeOn F (fun X σ x ↦ f X σ x + A x (X x) (σ x)) s where - addX {_X _X' _σ} x hx hX hX' hσ := by - simp [hf.addX hx hX hX' hσ] - abel - smulX {_X _σ _g} x hx hX hσ hg := by - simp [hf.smulX hx hX hσ hg] - addσ {_X _σ _σ' _x} hX hσ hσ' hx := by - simp [hf.addσ hX hσ hσ'] + (A : Π x : M, V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : + IsCovariantDerivativeOn F (fun σ x ↦ f σ x + A x (σ x)) s where + addσ {_σ _σ' _x} hσ hσ' hx := by + simp [hf.addσ hσ hσ'] abel - smul_const_σ {_X _σ _x} a hX hσ hx := by simp [hf.smul_const_σ a hX hσ] + smul_const_σ {_σ _x} a hσ hx := by simp [hf.smul_const_σ a hσ] leibniz {X σ g x} hX hσ hg hx := by simp [hf.leibniz hX hσ hg] module @@ -331,26 +271,23 @@ variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : IsCovariantDerivativeOn F (V := Trivial M F) - (fun X s x ↦ mfderiv I 𝓘(𝕜, F) s x (X x)) univ where - addX {_X _X' _σ} x _ hX hX' hσ := by simp - smulX {_X _σ} c' x _ := by simp - addσ {_X σ σ' x} hX hσ hσ' hx := by + (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where + addσ {σ σ' x} hσ hσ' hx := by rw [mdifferentiableAt_section] at hσ hσ' -- TODO: specialize mdifferentiableAt_section to trivial bundles? change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] - rfl - smul_const_σ {_X _σ _x} a hX hσ hx := by rw [mfderiv_const_smul] + smul_const_σ {_σ _x} a hσ hx := by ext X; rw [mfderiv_const_smul]; rfl leibniz {X σ f x} hX hσ hf hx := by rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) -lemma of_endomorphism (A : (x : M) → TangentSpace I x →L[𝕜] F →L[𝕜] F) : +lemma of_endomorphism (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F) : IsCovariantDerivativeOn F - (fun (X : Π x : M, TangentSpace I x) (s : M → F) x ↦ - letI d : F := mfderiv I 𝓘(𝕜, F) s x (X x) - d + A x (X x) (s x)) univ := + (fun (s : M → F) x ↦ + letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) s x + d + A x (s x)) univ := trivial I M F |>.add_one_form A end trivial_bundle @@ -362,7 +299,7 @@ end IsCovariantDerivativeOn variable (I F V) in @[ext] structure CovariantDerivative [IsManifold I 1 M] where - toFun : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) + toFun : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) isCovariantDerivativeOn : IsCovariantDerivativeOn F toFun Set.univ namespace CovariantDerivative @@ -373,7 +310,7 @@ variable [IsManifold I 1 M] /-- Coercion of a `CovariantDerivative` to function -/ instance : CoeFun (CovariantDerivative I F V) - fun _ ↦ (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := + fun _ ↦ (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := ⟨fun e ↦ e.toFun⟩ instance (cov : CovariantDerivative I F V) {s : Set M} : @@ -383,14 +320,14 @@ instance (cov : CovariantDerivative I F V) {s : Set M} : /-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant derivative on each set in an open cover, it is a covariant derivative. -/ def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) (hs : ⋃ i, s i = Set.univ) : CovariantDerivative I F V := ⟨f, hs ▸ IsCovariantDerivativeOn.iUnion hf⟩ @[simp] lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set M} - {f : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) (hs : ⋃ i, s i = Set.univ) : of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl @@ -414,23 +351,9 @@ lemma contMDiffCovariantDerivativeOn_univ_iff {cov : CovariantDerivative I F V} section computational_properties @[simp] -lemma zeroX (cov : CovariantDerivative I F V) {σ : Π x : M, V x} (hσ : MDiff (T% σ)) : - cov 0 σ = 0 := by - ext x - exact cov.isCovariantDerivativeOn.zeroX (by trivial) (hσ x) - -@[simp] -lemma zeroσ [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) - {X : Π x : M, TangentSpace I x} (hX : MDiff (T% X)) : cov X 0 = 0 := by - ext x - exact cov.isCovariantDerivativeOn.zeroσ (hX x) - -lemma sum_X (cov : CovariantDerivative I F V) - {ι : Type*} {s : Finset ι} {X : ι → Π x : M, TangentSpace I x} {σ : Π x : M, V x} - (hX : ∀ i, MDiff (T% (X i))) (hσ : MDiff (T% σ)): - cov (∑ i ∈ s, X i) σ = ∑ i ∈ s, cov (X i) σ := by - ext x - simpa using cov.isCovariantDerivativeOn.sum_X trivial (fun i ↦ hX i x) (hσ x) +lemma zeroσ [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 := by + ext1 x + simp [cov.isCovariantDerivativeOn.zeroσ] end computational_properties @@ -440,7 +363,7 @@ section operations @[simps] def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : CovariantDerivative I F V where - toFun := fun X σ ↦ (g • (cov X σ)) + (1 - g) • (cov' X σ) + toFun := fun σ ↦ (g • (cov σ)) + (1 - g) • (cov' σ) isCovariantDerivativeOn := cov.isCovariantDerivativeOn.affineCombination cov'.isCovariantDerivativeOn _ @@ -448,7 +371,7 @@ def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where - toFun X t x := ∑ i ∈ s, (f i x) • (cov i) X t x + toFun t x := ∑ i ∈ s, (f i x) • (cov i) t x isCovariantDerivativeOn := IsCovariantDerivativeOn.affineCombination' (fun i ↦ (cov i).isCovariantDerivativeOn) hf @@ -482,18 +405,15 @@ section trivial_bundle variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where - toFun X s x := mfderiv I 𝓘(𝕜, F) s x (X x) + toFun s x := mfderiv I 𝓘(𝕜, F) s x isCovariantDerivativeOn := -- TODO use previous work - { addX {_X _X' _σ} x _ hX hX' hσ := by simp - smulX {_X _σ} c' x _ := by simp - addσ {_X σ σ' x} hX hσ hσ' hx := by + { addσ {σ σ' x} hσ hσ' hx := by rw [mdifferentiableAt_section] at hσ hσ' -- TODO: specialize mdifferentiableAt_section to trivial bundles? change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] - rfl - smul_const_σ {_X _σ _x} a hX hσ hx := by rw [mfderiv_const_smul] + smul_const_σ {_σ _x} a hσ hx := by ext; rw [mfderiv_const_smul]; rfl leibniz {X σ f x} hX hσ hf hx := by rw [mdifferentiableAt_section] at hσ exact mfderiv_smul hσ hf (X x) } @@ -531,9 +451,9 @@ lemma trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial -- or perhaps a contMDiffOn version of this lemma? sorry -/ -noncomputable def of_endomorphism (A : E → E →L[𝕜] E' →L[𝕜] E') : +noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where - toFun X σ := fun x ↦ fderiv 𝕜 σ x (X x) + A x (X x) (σ x) + toFun σ := fun x ↦ fderiv 𝕜 σ x + A x (σ x) isCovariantDerivativeOn := by convert IsCovariantDerivativeOn.of_endomorphism (I := 𝓘(𝕜, E)) A ext f x v @@ -558,39 +478,44 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] namespace IsCovariantDerivativeOn +-- TODO can probably work for `IsManifold I 1 M`, +-- by weakening the conditions for the `extend` construction +theorem ext [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] + {P P' : (Π x : M, TangentSpace I x →L[ℝ] V x)} {x} + (H : ∀ {X : Π x : M, TangentSpace I x}, MDiffAt (T% X) x → P x (X x) = P' x (X x)) : + P x = P' x := by + ext X₀ + rw [← extend_apply_self (I := I) (F := E) X₀] + exact H (mdifferentiable_extend ..) + /-- `cov X σ x` only depends on `X` via `X x` -/ -lemma congr_X_at [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] - {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) +lemma congr_X_at + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {X X' : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) - (hσ : MDiffAt (T% σ) x) - (hx : x ∈ u) (hXX' : X x = X' x) : - cov X σ x = cov X' σ x := by - refine tensoriality_criterion I E (TangentSpace I) (φ := fun X ↦ cov X σ) F V hX hX' hXX' ?_ ?_ - · intro f X hf hX - exact hcov.smulX hX hσ hf hx - · intro X X' hX hX' - exact hcov.addX hX hX' hσ hx + (hXX' : X x = X' x) : + cov σ x (X x) = cov σ x (X' x) := by + rw [hXX'] lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] - {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) - (X : Π x : M, TangentSpace I x) {σ : Π x : M, V x} - (hX : MDiffAt (T% X) x) + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (f : SmoothBumpFunction I x) (hx : x ∈ u) : - cov X ((f : M → ℝ) • σ) x = cov X σ x := by + cov ((f : M → ℝ) • σ) x = cov σ x := by + apply IsCovariantDerivativeOn.ext + intro X hX have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) have := hcov.leibniz hX hσ hf hx rw [hcov.leibniz hX hσ _ hx] swap; · apply f.contMDiff.mdifferentiable (by norm_num) calc _ - _ = cov X σ x + 0 := ?_ - _ = cov X σ x := by rw [add_zero] + _ = cov σ x (X x) + 0 := ?_ + _ = cov σ x (X x) := by rw [add_zero] suffices mfderiv% (1 : M → ℝ) x (X x) = 0 ∨ σ x = 0 by simpa [f.eq_one, f.eventuallyEq_one.mfderiv_eq] rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] @@ -598,15 +523,15 @@ lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] rfl lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] - {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) - {X : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} - (hX : MDiffAt (T% X) x) + {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hxs : s ∈ 𝓝 x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : - cov X σ x = cov X σ' x := by + cov σ x = cov σ' x := by -- Choose a smooth bump function ψ with support around `x` contained in `s` obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hxs).mem_iff.1 hxs -- Observe that `ψ • σ = ψ • σ'` as dependent functions. @@ -615,133 +540,120 @@ lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M · simp [hσσ' x h] · simp [Function.notMem_support.mp fun a ↦ h (hψ a)] -- Then, it's a chain of (dependent) equalities. - calc cov X σ x - _ = cov X ((ψ : M → ℝ) • σ) x := by - rw [hcov.congr_σ_smoothBumpFunction X hX hσ ψ (mem_of_mem_nhds hxs)] - _ = cov X ((ψ : M → ℝ) • σ') x := by rw [funext this] - _ = cov X σ' x := by - rw [hcov.congr_σ_smoothBumpFunction X hX hσ' ψ (mem_of_mem_nhds hxs)] + calc cov σ x + _ = cov ((ψ : M → ℝ) • σ) x := by + rw [hcov.congr_σ_smoothBumpFunction hσ ψ (mem_of_mem_nhds hxs)] + _ = cov ((ψ : M → ℝ) • σ') x := by rw [funext this] + _ = cov σ' x := by + rw [hcov.congr_σ_smoothBumpFunction hσ' ψ (mem_of_mem_nhds hxs)] -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x -- this should be easy using the projection formula below. /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ -def differenceAux (cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) : - (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x) := - fun X σ ↦ cov X σ - cov' X σ +noncomputable def differenceAux + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : + (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x) := + fun σ ↦ cov σ - cov' σ -omit [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] in @[simp] lemma differenceAux_apply - (cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) - (X : Π x : M, TangentSpace I x) (σ : Π x : M, V x) : - differenceAux cov cov' X σ = cov X σ - cov' X σ := rfl - -variable [IsManifold I 1 M] - -lemma differenceAux_smul_eq - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) + (σ : Π x : M, V x) : + differenceAux cov cov' σ = cov σ - cov' σ := rfl + +lemma differenceAux_smul_eq [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) (hcov' : IsCovariantDerivativeOn F cov' u) - {X : Π x : M, TangentSpace I x} (σ : Π x : M, V x) (f : M → ℝ) + (σ : Π x : M, V x) (f : M → ℝ) {x : M} (hx : x ∈ u := by trivial) - (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hf : MDiffAt f x) : - differenceAux cov cov' X ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' X σ x:= + differenceAux cov cov' ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' σ x := by + apply IsCovariantDerivativeOn.ext + intro X hX calc _ - _ = cov X ((f : M → ℝ) • σ) x - cov' X ((f : M → ℝ) • σ) x := rfl - _ = (f x • cov X σ x + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) - - (f x • cov' X σ x + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by + _ = cov ((f : M → ℝ) • σ) x (X x) - cov' ((f : M → ℝ) • σ) x (X x) := rfl + _ = (f x • cov σ x (X x) + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) + - (f x • cov' σ x (X x) + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by simp [hcov.leibniz hX hσ hf, hcov'.leibniz hX hσ hf] - _ = f x • cov X σ x - f x • cov' X σ x := by simp - _ = f x • (cov X σ x - cov' X σ x) := by simp [smul_sub] + _ = f x • cov σ x (X x) - f x • cov' σ x (X x) := by simp + _ = f x • (cov σ x (X x) - cov' σ x (X x)) := by simp [smul_sub] _ = _ := rfl -lemma differenceAux_smul_eq' - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) - (hcov' : IsCovariantDerivativeOn F cov' u) - {X : Π x : M, TangentSpace I x} - (hX : MDiffAt (T% X) x) - {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) - {f : M → ℝ} (hf : MDiffAt f x) - (hx : x ∈ u := by trivial) : - differenceAux cov cov' (f • X) σ x = f x • differenceAux cov cov' X σ x := by - simp [differenceAux, hcov.smulX hX hσ hf, hcov'.smulX hX hσ hf, smul_sub] - -/-- The value of `differenceAux cov cov' X σ` at `x₀` depends only on `X x₀` and `σ x₀`. -/ +/-- The value of `differenceAux cov cov' σ` at `x₀` depends only on `σ x₀`. -/ lemma differenceAux_tensorial - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) (hcov' : IsCovariantDerivativeOn F cov' u) - [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {X X' : Π x : M, TangentSpace I x} {σ σ' : Π x : M, V x} {x₀ : M} - (hX : MDiffAt (T% X) x₀) -- TODO: is this hypotheses truly necessary? - (hX' : MDiffAt (T% X') x₀) + {σ σ' : Π x : M, V x} {x₀ : M} (hσ : MDiffAt (T% σ) x₀) (hσ' : MDiffAt (T% σ') x₀) - (hXX' : X x₀ = X' x₀) (hσσ' : σ x₀ = σ' x₀) (hx : x₀ ∈ u := by trivial) : - differenceAux cov cov' X σ x₀ = differenceAux cov cov' X' σ' x₀ := by - trans differenceAux cov cov' X' σ x₀ - · let φ : (Π x : M, TangentSpace I x) → (Π x, V x) := fun X ↦ differenceAux cov cov' X σ - change φ X x₀ = φ X' x₀ - -- TODO: is there a version of `tensoriality_criterion` which does not require `hX`? - apply tensoriality_criterion (E := E) (I := I) E (TangentSpace I) F V hX hX' hXX' - · intro f X hf hX - exact hcov.differenceAux_smul_eq' hcov' hX hσ hf - · intro X X' hX hX' - unfold φ differenceAux - simp only [Pi.sub_apply, hcov.addX hX hX' hσ, hcov'.addX hX hX' hσ] - abel - · let φ : (Π x : M, V x) → (Π x, V x) := fun σ ↦ differenceAux cov cov' X' σ - change φ σ x₀ = φ σ' x₀ - apply tensoriality_criterion (E := E) (I := I) F V F V hσ hσ' hσσ' - · intro f σ x hf - exact hcov.differenceAux_smul_eq hcov' σ f hx hX' hf x - · intro σ σ' hσ hσ' - unfold φ differenceAux - simp only [Pi.sub_apply] - rw [hcov.addσ, hcov'.addσ] <;> try assumption - abel + (hσσ' : σ x₀ = σ' x₀) (hx : x₀ ∈ u := by trivial) : + differenceAux cov cov' σ x₀ = differenceAux cov cov' σ' x₀ := by + apply tensoriality_criterion (I := I) F V (E →L[ℝ] F) + (fun x ↦ TangentSpace I x →L[ℝ] V x) hσ hσ' hσσ' + · intro f σ hf hσ + rw [hcov.differenceAux_smul_eq hcov' σ f hx hσ hf] + · intro σ σ' hσ hσ' + unfold differenceAux + simp only [Pi.sub_apply] + rw [hcov.addσ, hcov'.addσ] <;> try assumption + abel -lemma isBilinearMap_differenceAux +lemma isLinearMap_differenceAux [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] - [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] {s : Set M} {cov cov'} {x : M} + [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + {s : Set M} {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {x : M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) : - IsBilinearMap ℝ (fun (X₀ : TangentSpace I x) (σ₀ : V x) ↦ - differenceAux cov cov' (extend I E X₀) (extend I F σ₀) x) where - add_left u v w := by - simp only [differenceAux, extend_add, Pi.sub_apply] - rw [hcov.addX, hcov'.addX]; · abel - all_goals apply mdifferentiable_extend - add_right u v w := by + IsLinearMap ℝ (fun (σ₀ : V x) ↦ + differenceAux cov cov' (extend I F σ₀) x) where + map_add u v := by simp only [differenceAux, extend_add, Pi.sub_apply] rw [hcov.addσ, hcov'.addσ]; · abel all_goals apply mdifferentiable_extend - smul_left a u v := by - simp only [differenceAux, extend_smul, Pi.sub_apply] - rw [hcov.smul_const_X, hcov'.smul_const_X]; · module - all_goals apply mdifferentiable_extend - smul_right a u v := by + map_smul a u := by simp only [differenceAux, extend_smul, Pi.sub_apply] rw [hcov.smul_const_σ, hcov'.smul_const_σ]; · module all_goals apply mdifferentiable_extend +-- TODO this should be unnecessary, kept for now to minimize refactor +lemma isBilinearMap_differenceAux + [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] + [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + {s : Set M} {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {x : M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) : + IsBilinearMap ℝ (fun (σ₀ : V x) ↦ + differenceAux cov cov' (extend I F σ₀) x) where + add_left u v := by rw [(isLinearMap_differenceAux hcov hcov').map_add]; simp + add_right u v w := by rw [map_add] + smul_left u v := by rw [(isLinearMap_differenceAux hcov hcov').map_smul]; simp + smul_right a u := by simp [map_smul] + variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] /-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) - (x : M) : TangentSpace I x →L[ℝ] V x →L[ℝ] V x := + (x : M) : V x →L[ℝ] TangentSpace I x →L[ℝ] V x := + -- TODO give a construction which doesn't pass through `IsBilinearMap`, only `IsLinearMap` haveI : FiniteDimensional ℝ (TangentSpace I x) := by assumption open Classical in if hx : x ∈ s then (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap @@ -750,13 +662,13 @@ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Spac lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {s : Set M} {x : M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) - (hx : x ∈ s := by trivial) (X₀ : TangentSpace I x) (σ₀ : V x) : - difference hcov hcov' x X₀ σ₀ = - cov (extend I E X₀) (extend I F σ₀) x - cov' (extend I E X₀) (extend I F σ₀) x := by + (hx : x ∈ s := by trivial) (σ₀ : V x) : + difference hcov hcov' x σ₀ = + cov (extend I F σ₀) x - cov' (extend I F σ₀) x := by simp only [difference, hx, reduceDIte] rfl @@ -764,17 +676,17 @@ lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {s : Set M} {x : M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) - (hx : x ∈ s := by trivial) {X : Π x, TangentSpace I x} {σ : Π x, V x} - (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) : - difference hcov hcov' x (X x) (σ x) = - cov X σ x - cov' X σ x := by + (hx : x ∈ s := by trivial) {σ : Π x, V x} + (hσ : MDiffAt (T% σ) x) : + difference hcov hcov' x (σ x) = + cov σ x - cov' σ x := by simp only [difference, hx, reduceDIte] - exact hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hX - (mdifferentiable_extend ..) hσ (extend_apply_self _) (extend_apply_self _) hx + exact hcov.differenceAux_tensorial hcov' + (mdifferentiable_extend ..) hσ (extend_apply_self _) hx -- The classification of real connections over a trivial bundle section classification @@ -784,38 +696,36 @@ variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsMani /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term -/ -lemma exists_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} +lemma exists_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : - ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), - ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x ∈ s, - MDiffAt (T% X) x → MDiffAt (T% σ) x → - letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) - cov X σ x = d + A x (X x) (σ x) := by - use fun x ↦ hcov.difference (trivial I M F |>.mono <| subset_univ s) x - intro X σ x hx hX hσ - rw [hcov.difference_apply _ (by trivial) hX hσ] + ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), + ∀ σ : M → F, ∀ x ∈ s, MDiffAt (T% σ) x → + letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + cov σ x = d + A x (σ x) := by + use hcov.difference (trivial I M F |>.mono <| subset_univ s) + intro σ x hx hσ + rw [hcov.difference_apply _ (by trivial) hσ] module -noncomputable def one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} +noncomputable def one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : - Π x : M, TangentSpace I x →L[ℝ] F →L[ℝ] F := + Π x : M, F →L[ℝ] TangentSpace I x →L[ℝ] F := hcov.exists_one_form.choose -lemma eq_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} +lemma eq_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) - {X : (x : M) → TangentSpace I x} {σ : M → F} - {x : M} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) - cov X σ x = d + hcov.one_form x (X x) (σ x) := - hcov.exists_one_form.choose_spec X σ x hx hX hσ + {σ : M → F} + {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + cov σ x = d + hcov.one_form x (σ x) := + hcov.exists_one_form.choose_spec σ x hx hσ lemma _root_.CovariantDerivative.exists_one_form (cov : CovariantDerivative I F (Bundle.Trivial M F)) : - ∃ (A : (x : M) → TangentSpace I x →L[ℝ] F →L[ℝ] F), - ∀ X : (x : M) → TangentSpace I x, ∀ σ : M → F, ∀ x, - MDiffAt (T% X) x → MDiffAt (T% σ) x → - letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) - cov X σ x = d + A x (X x) (σ x) := by + ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), + ∀ σ : M → F, ∀ x, MDiffAt (T% σ) x → + letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + cov σ x = d + A x (σ x) := by simpa using cov.isCovariantDerivativeOn.exists_one_form end classification @@ -827,20 +737,20 @@ variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] local notation "TM" => TangentSpace I -variable {cov : (Π x : M, TangentSpace I x) → (M → F) → (M → F)} {s : Set M} +variable {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} noncomputable def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) × F →L[ℝ] F := - .snd ℝ (TM x) F + (evalL ℝ F F f ∘L hcov.one_form x ∘L .fst ℝ (TM x) F) + .snd ℝ (TM x) F + (hcov.one_form x f ∘L .fst ℝ (TM x) F) @[simp] lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : - hcov.projection x f (v, w) = w + hcov.one_form x v f := rfl + hcov.projection x f (v, w) = w + hcov.one_form x f v := rfl -lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (X : Π x : M, TM x) (σ : M → F) - {x : M} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - cov X σ x = hcov.projection x (σ x) (X x, mfderiv I 𝓘(ℝ, F) σ x (X x)) := by - simpa using hcov.eq_one_form hX hσ +lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (σ : M → F) + {x : M} (X₀ : TM x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + cov σ x X₀ = hcov.projection x (σ x) (X₀, mfderiv I 𝓘(ℝ, F) σ x X₀) := by + simpa using congr($(hcov.eq_one_form hσ) X₀) noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : Submodule ℝ (TM x × F) := @@ -862,7 +772,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : ∃ σ : M → F, MDiffAt (T% σ) x ∧ σ x = f ∧ mfderiv I 𝓘(ℝ, F) σ x u = v ∧ - cov (extend I E u) σ x = 0 := by + cov σ x u = 0 := by constructor · intro huv simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv @@ -872,16 +782,21 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : replace huv : v = 0 := by simpa using huv subst huv use fun x ↦ f - simp [hcov.zeroX, mdifferentiableAt_section, mdifferentiableAt_const] + simp [mdifferentiableAt_section, mdifferentiableAt_const] rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ use map_of_one_jet u w, ?_, h, h'' - · rw [hcov.eq_one_form (mdifferentiable_extend ..)] - · simp [w, h'', h, huv] + · rw [hcov.eq_one_form] + · simp only [w, h] + convert huv + convert ContinuousLinearMap.add_apply (M₁ := TangentSpace I x) (M₂ := F) _ + (hcov.one_form x f) u + exact h''.symm · rwa [mdifferentiableAt_section] · rwa [mdifferentiableAt_section] · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covσ] - rw [hcov.eq_one_form (mdifferentiable_extend ..) σ_diff, extend_apply_self] + rw [hcov.eq_one_form σ_diff] + rfl end projection_trivial_bundle @@ -889,64 +804,55 @@ end IsCovariantDerivativeOn section to_trivialization -variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] +variable (e : Trivialization F (π F V)) [VectorBundle ℝ F V] [MemTrivializationAtlas e] + [IsManifold I 1 M] noncomputable def Trivialization.pushCovDer - (cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)) : - (Π x : M, TangentSpace I x) → (M → F) → (M → F) := - fun X σ x ↦ e (cov X (fun x' ↦ e.symm x' <| σ x') x) |>.2 + (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : + (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := + fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (fun x' ↦ e.symm x' <| σ x') x) -omit [MemTrivializationAtlas e] in lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} (hcov : IsCovariantDerivativeOn F cov e.baseSet) - {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {x : M} - (hX : MDiffAt T%X x) (hσ : MDiffAt T%σ x) + {X₀ : TangentSpace I x} {σ : Π x : M, V x} {x : M} + (hσ : MDiffAt T%σ x) (hx : x ∈ e.baseSet := by assumption) : - (e.pushCovDer cov) X (fun x ↦ (e (σ x)).2) x = (e (cov X σ x)).2 := by - have : cov X (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov X σ x := by - apply hcov.congr_σ_of_eqOn hX _ hσ (e.baseSet_mem_nhds hx) + (e.pushCovDer cov) (fun x ↦ (e (σ x)).2) x X₀ = (e (cov σ x X₀)).2 := by + have : cov (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov σ x := by + apply hcov.congr_σ_of_eqOn _ hσ (e.baseSet_mem_nhds hx) · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? · rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] exact hσ unfold pushCovDer rw [this] + simp [Trivialization.coe_linearMapAt, hx] -variable {cov : (Π x : M, TangentSpace I x) → (Π x : M, V x) → (Π x : M, V x)} +variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) lemma Trivialization.pushCovDer_isCovariantDerivativeOn - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] {u : Set M} (hu : u ⊆ e.baseSet) (hcov : IsCovariantDerivativeOn F cov u) : IsCovariantDerivativeOn F (e.pushCovDer cov) u where - addX {X X' σ x} hX hX' hσ hx := by - set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold Trivialization.pushCovDer - rw [hcov.addX hX hX' hs, e.map_add ℝ (hu hx)] - smulX {X σ g x} hX hσ hg hx := by - set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold Trivialization.pushCovDer - rw [hcov.smulX hX hs hg, e.map_smul (hu hx)] - smul_const_σ {X σ x} a hX hσ hx := by + smul_const_σ {σ x} a hσ hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer - rw [← e.map_smul (hu hx), ← hcov.smul_const_σ a hX hs hx] + rw [← ContinuousLinearMap.comp_smul, ← hcov.smul_const_σ a hs hx] congr ext y simp [e.symm_map_smul, s] - addσ {X σ σ' x} hX hσ hσ' hx := by + addσ {σ σ' x} hσ hσ' hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ @@ -955,9 +861,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' unfold Trivialization.pushCovDer - rw [← e.map_add ℝ (hu hx)] - congr - rw [← hcov.addσ hX hs hs' hx] + rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] congr ext y simp [e.symm_map_add ℝ, s, s'] @@ -969,31 +873,38 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by ext y simp [s, e.symm_map_smul] - rw [this, hcov.leibniz hX hs hg hx] - suffices g x • (e ⟨x, cov X s x⟩).2 + (bar (g x)) ((mfderiv% g x) (X x)) • (e ⟨x, s x⟩).2 = - g x • (e ⟨x, cov X (fun x' ↦ e.symm x' (σ x')) x⟩).2 + - (bar (g x)) ((mfderiv% g x) (X x)) • σ x by simpa [e.map_add ℝ (hu hx), e.map_smul (hu hx)] + rw [this] + simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, Function.comp_apply, + AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearEquiv.coe_coe, + ContinuousLinearEquiv.coe_toLinearEquiv] + rw [hcov.leibniz hX hs hg hx] + simp only [AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearEquiv.coe_coe, + ContinuousLinearEquiv.coe_toLinearEquiv, _root_.map_add, _root_.map_smul, add_right_inj, s] congr - rw [e.apply_mk_symm (hu hx)] + exact e.linearMapAt_symmₗ (R := ℝ) (hu hx) (σ x) variable {e} in lemma Trivialization.coordChangeL_pushCovDer [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) - {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {s : M → F} (hs : MDiffAt s x) : - e.coordChangeL ℝ e' x (e.pushCovDer cov X s x) = - e'.pushCovDer cov X (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by + e.coordChangeL ℝ e' x ∘L (e.pushCovDer cov s x) = + e'.pushCovDer cov (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by + ext1 X₀ + simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, Function.comp_apply] unfold Trivialization.pushCovDer let σ := (fun x' ↦ e.symm x' (s x')) rw [coordChangeL_apply e e' hx] + simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, coe_linearMapAt, hx.1, + ↓reduceIte, Function.comp_apply, hx.2] refold_let σ - have : e.symm x (e ⟨x, cov X σ x⟩).2 = cov X σ x := by + have : e.symm x (e ⟨x, cov σ x X₀⟩).2 = cov σ x X₀ := by -- TODO fix `simp [hx.1]` not working - exact symm_apply_apply_mk e hx.1 (cov X σ x) + exact symm_apply_apply_mk e hx.1 (cov σ x X₀) rw [this] -- TODO: extract lemma? have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = @@ -1009,7 +920,7 @@ lemma Trivialization.coordChangeL_pushCovDer (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) have hσ : MDiffAt (T% σ) x := mdifferentiableAt_section_of_function e hx.1 hs - rw [hcov.congr_σ_of_eqOn hX hσ ?_ mem this] + rw [hcov.congr_σ_of_eqOn hσ ?_ mem this] -- TODO have automatation doing the next three lines… apply mdifferentiableAt_section_of_function e' hx.2 have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 @@ -1020,7 +931,8 @@ variable {e} in lemma Trivialization.coordChangeL_mem_horiz [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov @@ -1039,8 +951,8 @@ lemma Trivialization.coordChangeL_mem_horiz -- TODO: investigate whether the following line comes from inconsistent ways to -- state assumptions rw [mdifferentiableAt_section_trivial_iff] at sdiff - rw [← e.coordChangeL_pushCovDer hcov hx hX sdiff, covs] - simp + rw [← e.coordChangeL_pushCovDer hcov hx sdiff] + simp [covs] · sorry · congr · rw [← sxuw] @@ -1049,7 +961,6 @@ lemma Trivialization.coordChangeL_mem_horiz -- This is PAIIIIINNNN variable {e} in lemma Trivialization.coordChangeL_coordChangeL - [VectorBundle ℝ F V] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : e'.coordChangeL ℝ e x (e.coordChangeL ℝ e' x v) = v := by @@ -1081,7 +992,8 @@ variable {e} in lemma Trivialization.coordChangeL_mem_horiz_iff [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov @@ -1109,6 +1021,7 @@ namespace CovariantDerivative variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] local notation "TM" => TangentSpace I @@ -1186,17 +1099,17 @@ variable {cov : CovariantDerivative I F V} omit [ContMDiffVectorBundle 1 F V I] in lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] - {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) - (hX : MDiffAt (T% X) x) + {σ : Π x : M, V x} (x : M) (hσ : MDiffAt (T% σ) x) : - cov X σ x = cov.proj (σ x) - (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x (X x)) := by + cov σ x = cov.proj (σ x) ∘L + (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x) := by let t := trivializationAt F V x let s := fun x ↦ (t (σ x)).2 let Tσx := mfderiv% (T% σ) x -- FIXME `mfderiv%` fails in next line (fixed on master?) let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) - change cov X σ x = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) (X x)) + ext1 X₀ + change cov σ x X₀ = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) X₀) have hcov := cov.isCovariantDerivativeOn_pushCovDer t have hx := mem_baseSet_trivializationAt F V x have hs : MDiffAt (T% s) x := by @@ -1204,8 +1117,8 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] exact (mdifferentiableAt_section I s).mpr hσ apply t.eq_of hx erw [cov.snd_triv_proj (T% σ x), - ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hX hσ, - hcov.cov_eq_proj X s hX hs, t.mfderiv_comp_section hσ _ hx] + ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hσ, + hcov.cov_eq_proj s X₀ hs, t.mfderiv_comp_section hσ _ hx] end CovariantDerivative end horiz From e884dbfb44e8d7bfd51bfbce523e758e9ef6572e Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:01:23 +0000 Subject: [PATCH 426/601] remove X from leibniz rul --- .../CovariantDerivative/Basic.lean | 120 +++++++----------- 1 file changed, 45 insertions(+), 75 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index aaad9941c8695c..4411c181058d48 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -59,10 +59,11 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : f (σ + σ') x = f σ x + f σ' x - leibniz {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x} {g : M → 𝕜} {x} - (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): - -- TODO phrase without `X` as an equality in `TangentSpace I x →L[𝕜] V x` - f (g • σ) x (X x) = g x • f σ x (X x) + ((bar _).toFun (mfderiv I 𝓘(𝕜) g x (X x))) • σ x + leibniz {σ : Π x : M, V x} {g : M → 𝕜} {x} + (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): + f (g • σ) x = g x • f σ x + + ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L + (((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜) g x))) smul_const_σ {σ : Π x : M, V x} {x} (a : 𝕜) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : f (a • σ) x = a • f σ x @@ -98,7 +99,7 @@ lemma of_subsingleton [hE : Subsingleton E] [TopologicalSpace (TotalSpace E V)] exact { smul_const_σ {_σ x} a hσ hx := by simp [this] addσ {σ σ' x} hσ hσ' hx := by simp [this] - leibniz {X σ g x} hX hσ hg hx := by + leibniz {σ g x} hσ hg hx := by have H : (mfderiv I 𝓘(𝕜, 𝕜) g x) = 0 := have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) Subsingleton.eq_zero _ @@ -114,7 +115,7 @@ lemma mono {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s t : Set M} (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where addσ {_σ _σ' _x} hσ hσ' hx := hf.addσ hσ hσ' (hst hx) - leibniz {_X _σ _f _x} hX hσ hf' hx := hf.leibniz hX hσ hf' (hst hx) + leibniz {_σ _f _x} hσ hf' hx := hf.leibniz hσ hf' (hst hx) smul_const_σ {_σ _x} a hσ hx := hf.smul_const_σ a hσ (hst hx) lemma iUnion {ι : Type*} @@ -123,9 +124,9 @@ lemma iUnion {ι : Type*} addσ {_σ _σ' _x} hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).addσ hσ hσ' - leibniz {X σ f x} hX hσ hf' hx := by + leibniz {σ f x} hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).leibniz hX hσ hf' + exact (hf i).leibniz hσ hf' smul_const_σ {_σ _x} a hσ hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).smul_const_σ _ hσ @@ -141,7 +142,7 @@ lemma congr {f g : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V (hfg : ∀ {σ : Π x : M, V x}, ∀ {x}, x ∈ s → f σ x = g σ x) : IsCovariantDerivativeOn F g s where addσ hσ hσ' hx := by simp [← hfg hx, hf.addσ hσ hσ'] - leibniz hX hσ hf' hx := by simp [← hfg hx, hf.leibniz hX hσ hf'] + leibniz hσ hf' hx := by simp [← hfg hx, hf.leibniz hσ hf'] smul_const_σ a hσ hx := by simp [← hfg hx, hf.smul_const_σ a hσ] end @@ -176,8 +177,8 @@ def affineCombination smul_const_σ {_σ _x} a hσ hx := by simp [hf.smul_const_σ a hσ, hf'.smul_const_σ a hσ] module - leibniz {X σ φ x} hX hσ hφ hx := by - simp [hf.leibniz hX hσ hφ, hf'.leibniz hX hσ hφ] + leibniz {σ φ x} hσ hφ hx := by + simp [hf.leibniz hσ hφ, hf'.leibniz hσ hφ] module /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ @@ -209,32 +210,17 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] ext i simp [(h i).smul_const_σ a hσ] module - leibniz {X σ g x} hX hσ hg hx := by - calc (∑ i ∈ s, f i x • (cov i) (g • σ) x) (X x) - _ = ∑ i ∈ s, f i x • (cov i) (g • σ) x (X x) := by simp - _ = ∑ i ∈ s, ((g • (f i • (cov i) σ)) x (X x) - + f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x) := by - congr - ext i - rw [(h i).leibniz hX hσ hg] - simp_rw [Pi.smul_apply', smul_add] - dsimp - rw [smul_comm] - _ = ∑ i ∈ s, ((g • (f i • (cov i) σ)) x) (X x) - + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by - rw [Finset.sum_add_distrib] - _ = (g • ∑ i ∈ s, f i • (cov i) σ) x (X x) + (bar (g x)) - ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x := by - -- There has to be a shorter proof! - simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, - ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.coe_sum', - Finset.sum_apply, add_right_inj] - set B := (bar (g x)) ((mfderiv I 𝓘(𝕜) g x) (X x)) • σ x - trans (∑ i ∈ s, f i x) • B - · rw [Finset.sum_smul] - have : ∑ i ∈ s, f i x = 1 := by convert congr_fun hf x; simp - rw [this, one_smul] - simp + leibniz {σ g x} hσ hg hx := by + set B := (ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L + ((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜, 𝕜) g x))) + calc ∑ i ∈ s, f i x • cov i (g • σ) x + _ = ∑ i ∈ s, (g x • f i x • cov i σ x + f i x • B) := by + congr! 1 with i hi + rw [(h i).leibniz hσ hg] + module + _ = g x • ∑ i ∈ s, f i x • cov i σ x + (∑ i ∈ s, f i) x • B := by + rw [Finset.sum_add_distrib, Finset.smul_sum, Finset.sum_apply, Finset.sum_smul] + _ = g x • ∑ i ∈ s, f i x • cov i σ x + B := by rw [hf]; simp /-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : ℕ∞} @@ -259,8 +245,8 @@ lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] simp [hf.addσ hσ hσ'] abel smul_const_σ {_σ _x} a hσ hx := by simp [hf.smul_const_σ a hσ] - leibniz {X σ g x} hX hσ hg hx := by - simp [hf.leibniz hX hσ hg] + leibniz {σ g x} hσ hg hx := by + simp [hf.leibniz hσ hg] module end operations @@ -279,9 +265,10 @@ noncomputable def trivial [IsManifold I 1 M] : change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] smul_const_σ {_σ _x} a hσ hx := by ext X; rw [mfderiv_const_smul]; rfl - leibniz {X σ f x} hX hσ hf hx := by + leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ - exact mfderiv_smul hσ hf (X x) + ext1 X₀ + exact mfderiv_smul hσ hf X₀ lemma of_endomorphism (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F) : IsCovariantDerivativeOn F @@ -414,9 +401,10 @@ noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] smul_const_σ {_σ _x} a hσ hx := by ext; rw [mfderiv_const_smul]; rfl - leibniz {X σ f x} hX hσ hf hx := by + leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ - exact mfderiv_smul hσ hf (X x) } + ext1 X₀ + exact mfderiv_smul hσ hf X₀ } end trivial_bundle @@ -507,20 +495,10 @@ lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] (f : SmoothBumpFunction I x) (hx : x ∈ u) : cov ((f : M → ℝ) • σ) x = cov σ x := by - apply IsCovariantDerivativeOn.ext - intro X hX have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) - have := hcov.leibniz hX hσ hf hx - rw [hcov.leibniz hX hσ _ hx] - swap; · apply f.contMDiff.mdifferentiable (by norm_num) - calc _ - _ = cov σ x (X x) + 0 := ?_ - _ = cov σ x (X x) := by rw [add_zero] - suffices mfderiv% (1 : M → ℝ) x (X x) = 0 ∨ σ x = 0 by - simpa [f.eq_one, f.eventuallyEq_one.mfderiv_eq] + rw [hcov.leibniz hσ hf hx, f.eq_one, f.eventuallyEq_one.mfderiv_eq] rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] - left - rfl + simp lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -565,7 +543,7 @@ lemma differenceAux_apply (σ : Π x : M, V x) : differenceAux cov cov' σ = cov σ - cov' σ := rfl -lemma differenceAux_smul_eq [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] +lemma differenceAux_smul_eq [IsManifold I 1 M] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) @@ -575,16 +553,8 @@ lemma differenceAux_smul_eq [FiniteDimensional ℝ E] [T2Space M] [IsManifold I (hσ : MDiffAt (T% σ) x) (hf : MDiffAt f x) : differenceAux cov cov' ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' σ x := by - apply IsCovariantDerivativeOn.ext - intro X hX - calc _ - _ = cov ((f : M → ℝ) • σ) x (X x) - cov' ((f : M → ℝ) • σ) x (X x) := rfl - _ = (f x • cov σ x (X x) + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) - - (f x • cov' σ x (X x) + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by - simp [hcov.leibniz hX hσ hf, hcov'.leibniz hX hσ hf] - _ = f x • cov σ x (X x) - f x • cov' σ x (X x) := by simp - _ = f x • (cov σ x (X x) - cov' σ x (X x)) := by simp [smul_sub] - _ = _ := rfl + simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf] + module /-- The value of `differenceAux cov cov' σ` at `x₀` depends only on `σ x₀`. -/ lemma differenceAux_tensorial @@ -865,7 +835,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn congr ext y simp [e.symm_map_add ℝ, s, s'] - leibniz {X σ g x} hX hσ hg hx := by + leibniz {σ g x} hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ @@ -873,14 +843,14 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by ext y simp [s, e.symm_map_smul] - rw [this] - simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, Function.comp_apply, - AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearEquiv.coe_coe, - ContinuousLinearEquiv.coe_toLinearEquiv] - rw [hcov.leibniz hX hs hg hx] - simp only [AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearEquiv.coe_coe, - ContinuousLinearEquiv.coe_toLinearEquiv, _root_.map_add, _root_.map_smul, add_right_inj, s] - congr + rw [this, hcov.leibniz hs hg hx] + ext X₀ + simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, + ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', + continuousLinearMapAt_apply, Pi.smul_apply, Function.comp_apply, + ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply, _root_.map_smul, + add_right_inj, s] + congr! 1 exact e.linearMapAt_symmₗ (R := ℝ) (hu hx) (σ x) variable {e} in From 9dcc31811c4d8097b679929f284bc80076b11b59 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:06:21 +0000 Subject: [PATCH 427/601] =?UTF-8?q?remove=20smul=5Fconst=5F=CF=83=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CovariantDerivative/Basic.lean | 36 ++++--------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 4411c181058d48..7bba3ddfbf0f2d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -64,9 +64,14 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] f (g • σ) x = g x • f σ x + ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L (((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜) g x))) - smul_const_σ {σ : Π x : M, V x} {x} (a : 𝕜) + +theorem IsCovariantDerivativeOn.smul_const_σ [IsManifold I 1 M] + {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + (s : Set M) (hf : IsCovariantDerivativeOn F f s) + {σ : Π x : M, V x} {x} (a : 𝕜) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - f (a • σ) x = a • f σ x + f (a • σ) x = a • f σ x := by + simpa using hf.leibniz (g := fun _ ↦ a) hσ mdifferentiableAt_const /-- A covariant derivative ∇ is called of class `C^k` iff, @@ -97,7 +102,6 @@ lemma of_subsingleton [hE : Subsingleton E] [TopologicalSpace (TotalSpace E V)] have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) exact Subsingleton.eq_zero _ exact { - smul_const_σ {_σ x} a hσ hx := by simp [this] addσ {σ σ' x} hσ hσ' hx := by simp [this] leibniz {σ g x} hσ hg hx := by have H : (mfderiv I 𝓘(𝕜, 𝕜) g x) = 0 := @@ -116,7 +120,6 @@ lemma mono (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where addσ {_σ _σ' _x} hσ hσ' hx := hf.addσ hσ hσ' (hst hx) leibniz {_σ _f _x} hσ hf' hx := hf.leibniz hσ hf' (hst hx) - smul_const_σ {_σ _x} a hσ hx := hf.smul_const_σ a hσ (hst hx) lemma iUnion {ι : Type*} {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : ι → Set M} @@ -127,9 +130,6 @@ lemma iUnion {ι : Type*} leibniz {σ f x} hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).leibniz hσ hf' - smul_const_σ {_σ _x} a hσ hx := by - obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).smul_const_σ _ hσ end changing_set @@ -143,7 +143,6 @@ lemma congr {f g : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V IsCovariantDerivativeOn F g s where addσ hσ hσ' hx := by simp [← hfg hx, hf.addσ hσ hσ'] leibniz hσ hf' hx := by simp [← hfg hx, hf.leibniz hσ hf'] - smul_const_σ a hσ hx := by simp [← hfg hx, hf.smul_const_σ a hσ] end @@ -174,9 +173,6 @@ def affineCombination addσ {_σ _σ' x} hσ hσ' hx := by simp [hf.addσ hσ hσ', hf'.addσ hσ hσ'] module - smul_const_σ {_σ _x} a hσ hx := by - simp [hf.smul_const_σ a hσ, hf'.smul_const_σ a hσ] - module leibniz {σ φ x} hσ hφ hx := by simp [hf.leibniz hσ hφ, hf'.leibniz hσ hφ] module @@ -204,12 +200,6 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] congr ext i rw [← smul_add, (h i).addσ hσ hσ' hx] - smul_const_σ {_σ _x} a hσ hx := by - rw [Finset.smul_sum] - congr - ext i - simp [(h i).smul_const_σ a hσ] - module leibniz {σ g x} hσ hg hx := by set B := (ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L ((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜, 𝕜) g x))) @@ -244,7 +234,6 @@ lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] addσ {_σ _σ' _x} hσ hσ' hx := by simp [hf.addσ hσ hσ'] abel - smul_const_σ {_σ _x} a hσ hx := by simp [hf.smul_const_σ a hσ] leibniz {σ g x} hσ hg hx := by simp [hf.leibniz hσ hg] module @@ -264,7 +253,6 @@ noncomputable def trivial [IsManifold I 1 M] : change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] - smul_const_σ {_σ _x} a hσ hx := by ext X; rw [mfderiv_const_smul]; rfl leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ ext1 X₀ @@ -400,7 +388,6 @@ noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' rw [mfderiv_add hσ hσ'] - smul_const_σ {_σ _x} a hσ hx := by ext; rw [mfderiv_const_smul]; rfl leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ ext1 X₀ @@ -813,15 +800,6 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn {u : Set M} (hu : u ⊆ e.baseSet) (hcov : IsCovariantDerivativeOn F cov u) : IsCovariantDerivativeOn F (e.pushCovDer cov) u where - smul_const_σ {σ x} a hσ hx := by - set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold Trivialization.pushCovDer - rw [← ContinuousLinearMap.comp_smul, ← hcov.smul_const_σ a hs hx] - congr - ext y - simp [e.symm_map_smul, s] addσ {σ σ' x} hσ hσ' hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := From d63f81929e33308c8a109491d7b28fd6838f8229 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:39:24 +0000 Subject: [PATCH 428/601] move lemma --- .../VectorBundle/CovariantDerivative/Basic.lean | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 7bba3ddfbf0f2d..95ecc362dc5054 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -65,14 +65,6 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] + ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L (((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜) g x))) -theorem IsCovariantDerivativeOn.smul_const_σ [IsManifold I 1 M] - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - (s : Set M) (hf : IsCovariantDerivativeOn F f s) - {σ : Π x : M, V x} {x} (a : 𝕜) - (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - f (a • σ) x = a • f σ x := by - simpa using hf.leibniz (g := fun _ ↦ a) hσ mdifferentiableAt_const - /-- A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. @@ -157,6 +149,12 @@ lemma zeroσ [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) simpa using (hf.addσ (mdifferentiableAt_zeroSection ..) (mdifferentiableAt_zeroSection ..) : f (0 + 0) x = _) +theorem smul_const_σ (hf : IsCovariantDerivativeOn F f s) + {σ : Π x : M, V x} {x} (a : 𝕜) + (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + f (a • σ) x = a • f σ x := by + simpa using hf.leibniz (g := fun _ ↦ a) hσ mdifferentiableAt_const + end computational_properties section operations From 392b8a937a867a662a3bf88bf54b81fbdf70c79b Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 09:39:21 +0000 Subject: [PATCH 429/601] remove test vector field from smoothness criterion --- .../CovariantDerivative/Basic.lean | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 95ecc362dc5054..5eb115d55f1e93 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -70,13 +70,15 @@ A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ -class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : ℕ∞) +class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle 𝕜 F V] (k : ℕ∞) (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (u : Set M) where - contMDiff : ∀ {X : Π x : M, TangentSpace I x} {σ : Π x : M, V x}, - CMDiff[u] (k + 1) (T% σ) → - -- TODO phrase this in terms of the smoothness of a section of the bundle Hom(TM, V) - CMDiff[u] k (T% X) → CMDiff[u] k (T% (fun x ↦ cov σ x (X x))) + contMDiff : ∀ {σ : Π x : M, V x}, CMDiff[u] (k + 1) (T% σ) → + let f (x : M) : TotalSpace (E →L[𝕜] F) fun x ↦ TangentSpace I x →L[𝕜] V x := ⟨x, cov σ x⟩ + ContMDiffOn I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k f u + -- elaborators not working here, TODO investigate + -- ContMDiffOn I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k (T% (cov σ)) u + -- CMDiff[u] k f variable {F} @@ -183,10 +185,10 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : ContMDiffCovariantDerivativeOn F n (fun σ ↦ (f • (cov σ)) + (1 - f) • (cov' σ)) u where - contMDiff hX hσ := by + contMDiff hσ := by apply ContMDiffOn.add_section - · exact hf.smul_section <| Hcov.contMDiff hX hσ - · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hσ + · exact hf.smul_section <| Hcov.contMDiff hσ + · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hσ /-- A finite affine combination of covariant derivatives is a covariant derivative. -/ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] @@ -217,9 +219,9 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : ℕ∞} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) {f : ι → M → 𝕜} (hf : ∀ i ∈ s, CMDiff[u] n (f i)) : ContMDiffCovariantDerivativeOn F n (fun σ x ↦ ∑ i ∈ s, (f i x) • (cov i) σ x) u where - contMDiff {X} σ hσ hX := by + contMDiff {σ} hσ := by simpa using ContMDiffOn.sum_section - (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ hX) + (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ) variable {s : Set M} {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} @@ -310,11 +312,13 @@ A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ -class ContMDiffCovariantDerivative (cov : CovariantDerivative I F V) (k : ℕ∞) where +class ContMDiffCovariantDerivative [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) + (k : ℕ∞) where contMDiff : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ @[simp] -lemma contMDiffCovariantDerivativeOn_univ_iff {cov : CovariantDerivative I F V} {k : ℕ∞} : +lemma contMDiffCovariantDerivativeOn_univ_iff [VectorBundle 𝕜 F V] {cov : CovariantDerivative I F V} + {k : ℕ∞} : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ ↔ ContMDiffCovariantDerivative cov k := ⟨fun h ↦ ⟨h⟩, fun h ↦ h.contMDiff⟩ From 6f8f17085d886416bf93e80c3cb3c3fdbd808f0e Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 09:48:27 +0000 Subject: [PATCH 430/601] start on torsion --- .../CovariantDerivative/Torsion.lean | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 75ec9921d70510..18a795e57bda7f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -34,20 +34,22 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -- TODO: where is a good namespace for this? /-- The torsion of a covariant derivative on the tangent bundle `TM` -/ noncomputable def Bundle.torsion - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) : + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - fun X Y ↦ f X Y - f Y X - VectorField.mlieBracket I X Y + fun X Y x ↦ f X x (Y x) - f Y x (X x) - VectorField.mlieBracket I X Y x variable - {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {X X' Y : Π x : M, TangentSpace I x} variable (f X) in lemma torsion_self : torsion f X X = 0 := by + ext simp [torsion] variable (X Y) in lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by + ext simp only [torsion] rw [VectorField.mlieBracket_swap] module @@ -76,7 +78,7 @@ lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E variable (Y) in lemma torsion_smul_left_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} + {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : @@ -88,7 +90,7 @@ lemma torsion_smul_left_apply [CompleteSpace E] variable (X) in lemma torsion_smul_right_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x} + {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : torsion F X (f • Y) x = f x • torsion F X Y x := by @@ -99,7 +101,7 @@ end IsCovariantDerivativeOn /-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ noncomputable def IsTorsionFreeOn - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) (U : Set M) : Prop := ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 @@ -126,7 +128,7 @@ section -- unused? lemma congr {s : Set M} (h : IsTorsionFreeOn f s) - (hfg : ∀ {X Y : Π x : M, TangentSpace I x}, ∀ {x}, x ∈ s → f X Y x = g X Y x) : + (hfg : ∀ {X Y : Π x : M, TangentSpace I x}, ∀ {x}, x ∈ s → f X x (Y x) = g X x (Y x)) : IsTorsionFreeOn g s := by intro x hx X Y specialize h x hx X Y @@ -230,7 +232,7 @@ lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTo -- This should be obvious; am I doing something wrong? lemma isTorsionFree_iff : IsTorsionFree cov ↔ - ∀ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by + ∀ X Y x, cov X x (Y x) - cov Y x (X x) = VectorField.mlieBracket I X Y x := by simp only [IsTorsionFree] constructor · intro h X Y @@ -245,7 +247,7 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ variable {n} in lemma aux1 {ι : Type*} [Fintype ι] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : torsion f X Y x = ∑ i, (hs.coeff i) X x • torsion f (s i) Y x := @@ -261,7 +263,7 @@ lemma aux1 {ι : Type*} [Fintype ι] -- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x variable {n} in lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : @@ -284,7 +286,7 @@ lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] /-- We can test torsion-freeness on a set using a local frame. -/ lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by From 4c2d30be8bb8576b75f28a73dc825394a11837ae Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 09:59:28 +0000 Subject: [PATCH 431/601] Fix torsion --- .../CovariantDerivative/Torsion.lean | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 18a795e57bda7f..7eecb845a4819d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -49,9 +49,10 @@ lemma torsion_self : torsion f X X = 0 := by variable (X Y) in lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by - ext - simp only [torsion] + ext x + unfold torsion rw [VectorField.mlieBracket_swap] + dsimp module namespace IsCovariantDerivativeOn @@ -64,9 +65,9 @@ lemma torsion_add_left_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by - sorry -- simp [torsion, hf.addX (x := x) (hx := sorry) hX hX'] + simp [torsion]--, hf.addX (x := x) (hx := sorry) hX hX'] -- rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] - -- module + sorry -- module lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) @@ -151,13 +152,14 @@ variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) -- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! variable (f) in @[simp] -lemma torsion_zero (hX : MDiff T% X) : torsion cov 0 X = 0 := by - simp [torsion, cov.zeroX hX, cov.zeroσ hX] +lemma torsion_zero : torsion cov 0 X = 0 := by + ext x + simp [torsion] @[simp] -lemma torsion_zero' (hX : MDiff T% X) : torsion cov X 0 = 0 := by - rw [torsion_antisymm, torsion_zero hX]; simp +lemma torsion_zero' : torsion cov X 0 = 0 := by + rw [torsion_antisymm, torsion_zero]; simp variable (Y) in lemma torsion_add_left [CompleteSpace E] @@ -233,17 +235,8 @@ lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTo -- This should be obvious; am I doing something wrong? lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ X Y x, cov X x (Y x) - cov Y x (X x) = VectorField.mlieBracket I X Y x := by - simp only [IsTorsionFree] - constructor - · intro h X Y - have : torsion cov X Y = 0 := by simp [h] - -- XXX: abel, ring, module and grind all fail here - exact eq_of_sub_eq_zero this - · intro h - ext X Y x - specialize h X Y - apply congr_fun - simp_all [torsion] + unfold IsTorsionFree torsion + simp [funext_iff, sub_eq_iff_eq_add'] variable {n} in lemma aux1 {ι : Type*} [Fintype ι] From cfdf94312f1fc629070a6dace877c43e939f585b Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:38:00 +0000 Subject: [PATCH 432/601] start to adjust levi-civita --- .../CovariantDerivative/LeviCivita.lean | 113 ++++++++++-------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 9ff0a689e542cb..18af8b7b543046 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -179,13 +179,15 @@ namespace CovariantDerivative -- TODO: include in cheat sheet! variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) +local notation "∇" X "," Y => fun (x:M) ↦ cov X x (Y x) + /-- Predicate saying for a connection `∇` on a Riemannian manifold `M` to be compatible with the ambient metric, i.e. for all smooth vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ def IsCompatible : Prop := ∀ X Y Z : Π x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! ∀ x : M, - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪cov X Y, Z⟫ x + ⟪Y, cov X Z⟫ x + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. @@ -639,8 +641,8 @@ end leviCivitaRhs variable (X Y Z) in lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = - ⟪cov X Y, Z⟫ + ⟪Y, cov Z X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by - trans ⟪cov X Y, Z⟫ + ⟪Y, cov X Z⟫ + ⟪∇ X, Y, Z⟫ + ⟪Y, ∇ Z, X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by + trans ⟪∇ X, Y, Z⟫ + ⟪Y, ∇ X, Z⟫ · ext x exact h.1 X Y Z x · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] @@ -654,23 +656,23 @@ variable (X Y Z) {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : - ⟪cov X Y, Z⟫ = leviCivitaRhs I X Y Z := by - set A := ⟪cov X Y, Z⟫ - set B := ⟪cov Z X, Y⟫ - set C := ⟪cov Y Z, X⟫ + ⟪∇ X, Y, Z⟫ = leviCivitaRhs I X Y Z := by + set A := ⟪∇ X, Y, Z⟫ + set B := ⟪∇ Z, X, Y⟫ + set C := ⟪∇ Y, Z, X⟫ set D := ⟪Y, VectorField.mlieBracket I X Z⟫ with D_eq set E := ⟪Z, VectorField.mlieBracket I Y X⟫ with E_eq set F := ⟪X, VectorField.mlieBracket I Z Y⟫ with F_eq have eq1 : rhs_aux I X Y Z = A + B + D := by - simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (cov Z X)] + simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (∇ Z, X)] have eq2 : rhs_aux I Y Z X = C + A + E := by - simp only [aux I Y Z X cov h, A, C, E, product_swap _ (cov X Y) Z] + simp only [aux I Y Z X cov h, A, C, E, product_swap _ (∇ X, Y) Z] have eq3 : rhs_aux I Z X Y = B + C + F := by - simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] + simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (∇ Y, Z)] -- Add eq1 and eq2 and subtract eq3. have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by rw [eq1, eq2, eq3]; abel - -- Solve for ⟪cov X Y, Z⟫ and obtain the claim. + -- Solve for ⟪∇ X, Y, Z⟫ and obtain the claim. have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) (by simp [this]) have almoster : A + A = leviCivitaRhs' I X Y Z := by simp only [leviCivitaRhs', *] @@ -736,7 +738,7 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] given a trivialisation `e` and a choice `o` of linear order on the standard basis of `E`, we take the expression defined by the Koszul formula (using the orthonormal frame determined by `e` and `o`). -/ -noncomputable def lcCandidateAux [FiniteDimensional ℝ E] +noncomputable def lcCandidateAux' [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := @@ -754,15 +756,44 @@ noncomputable def lcCandidateAux [FiniteDimensional ℝ E] -- is given by `leviCivitaRhs X Y (s i)`. ∑ i, ((leviCivitaRhs I X Y (frame i)) x) • (frame i x) +noncomputable def lcCandidateAux [FiniteDimensional ℝ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] + (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) + (Y : (x : M) → TangentSpace I x) (x : M) : + TangentSpace I x →L[ℝ] TangentSpace I x := + have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) + LinearMap.toContinuousLinearMap <| + { toFun X₀ := lcCandidateAux' I e o Y (_root_.extend I E X₀) x + map_add' X₀ Y₀ := by + sorry + -- simp only [lcCandidateAux', hE, ↓reduceDIte] + -- simp only [← Finset.sum_add_distrib, ← add_smul] + -- congr; ext i + -- rw [leviCivitaRhs_addX_apply] <;> try assumption + -- let b := Basis.ofVectorSpace ℝ E + -- have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + -- exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx + map_smul' a X₀ := by + sorry + -- simp only [lcCandidateAux', hE, ↓reduceDIte] + -- rw [Finset.smul_sum] + -- congr; ext i + -- rw [leviCivitaRhs_smulX_apply] <;> try assumption + -- · simp [← smul_assoc] + -- · let b := Basis.ofVectorSpace ℝ E + -- have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty + -- exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx } + } + variable (M) in -- TODO: make g part of the notation! /-- Given two vector fields X and Y on TM, compute the candidate definition for the Levi-Civita connection on `TM`. -/ noncomputable def lcCandidate [FiniteDimensional ℝ E] (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : - (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := + (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x) := -- Use the preferred trivialisation at `x` to write down a candidate for the existence. - fun X Y x ↦ lcCandidateAux I (trivializationAt E (TangentSpace I : M → Type _) x) o X Y x + fun X x ↦ lcCandidateAux I (trivializationAt E (TangentSpace I : M → Type _) x) o X x variable (X Y) in /-- The definition `lcCandidate` behaves well: for each compatible trivialisation `e`, @@ -770,7 +801,7 @@ the candidate definition using `e` agrees with `lcCandidate` on `e.baseSet`. -/ lemma lcCandidate_eq_lcCandidateAux [FiniteDimensional ℝ E] (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} {x : M} (hx : x ∈ e.baseSet) : - lcCandidate I M o X Y x = lcCandidateAux I e o X Y x := by + lcCandidate I M o X x = lcCandidateAux I e o X x := by by_cases hE : Subsingleton E · simp [lcCandidate, lcCandidateAux, hE] · simp only [lcCandidate, lcCandidateAux, hE, ↓reduceDIte] @@ -782,31 +813,7 @@ lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet where - addX {_X _X' _σ x} hX hX' hσ hx := by - simp only [lcCandidateAux, hE, ↓reduceDIte] - simp only [← Finset.sum_add_distrib, ← add_smul] - congr; ext i - rw [leviCivitaRhs_addX_apply] <;> try assumption - let b := Basis.ofVectorSpace ℝ E - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx - smulX {_X _σ _g _x} hX hσ hg hx := by - simp only [lcCandidateAux, hE, ↓reduceDIte] - rw [Finset.smul_sum] - congr; ext i - rw [leviCivitaRhs_smulX_apply] <;> try assumption - · simp [← smul_assoc] - · let b := Basis.ofVectorSpace ℝ E - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx - smul_const_σ {X _σ x} a hX hσ hx := by - simp only [lcCandidateAux, hE, ↓reduceDIte] - rw [Finset.smul_sum]; congr; ext i - rw [leviCivitaRhs_smulY_const_apply hX hσ, ← smul_assoc] - · let b := Basis.ofVectorSpace ℝ E - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx - addσ {X σ σ' x} hX hσ hσ' hx := by + addσ {σ σ' x} hσ hσ' hx := by simp only [lcCandidateAux, hE, ↓reduceDIte] simp only [← Finset.sum_add_distrib, ← add_smul] congr; ext i @@ -814,7 +821,7 @@ lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx - leibniz {X σ g x} hX hσ hg hx := by + leibniz {σ g x} hσ hg hx := by simp only [lcCandidateAux, hE, ↓reduceDIte] let b := Basis.ofVectorSpace ℝ E have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty @@ -903,22 +910,22 @@ section with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, this is a function `Γᵢⱼᵏ : M → ℝ`, whose value outside of `U` is meaningless. -/ noncomputable def ChristoffelSymbol - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) {U : Set M} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := - hs.coeff k (f (s i) (s j)) + hs.coeff k (fun x ↦ f (s i) x (s j x)) -- special case of `foobar` below; needed? lemma ChristoffelSymbol.sum_eq - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)) + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (i j : ι) (hx : x ∈ U) : - f (s i) (s j) x = ∑ k, (ChristoffelSymbol I f hs i j k x) • (s k) x := by + f (s i) x (s j x) = ∑ k, (ChristoffelSymbol I f hs i j k x) • (s k) x := by simp only [ChristoffelSymbol] exact hs.coeff_sum_eq _ hx variable {U : Set M} - {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} -- Note that this result is false if `{s i}` is merely a local frame. @@ -926,7 +933,7 @@ lemma eq_product_apply [Fintype ι] (hf : IsCovariantDerivativeOn E f U) (hs : IsOrthonormalFrameOn I E n s U) (i j k : ι) (hx : x ∈ U) : - ChristoffelSymbol I f hs.toIsLocalFrameOn i j k x = ⟪f (s i) (s j), (s k)⟫ x := by + ChristoffelSymbol I f hs.toIsLocalFrameOn i j k x = inner ℝ (f (s i) x (s j x)) (s k x) := by -- Choose a linear order on ι: which one really does not matter for our result. have : LinearOrder ι := by choose r wo using exists_wellOrder _ @@ -937,7 +944,7 @@ lemma eq_product_apply [Fintype ι] -- Lemma 4.3 in Lee, Chapter 5: first term still missing lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E 1 s U) {x : M} (hx : x ∈ U) : - f X Y x = ∑ k, + f X x (Y x) = ∑ k, letI S₁ := ∑ i, ∑ j, (hs.coeff i X) * (hs.coeff j Y) * (ChristoffelSymbol I f hs i j k) letI S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! S₁ x • s k x := by @@ -946,7 +953,7 @@ lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeO have : ∀ x ∈ U, Y x = ∑ i, (hs.coeff i) Y x • s i x := by intro x hx apply hs.coeff_sum_eq Y hx - have : f X Y x = f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by + have : f X x (Y x) = f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by -- apply `congr_σ_of_eventuallyEq` from Basic.lean (after restoring it) -- want U to be a neighbourhood of x to make this work sorry @@ -966,7 +973,7 @@ lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) (hs : IsLocalFrameOn I E n s U) (hfg : ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x) : - ∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x := by + ∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X x (Y x) = g X x (Y x) := by have (i j : ι) : ∀ x ∈ U, f (s i) (s j) x = g (s i) (s j) x := by intro x hx rw [hs.eq_iff_coeff hx] @@ -981,7 +988,7 @@ lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ι] [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) (hs : IsLocalFrameOn I E n s U) : - (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X Y x = g X Y x) ↔ + (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X x (Y x) = g X x (Y x)) ↔ ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x := ⟨fun hfg _i _j _k _x hx ↦ hs.coeff_congr (hfg _ _ _ hx ) .., fun h X Y x hx ↦ hf.congr_of_christoffelSymbol_eq I hg hs h X Y x hx⟩ @@ -1003,7 +1010,7 @@ end -- Lemma 4.3 in Lee, Chapter 5: first term still missing variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x)} + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} -- errors: omit [IsContMDiffRiemannianBundle I 1 E fun x ↦ TangentSpace I x] in /-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. @@ -1018,7 +1025,7 @@ lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fin ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by rw [hf.isTorsionFreeOn_iff_localFrame (n := n) hs] have (i j : ι) {x} (hx : x ∈ U) : - torsion f (s i) (s j) x = f (s i) (s j) x - f (s j) (s i) x := by + torsion f (s i) (s j) x = f (s i) x (s j x) - f (s j) x (s i x) := by simp [torsion, hs'' i j ⟨x, hx⟩] peel with i j refine ⟨?_, ?_⟩ From a6fec8bc39f6c98746f8f2f938448c257ab7f066 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:12:02 +0000 Subject: [PATCH 433/601] give a phrasing for the tensoriality construction --- .../CovariantDerivative/Prelim.lean | 86 ++++++++++++++++++- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index c892eb43f4cd48..7cf0676cfb783b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -376,6 +376,89 @@ theorem contDiff_extend end extend +section tensoriality + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] + (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [T2Space M] [ChartedSpace H M] [IsManifold I ∞ M] + +variable + (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] [FiniteDimensional ℝ F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] + +variable + (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] + {V' : M → Type*} [TopologicalSpace (TotalSpace F' V')] [(x : M) → AddCommGroup (V' x)] + [(x : M) → Module ℝ (V' x)] [(x : M) → TopologicalSpace (V' x)] + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] + [FiberBundle F' V'] [VectorBundle ℝ F' V'] + +noncomputable def mkTensorAt + -- `φ` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x, V' x)) (x) + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') x = φ σ x + φ σ' x) : + V x →L[ℝ] V' x := + let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space + have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + LinearMap.toContinuousLinearMap { + toFun v := φ (_root_.extend I F v) x + map_add' v₁ v₂ := by + rw [← φ_add] + · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add + · exact mdifferentiable_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + map_smul' c v := by + dsimp + rw [← φ_smul (fun _ ↦ c)] + · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add + · exact mdifferentiable_extend .. + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. } + +noncomputable def mkTensor + -- `φ` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x, V' x)) + -- TODO could weaken `φ_smul` and `φ_add` to require the property only globally, is it useful? + (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) + (x : M) : + V x →L[ℝ] V' x := + mkTensorAt I F F' φ x (φ_smul x) (φ_add x) + +theorem contMDiff_mkTensor + (φ : (Π x : M, V x) → (Π x, V' x)) + (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) + -- hopefully this is the correct smoothness criterion! + {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : + -- elaborators not working here + let T (x : M) : TotalSpace (F →L[ℝ] F') (fun x ↦ V x →L[ℝ] V' x) := + ⟨x, mkTensor I F F' φ φ_smul φ_add x⟩ + ContMDiff I (I.prod 𝓘(ℝ, F →L[ℝ] F')) k T := by + sorry + +end tensoriality + section trivilization_topology variable {B F Z : Type*} [TopologicalSpace B] @@ -781,6 +864,3 @@ lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} · simp end linear_algebra_isCompl - - - From e9be3d07f9f6990f01a1b4e1b461372d86c60015 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 16:18:36 +0000 Subject: [PATCH 434/601] chore(Torsion): cosmetic rename --- .../CovariantDerivative/Torsion.lean | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 7eecb845a4819d..719f2173c26a08 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -34,21 +34,21 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -- TODO: where is a good namespace for this? /-- The torsion of a covariant derivative on the tangent bundle `TM` -/ noncomputable def Bundle.torsion - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) : + (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - fun X Y x ↦ f X x (Y x) - f Y x (X x) - VectorField.mlieBracket I X Y x + fun X Y x ↦ cov X x (Y x) - cov Y x (X x) - VectorField.mlieBracket I X Y x variable - {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {X X' Y : Π x : M, TangentSpace I x} variable (f X) in -lemma torsion_self : torsion f X X = 0 := by +lemma torsion_self : torsion cov X X = 0 := by ext simp [torsion] variable (X Y) in -lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by +lemma torsion_antisymm : torsion cov X Y = - torsion cov Y X := by ext x unfold torsion rw [VectorField.mlieBracket_swap] @@ -57,22 +57,21 @@ lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by namespace IsCovariantDerivativeOn -variable [h : IsManifold I ∞ M] -variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) +variable [IsManifold I ∞ M] {U : Set M} (hf : IsCovariantDerivativeOn E cov U) variable (Y) in lemma torsion_add_left_apply [CompleteSpace E] - (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) + (hf : IsCovariantDerivativeOn E cov U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : - torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by + torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by simp [torsion]--, hf.addX (x := x) (hx := sorry) hX hX'] -- rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] sorry -- module -lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x ∈ U) +lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E cov U) (hx : x ∈ U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : - torsion f Y (X + X') x = torsion f Y X x + torsion f Y X' x := by + torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by rw [torsion_antisymm, Pi.neg_apply, hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] simp; abel @@ -100,11 +99,11 @@ lemma torsion_smul_right_apply [CompleteSpace E] end IsCovariantDerivativeOn -/-- `f` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ +/-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ noncomputable def IsTorsionFreeOn - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) + (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) (U : Set M) : Prop := - ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion f X Y x = 0 + ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion cov X Y x = 0 namespace IsTorsionFreeOn @@ -114,11 +113,11 @@ section changing_set In this changing we change `s` in `IsTorsionFreeOn F f s`. -/ -lemma mono {s t : Set M} (hf : IsTorsionFreeOn f t) (hst : s ⊆ t) : IsTorsionFreeOn f s := +lemma mono {s t : Set M} (hf : IsTorsionFreeOn cov t) (hst : s ⊆ t) : IsTorsionFreeOn cov s := fun _ hx _ _ ↦ hf _ (hst hx) .. -lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn f (s i)) : - IsTorsionFreeOn f (⋃ i, s i) := by +lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn cov (s i)) : + IsTorsionFreeOn cov (⋃ i, s i) := by rintro x ⟨si, ⟨i, hi⟩, hxsi⟩ X Y exact hf i x (by simp [hi, hxsi]) X Y @@ -128,9 +127,9 @@ end changing_set section -- unused? -lemma congr {s : Set M} (h : IsTorsionFreeOn f s) - (hfg : ∀ {X Y : Π x : M, TangentSpace I x}, ∀ {x}, x ∈ s → f X x (Y x) = g X x (Y x)) : - IsTorsionFreeOn g s := by +lemma congr {s : Set M} (h : IsTorsionFreeOn cov s) + (hfg : ∀ {X Y : Π x : M, TangentSpace I x}, ∀ {x}, x ∈ s → cov X x (Y x) = cov' X x (Y x)) : + IsTorsionFreeOn cov' s := by intro x hx X Y specialize h x hx X Y -- now, use torsion congruence lemma, i.e. tensoriality of sorts! @@ -143,11 +142,11 @@ end IsTorsionFreeOn namespace CovariantDerivative -variable [h : IsManifold I ∞ M] +variable [IsManifold I ∞ M] -- The torsion tensor of a covariant derivative on the tangent bundle `TM`. variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} -variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) +variable {U : Set M} (hf : IsCovariantDerivativeOn E cov U) -- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! variable (f) in From c17e97f027580fccd1cab0dae22a54a249d3678f Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:43:13 +0000 Subject: [PATCH 435/601] 2-tensor construction --- .../CovariantDerivative/Prelim.lean | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 7cf0676cfb783b..1a300d58e16024 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -457,6 +457,75 @@ theorem contMDiff_mkTensor ContMDiff I (I.prod 𝓘(ℝ, F →L[ℝ] F')) k T := by sorry +-- TODO allow the two input types to differ +noncomputable def mk2TensorAt + -- `φ` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} + (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : + V x →L[ℝ] V x →L[ℝ] V' x := + let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space + have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + have H : IsBilinearMap ℝ + (fun (v w : V x) ↦ φ (_root_.extend I F v) (_root_.extend I F w) x) := + { add_left v₁ v₂ w := by + rw [← σ_add] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + smul_left c v w := by + rw [← σ_smul (f := fun _ ↦ c)] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. + add_right v w₁ w₂ := by + rw [← τ_add] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + smul_right c v w := by + rw [← τ_smul (f := fun _ ↦ c)] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. } + H.toContinuousLinearMap + end tensoriality section trivilization_topology From 75204986657229cb51fb5afdeea14ed1ecaf8f1e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 16:51:24 +0000 Subject: [PATCH 436/601] chore: cherry-pick Lie bracket changes from #26743 --- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 39 ++ .../Manifold/MFDeriv/NormedSpace.lean | 21 + .../Manifold/VectorField/LieBracket.lean | 400 ++++++------------ 3 files changed, 198 insertions(+), 262 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index 487bed96525b03..39ad73ccb15588 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -382,4 +382,43 @@ theorem TangentBundle.symmL_trivializationAt simpa using mdifferentiableWithinAt_extChartAt_symm (by simp [hx]) simp [hx, mfderivWithin, this] +omit [IsManifold I 1 M] in +/-- The `fderivWithin` of the round-trip composition `(extChartAt I x) ∘ (extChartAt I x).symm` +at the chart point in `range I` equals the identity. -/ +lemma fderivWithin_extChartAt_comp_extChartAt_symm_range : + fderivWithin 𝕜 ((extChartAt I x) ∘ (extChartAt I x).symm) (range I) (extChartAt I x x) = + ContinuousLinearMap.id 𝕜 _ := by + set φ := extChartAt I x + have eq_nhd : ((extChartAt I x) ∘ (extChartAt I x).symm) =ᶠ[𝓝[range I] (extChartAt I x x)] id := + Filter.eventuallyEq_of_mem (extChartAt_target_mem_nhdsWithin x) + (fun _ ↦ (extChartAt I x).right_inv) + rw [eq_nhd.fderivWithin_eq (by simp)] + exact fderivWithin_id <| I.uniqueDiffOn.uniqueDiffWithinAt (mem_range_self _) + +/-- The manifold derivative of `extChartAt` at the basepoint is the identity. -/ +lemma mfderiv_extChartAt_self : + mfderiv I 𝓘(𝕜, E) (extChartAt I x) x = ContinuousLinearMap.id 𝕜 _ := by + rw [← TangentBundle.continuousLinearMapAt_trivializationAt (by simp), + TangentBundle.continuousLinearMapAt_trivializationAt_eq_core (by simp)] + ext v + simpa using (tangentBundleCore I M).coordChange_self (achart H x) x (mem_chart_source H x) v + +-- TODO: should there be a version for `extChartAt`? +/-- The manifold derivative within `range I` of `(extChartAt I x).symm` at the chart point is +the identity. -/ +lemma mfderivWithin_range_extChartAt_symm : + mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) (extChartAt I x x) = + ContinuousLinearMap.id 𝕜 _ := by + have hcomp := mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (I := I) + (mem_extChartAt_source x) + rw [mfderiv_extChartAt_self, ContinuousLinearMap.comp_id] at hcomp + simpa using hcomp + +/-- The inverse of the derivative of `(extChartAt I x).symm` at the chart point, +applied to a tangent vector, gives back the tangent vector. -/ +lemma mfderivWithin_extChartAt_symm_inverse_apply (v : TangentSpace I x) : + (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) (extChartAt I x x)).inverse v = v := by + rw [mfderivWithin_range_extChartAt_symm, ContinuousLinearMap.inverse_id] + exact ContinuousLinearMap.id_apply .. + end extChartAt diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 6c21fef2b5823d..c959c17232e059 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -81,6 +81,27 @@ theorem Differentiable.comp_mdifferentiable {g : F → F'} {f : M → F} (hg : D (hf : MDifferentiable I 𝓘(𝕜, F) f) : MDifferentiable I 𝓘(𝕜, F') (g ∘ f) := fun x => hg.differentiableAt.comp_mdifferentiableAt (hf x) +section extChartAt + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {f : M → F} + +-- TODO: add pre-composition version also +theorem MDifferentiableWithinAt.differentiableWithinAt_comp_extChartAt_symm + (hf : MDifferentiableWithinAt I 𝓘(𝕜, F) f s x) : + letI φ := extChartAt I x + DifferentiableWithinAt 𝕜 (f ∘ φ.symm) (φ.symm ⁻¹' s ∩ range I) (φ x) := by + simpa [extChartAt_self_eq] using (mdifferentiableWithinAt_iff.1 hf).2 + +-- TODO: the `IsManifold I 1 M` assumption can probably be removed +theorem DifferentiableWithinAt.mdifferentiableWithinAt_of_comp_extChartAt_symm [IsManifold I 1 M] + (hf : letI φ := extChartAt I x + DifferentiableWithinAt 𝕜 (f ∘ φ.symm) (φ.symm ⁻¹' s ∩ range I) (φ x)) : + MDifferentiableWithinAt I 𝓘(𝕜, F) f s x := by + refine (mdifferentiableWithinAt_iff_source_of_mem_source (mem_chart_source H x)).2 ?_ + simpa [extChartAt_self_eq] using hf.mdifferentiableWithinAt + +end extChartAt + end Module /-! ### Linear maps between normed spaces are differentiable -/ diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 0fd99c0a3f1069..ae99f40da40153 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -10,6 +10,7 @@ public import Mathlib.Geometry.Manifold.ContMDiffMFDeriv public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable public import Mathlib.Geometry.Manifold.VectorField.Pullback +import Mathlib.Geometry.Manifold.Notation /-! # Lie brackets of vector fields on manifolds @@ -85,8 +86,7 @@ lemma mlieBracketWithin_def : ((extChartAt I x₀).symm ⁻¹' s ∩ range I)) x₀ := rfl lemma mlieBracketWithin_apply : - mlieBracketWithin I V W s x₀ = - (mfderiv I 𝓘(𝕜, E) (extChartAt I x₀) x₀).inverse + mlieBracketWithin I V W s x₀ = (mfderiv% (extChartAt I x₀) x₀).inverse ((lieBracketWithin 𝕜 (mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x₀).symm V (range I)) (mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x₀).symm W (range I)) @@ -299,177 +299,95 @@ protected theorem _root_.Filter.EventuallyEq.mlieBracket_vectorField section variable {c : 𝕜} -variable [IsManifold I 2 M] [CompleteSpace E] +variable [IsManifold I 2 M] lemma _root_.MDifferentiableWithinAt.differentiableWithinAt_mpullbackWithin_vectorField - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) : + [CompleteSpace E] + (hV : MDiffAt[s] (fun x ↦ (V x : TangentBundle I M)) x) : DifferentiableWithinAt 𝕜 (mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I)) - ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by + ((extChartAt I x).symm ⁻¹' s ∩ range I) (extChartAt I x x) := by apply MDifferentiableWithinAt.differentiableWithinAt have := MDifferentiableWithinAt.mpullbackWithin_vectorField_inter_of_eq hV (contMDiffWithinAt_extChartAt_symm_range x (mem_extChartAt_target x)) (isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x)) (mem_range_self _) I.uniqueMDiffOn le_rfl (extChartAt_to_inv x).symm rw [inter_comm] - exact ((contMDiff_snd_tangentBundle_modelSpace E 𝓘(𝕜, E)).contMDiffAt.mdifferentiableAt - one_ne_zero).comp_mdifferentiableWithinAt _ this - -variable (W x) in -omit [CompleteSpace E] in -lemma aux_computation : - (mfderiv I 𝓘(𝕜, E) (extChartAt I x) x).inverse - ((mfderivWithin 𝓘(𝕜, E) I ((extChartAt I x).symm) (range I) ((extChartAt I x) x)).inverse - (W ((extChartAt I x).symm ((extChartAt I x) x)))) - = W x := by - set φ := extChartAt I x - set x' := (extChartAt I x) x - rw [extChartAt_to_inv x] - calc - _ = ((mfderiv I 𝓘(𝕜, E) φ x).inverse.comp - (mfderivWithin 𝓘(𝕜, E) I φ.symm (range I) x').inverse) (W x) := rfl - _ = (ContinuousLinearMap.id 𝕜 _) (W x) := by - congr - rw [← ContinuousLinearMap.IsInvertible.inverse_comp_of_left, - ← ContinuousLinearMap.inverse_id, - mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (mem_extChartAt_source x)] - exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) - _ = W x := by simp - --- does this version suffice for my purposes below? -variable (x V) in -omit [CompleteSpace E] in -lemma aux_computation2' : + exact (contMDiff_snd_tangentBundle_modelSpace E 𝓘(𝕜, E)).contMDiffAt.mdifferentiableAt one_ne_zero + |>.comp_mdifferentiableWithinAt _ this + +lemma mfderiv_extChartAt_inverse_comp_mfderivWithin_extChartAT_symm (Y : TangentSpace I x) : letI φ := extChartAt I x - (mfderivWithin 𝓘(𝕜, E) I φ.symm φ.target (φ x)).inverse (V x) = V x := by + ((mfderiv% φ x).inverse.comp ((mfderiv[range I] φ.symm (φ x)).inverse) Y) = Y := by set φ := extChartAt I x - set x' := (extChartAt I x) x - have : mfderivWithin 𝓘(𝕜, E) I φ.symm φ.target (φ x) = ContinuousLinearMap.id 𝕜 _ := by - rw [mfderivWithin] - have : MDifferentiableWithinAt 𝓘(𝕜, E) I φ.symm φ.target (φ x) := by - have := mdifferentiableWithinAt_extChartAt_symm (I := I) (mem_extChartAt_target x) - exact this.mono (extChartAt_target_subset_range x) - simp only [this, ↓reduceIte, writtenInExtChartAt, extChartAt, OpenPartialHomeomorph.extend, - PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, - OpenPartialHomeomorph.toFun_eq_coe, OpenPartialHomeomorph.refl_partialEquiv, - PartialEquiv.refl_source, OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, - modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, PartialEquiv.refl_symm, - PartialEquiv.refl_coe, CompTriple.comp_eq, preimage_id_eq, id_eq, modelWithCornersSelf_coe, - range_id, inter_univ] - rw [extChartAt_to_inv x, ← extChartAt_coe] - -- debug why this line is needed! - change fderivWithin 𝕜 (↑(extChartAt I x) ∘ ↑φ.symm) (extChartAt I x).target (φ x) = _ - have : fderivWithin 𝕜 (φ ∘ φ.symm) (extChartAt I x).target (φ x) = - fderivWithin 𝕜 id (extChartAt I x).target (φ x) := - fderivWithin_congr' (fun x' hx' ↦ PartialEquiv.right_inv φ hx') (mem_extChartAt_target x) - rw [this] - exact fderivWithin_id (uniqueDiffWithinAt_extChartAt_target x) - rw [this, ContinuousLinearMap.inverse_id] - exact rfl - -variable (x V) in -omit [CompleteSpace E] in -lemma aux_computation2 : + trans (ContinuousLinearMap.id 𝕜 _) Y; swap; · simp + rw [extChartAt_to_inv x, ← ContinuousLinearMap.IsInvertible.inverse_comp_of_left, + ← ContinuousLinearMap.inverse_id, + mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (mem_extChartAt_source x)] + exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) + +variable (x W) in +private lemma mfderiv_extChart_inverse_comp_aux : letI φ := extChartAt I x - (mfderivWithin 𝓘(𝕜, E) I φ.symm (range I) (φ x)).inverse (V x) = V x := by - set φ := extChartAt I x - set x' := (extChartAt I x) x - -- this is almost true: it is true within a smaller set (namely extChartAt I x).target... - have : mfderivWithin 𝓘(𝕜, E) I φ.symm (range I) (φ x) = ContinuousLinearMap.id 𝕜 _ := by - rw [mfderivWithin] - have : MDifferentiableWithinAt 𝓘(𝕜, E) I (↑φ.symm) (range ↑I) (φ x) := - mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) - simp only [this, ↓reduceIte, writtenInExtChartAt, extChartAt, OpenPartialHomeomorph.extend, - PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, - OpenPartialHomeomorph.toFun_eq_coe, OpenPartialHomeomorph.refl_partialEquiv, - PartialEquiv.refl_source, OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, - modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, PartialEquiv.refl_symm, - PartialEquiv.refl_coe, CompTriple.comp_eq, preimage_id_eq, id_eq, modelWithCornersSelf_coe, - range_id, inter_univ] - rw [extChartAt_to_inv x, ← extChartAt_coe] - have : fderivWithin 𝕜 (φ ∘ φ.symm) (range I) (φ x) = fderivWithin 𝕜 id (range I) (φ x) := by - refine fderivWithin_congr' ?_ ?_ - · intro x' hx' - simp only [comp_apply, id_eq] - refine PartialEquiv.right_inv φ ?_ - rw [extChartAt_target] - refine ⟨?_, hx'⟩ - rw [mem_preimage] -- not necessarily true, though... - sorry - · sorry - rw [this] - exact fderivWithin_id <| I.uniqueDiffOn.uniqueDiffWithinAt (mem_range_self _) - rw [this, ContinuousLinearMap.inverse_id] - exact rfl + (mfderiv% φ x).inverse.comp + ((mfderiv[range I] φ.symm (φ x)).inverse) (W (φ.symm (φ x))) = W x := by + rw [mfderiv_extChartAt_inverse_comp_mfderivWithin_extChartAT_symm, extChartAt_to_inv] + +/-- Pulling back through `extChartAt` the scalar multiplication of a vector field by +the derivative of a scalar function equals the scalar multiplication by the manifold derivative. -/ +lemma mpullback_mfderivWithin_apply_smul {f : M → 𝕜} + (hf : MDiffAt[s] f x) : + let V' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) + let W' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm W (range I) + letI s' : Set E := (extChartAt I x).symm ⁻¹' s ∩ range I + mpullback I 𝓘(𝕜, E) (extChartAt I x) + (fun x₀ ↦ (fderivWithin 𝕜 (f ∘ (extChartAt I x).symm) s' x₀) (V' x₀) • W' x₀) x = + (mfderiv[s] f x) (V x) • W x := by + simp only [mpullback, mfderivWithin, hf, map_smul, ← mfderiv_extChart_inverse_comp_aux x W, + mpullbackWithin] + congr 2 + rw [extChartAt_to_inv] + exact mfderivWithin_extChartAt_symm_inverse_apply (v := V x) + +variable [CompleteSpace E] /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. Version within a set. -/ -lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinAt I 𝓘(𝕜) f s x) - (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) +lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDiffAt[s] f x) + (hW : MDiffAt[s] (fun x ↦ (W x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (f • W) s x = (mfderivWithin I 𝓘(𝕜) f s x) (V x) • (W x) + (f x) • mlieBracketWithin I V W s x := by - simp only [mlieBracketWithin] - rw [mpullbackWithin_smul] + simp only [mlieBracketWithin, mpullbackWithin_smul] -- Simplify local notation a bit. set V' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) set W' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm W (range I) set f' := f ∘ (extChartAt I x).symm set s' := (extChartAt I x).symm ⁻¹' s ∩ range I - set x' := (extChartAt I x) x - change mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (lieBracketWithin 𝕜 V' (fun y ↦ f' y • W' y) s') x = - (mfderivWithin I 𝓘(𝕜, 𝕜) f s x) (V x) • W x + - f x • mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (lieBracketWithin 𝕜 V' W' s') x - -- Step 1: rewrite using lieBracketWithin_smul_right - have hf' : DifferentiableWithinAt 𝕜 f' s' x' := by - -- Is this worth a separate lemma? - obtain ⟨_, hf⟩ := mdifferentiableWithinAt_iff.mp hf - rwa [extChartAt_self_eq] at hf - let aux := lieBracketWithin_smul_right (V := V') hf' - hW.differentiableWithinAt_mpullbackWithin_vectorField hs - -- rw [← Pi.smul_def'] - -- We need the cast, since on the nose `B` is a map `E → E`, - -- while we need a map between tangent spaces. + -- We begin by rewriting using `lieBracketWithin_smul_right`. + -- We need the coercion since on the nose `B` is a map `E → E`, + -- whereas we need a map between tangent spaces. let A (x₀) := (fderivWithin 𝕜 f' s' x₀) (V' x₀) • W' x₀ let B (x₀) : TangentSpace 𝓘(𝕜, E) x₀ := f' x₀ • lieBracketWithin 𝕜 V' W' s' x₀ trans mpullback I 𝓘(𝕜, E) ((extChartAt I x)) (fun y ↦ A y + B y) x · simp only [mpullback_apply] congr + exact lieBracketWithin_smul_right (V := V') hf.differentiableWithinAt_comp_extChartAt_symm + hW.differentiableWithinAt_mpullbackWithin_vectorField hs -- We prove the equality of each summand separately. - rw [← Pi.add_def, mpullback_add_apply]; congr; swap + rw [← Pi.add_def, mpullback_add_apply]; congr + · simpa only [A] using mpullback_mfderivWithin_apply_smul hf · simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] - -- This part is still TODO/ in progress!! - unfold A - simp only [mpullback, extChartAt.eq_1, OpenPartialHomeomorph.extend.eq_1, PartialEquiv.coe_trans, - ModelWithCorners.toPartialEquiv_coe, OpenPartialHomeomorph.toFun_eq_coe, comp_apply, extChartAt, - OpenPartialHomeomorph.extend, map_smul, mfderivWithin, hf, ↓reduceIte, writtenInExtChartAt, - OpenPartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, - OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, - PartialEquiv.trans_refl, PartialEquiv.refl_coe, PartialEquiv.coe_trans_symm, - OpenPartialHomeomorph.coe_coe_symm, ModelWithCorners.toPartialEquiv_coe_symm, - CompTriple.comp_eq] - have cleanup1 : I ((chartAt H x) x) = x' := rfl - have cleanup2 : f ∘ (chartAt H x).symm ∘ I.symm = f' := rfl - rw [cleanup1, cleanup2, ← aux_computation x W] - congr -- congr 1 is less strong - -- This statement is not fully true, but I only need a weaker version... - -- if V' x' is a tangent vector within s, i.e. my aux_computation' should suffice! - -- Make this intuition hunch rigorous! - have : V' x' = V x := by - simp only [V', x', mpullbackWithin] - rw [extChartAt_to_inv x] - exact aux_computation2 x V - exact this /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. -/ -lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDifferentiableAt I 𝓘(𝕜) f x) - (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : +lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDiffAt f x) + (hW : MDiffAt (fun x ↦ (W x : TangentBundle I M)) x) : mlieBracket I V (f • W) x = - (mfderiv I 𝓘(𝕜) f x) (V x) • (W x) + (f x) • mlieBracket I V W x := by + (mfderiv% f x) (V x) • (W x) + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hW rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I) @@ -478,8 +396,8 @@ lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDifferentiableAt I 𝓘( Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[f • V, W] = -(df W) • V + f • [V, W]`. Version within a set. -/ -lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDifferentiableWithinAt I 𝓘(𝕜) f s x) - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) +lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDiffAt[s] f x) + (hV : MDiffAt[s] (fun x ↦ (V x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (f • V) W s x = -(mfderivWithin I 𝓘(𝕜) f s x) (W x) • (V x) + (f x) • mlieBracketWithin I V W s x := by @@ -491,47 +409,41 @@ lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDifferentiableWithinAt Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[f • V, W] = -(df W) • V + f • [V, W]`. -/ -lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDifferentiableAt I 𝓘(𝕜) f x) - (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) : +lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDiffAt f x) + (hV : MDiffAt (fun x ↦ (V x : TangentBundle I M)) x) : mlieBracket I (f • V) W x = - -(mfderiv I 𝓘(𝕜) f x) (W x) • (V x) + (f x) • mlieBracket I V W x := by + -(mfderiv% f x) (W x) • (V x) + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hV rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I) set_option backward.isDefEq.respectTransparency false in lemma mlieBracketWithin_const_smul_left - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) - (hs : UniqueMDiffWithinAt I s x) : + (hV : MDiffAt[s] (T% V) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (c • V) W s x = c • mlieBracketWithin I V W s x := by - have aux := mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs - simpa [mfderivWithin_const] using aux + simpa [mfderivWithin_const] using + mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs -lemma mlieBracket_const_smul_left - (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) : +lemma mlieBracket_const_smul_left (hV : MDiffAt (T% V) x) : mlieBracket I (c • V) W x = c • mlieBracket I V W x := by simp only [← mlieBracketWithin_univ] at hV ⊢ exact mlieBracketWithin_const_smul_left hV (uniqueMDiffWithinAt_univ _) set_option backward.isDefEq.respectTransparency false in lemma mlieBracketWithin_const_smul_right - (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) - (hs : UniqueMDiffWithinAt I s x) : + (hW : MDiffAt[s] (T% W) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (c • W) s x = c • mlieBracketWithin I V W s x := by - have aux := mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs - simpa [mfderivWithin_const] using aux + simpa [mfderivWithin_const] using + mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs -lemma mlieBracket_const_smul_right - (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : +lemma mlieBracket_const_smul_right (hW : MDiffAt (T% W) x) : mlieBracket I V (c • W) x = c • mlieBracket I V W x := by simp only [← mlieBracketWithin_univ] at hW ⊢ exact mlieBracketWithin_const_smul_right hW (uniqueMDiffWithinAt_univ _) set_option backward.isDefEq.respectTransparency false in lemma mlieBracketWithin_add_left - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) - (hV₁ : MDifferentiableWithinAt I I.tangent (fun x ↦ (V₁ x : TangentBundle I M)) s x) - (hs : UniqueMDiffWithinAt I s x) : + (hV : MDiffAt[s] (T% V) x) (hV₁ : MDiffAt[s] (T% V₁) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (V + V₁) W s x = mlieBracketWithin I V W s x + mlieBracketWithin I V₁ W s x := by simp only [mlieBracketWithin_apply] @@ -540,67 +452,52 @@ lemma mlieBracketWithin_add_left · exact hV₁.differentiableWithinAt_mpullbackWithin_vectorField · exact uniqueMDiffWithinAt_iff_inter_range.1 hs -lemma mlieBracket_add_left - (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) - (hV₁ : MDifferentiableAt I I.tangent (fun x ↦ (V₁ x : TangentBundle I M)) x) : - mlieBracket I (V + V₁) W x = - mlieBracket I V W x + mlieBracket I V₁ W x := by +lemma mlieBracket_add_left (hV : MDiffAt (T% V) x) (hV₁ : MDiffAt (T% V₁) x) : + mlieBracket I (V + V₁) W x = mlieBracket I V W x + mlieBracket I V₁ W x := by simp only [← mlieBracketWithin_univ] at hV hV₁ ⊢ exact mlieBracketWithin_add_left hV hV₁ (uniqueMDiffWithinAt_univ _) lemma mlieBracketWithin_add_right - (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) - (hW₁ : MDifferentiableWithinAt I I.tangent (fun x ↦ (W₁ x : TangentBundle I M)) s x) - (hs : UniqueMDiffWithinAt I s x) : + (hW : MDiffAt[s] (T% W) x) (hW₁ : MDiffAt[s] (T% W₁) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (W + W₁) s x = mlieBracketWithin I V W s x + mlieBracketWithin I V W₁ s x := by rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_add_left hW hW₁ hs, mlieBracketWithin_swap (V := V), mlieBracketWithin_swap (V := V), Pi.neg_apply, Pi.neg_apply] abel -lemma mlieBracket_add_right - (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) - (hW₁ : MDifferentiableAt I I.tangent (fun x ↦ (W₁ x : TangentBundle I M)) x) : - mlieBracket I V (W + W₁) x = - mlieBracket I V W x + mlieBracket I V W₁ x := by +lemma mlieBracket_add_right (hW : MDiffAt (T% W) x) (hW₁ : MDiffAt (T% W₁) x) : + mlieBracket I V (W + W₁) x = mlieBracket I V W x + mlieBracket I V W₁ x := by simp only [← mlieBracketWithin_univ] at hW hW₁ ⊢ exact mlieBracketWithin_add_right hW hW₁ (uniqueMDiffWithinAt_univ _) -theorem mlieBracketWithin_of_mem_nhdsWithin - (st : t ∈ 𝓝[s] x) (hs : UniqueMDiffWithinAt I s x) - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) t x) - (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) t x) : +theorem mlieBracketWithin_of_mem_nhdsWithin (st : t ∈ 𝓝[s] x) (hs : UniqueMDiffWithinAt I s x) + (hV : MDiffAt[t] (T% V) x) (hW : MDiffAt[t] (T% W) x) : mlieBracketWithin I V W s x = mlieBracketWithin I V W t x := by simp only [mlieBracketWithin_apply] congr 1 rw [lieBracketWithin_of_mem_nhdsWithin] · apply Filter.inter_mem - · apply nhdsWithin_mono _ inter_subset_left - exact (continuousAt_extChartAt_symm x).continuousWithinAt.preimage_mem_nhdsWithin'' - st (by simp) + · apply nhdsWithin_mono _ inter_subset_left <| + (continuousAt_extChartAt_symm x).continuousWithinAt.preimage_mem_nhdsWithin'' st (by simp) · exact nhdsWithin_mono _ inter_subset_right self_mem_nhdsWithin · exact uniqueMDiffWithinAt_iff_inter_range.1 hs · exact hV.differentiableWithinAt_mpullbackWithin_vectorField · exact hW.differentiableWithinAt_mpullbackWithin_vectorField theorem mlieBracketWithin_subset (st : s ⊆ t) (ht : UniqueMDiffWithinAt I s x) - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) t x) - (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) t x) : + (hV : MDiffAt[t] (T% V) x) (hW : MDiffAt[t] (T% W) x) : mlieBracketWithin I V W s x = mlieBracketWithin I V W t x := mlieBracketWithin_of_mem_nhdsWithin (nhdsWithin_mono _ st self_mem_nhdsWithin) ht hV hW theorem mlieBracketWithin_eq_mlieBracket (hs : UniqueMDiffWithinAt I s x) - (hV : MDifferentiableAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) x) - (hW : MDifferentiableAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) x) : + (hV : MDiffAt (T% V) x) (hW : MDiffAt (T% W) x) : mlieBracketWithin I V W s x = mlieBracket I V W x := by simp only [← mlieBracketWithin_univ, ← mdifferentiableWithinAt_univ] at hV hW ⊢ exact mlieBracketWithin_subset (subset_univ _) hs hV hW theorem _root_.DifferentiableWithinAt.mlieBracketWithin_congr_mono - (hV : MDifferentiableWithinAt I I.tangent (fun x ↦ (V x : TangentBundle I M)) s x) - (hVs : EqOn V₁ V t) (hVx : V₁ x = V x) - (hW : MDifferentiableWithinAt I I.tangent (fun x ↦ (W x : TangentBundle I M)) s x) - (hWs : EqOn W₁ W t) (hWx : W₁ x = W x) + (hV : MDiffAt[s] (T% V) x) (hVs : EqOn V₁ V t) (hVx : V₁ x = V x) + (hW : MDiffAt[s] (T% W) x) (hWs : EqOn W₁ W t) (hWx : W₁ x = W x) (hxt : UniqueMDiffWithinAt I t x) (h₁ : t ⊆ s) : mlieBracketWithin I V₁ W₁ t x = mlieBracketWithin I V W s x := by rw [mlieBracketWithin_congr hVs hVx hWs hWx] @@ -618,9 +515,8 @@ diffeomorphisms. Auxiliary version where one assumes that all relevant sets are in chart domains. -/ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} - (hV : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (V x : TangentBundle I' M')) t (f x₀)) - (hW : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (W x : TangentBundle I' M')) t (f x₀)) - (hu : UniqueMDiffOn I s) (hf : ContMDiffOn I I' 2 f s) (hx₀ : x₀ ∈ s) + (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) + (hu : UniqueMDiffOn I s) (hf : CMDiff[s] 2 f) (hx₀ : x₀ ∈ s) (ht : t ⊆ (extChartAt I' (f x₀)).source) (hst : MapsTo f s t) (hsymm : IsSymmSndFDerivWithinAt 𝕜 ((extChartAt I' (f x₀)) ∘ f ∘ (extChartAt I x₀).symm) ((extChartAt I x₀).symm ⁻¹' s ∩ range I) (extChartAt I x₀ x₀)) : @@ -628,7 +524,7 @@ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] mlieBracketWithin I (mpullbackWithin I I' f V s) (mpullbackWithin I I' f W s) s x₀ := by have A : (extChartAt I x₀).symm (extChartAt I x₀ x₀) = x₀ := by simp have A' : x₀ = (extChartAt I x₀).symm (extChartAt I x₀ x₀) := by simp - have h'f : MDifferentiableWithinAt I I' f s x₀ := (hf x₀ hx₀).mdifferentiableWithinAt two_ne_zero + have h'f : MDiffAt[s] f x₀ := (hf x₀ hx₀).mdifferentiableWithinAt two_ne_zero simp only [mlieBracketWithin_apply, mpullbackWithin_apply] -- first, rewrite the pullback of the Lie bracket as a pullback in `E` under the map -- `F = extChartAt I' (f x₀) ∘ f ∘ (extChartAt I x₀).symm` of a Lie bracket computed in `E'`, @@ -638,8 +534,8 @@ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] rw [← mfderiv_comp_mfderivWithin _ (mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source (f x₀))) h'f (hu x₀ hx₀)] rw [eq_comm, (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x₀)).inverse_apply_eq] - have : (mfderivWithin 𝓘(𝕜, E) I (extChartAt I x₀).symm (range I) (extChartAt I x₀ x₀)).inverse = - mfderiv I 𝓘(𝕜, E) (extChartAt I x₀) x₀ := by + have : (mfderiv[range I] (extChartAt I x₀).symm (extChartAt I x₀ x₀)).inverse = + mfderiv% (extChartAt I x₀) x₀ := by apply ContinuousLinearMap.inverse_eq · convert mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt (I := I) (x := x₀) (y := extChartAt I x₀ x₀) (by simp) @@ -647,9 +543,8 @@ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] (y := extChartAt I x₀ x₀) (by simp) rw [← this, ← ContinuousLinearMap.IsInvertible.inverse_comp_apply_of_right]; swap · exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x₀) - have : mfderivWithin 𝓘(𝕜, E) I (extChartAt I x₀).symm (range I) (extChartAt I x₀ x₀) = - mfderivWithin 𝓘(𝕜, E) I (extChartAt I x₀).symm ((extChartAt I x₀).symm ⁻¹' s ∩ range I) - (extChartAt I x₀ x₀) := + have : mfderiv[range I] (extChartAt I x₀).symm (extChartAt I x₀ x₀) = + mfderiv[(extChartAt I x₀).symm ⁻¹' s ∩ range I] (extChartAt I x₀).symm (extChartAt I x₀ x₀) := (MDifferentiableWithinAt.mfderivWithin_mono (mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x₀)) (UniqueDiffWithinAt.uniqueMDiffWithinAt (hu x₀ hx₀)) inter_subset_right).symm @@ -705,9 +600,9 @@ private lemma mpullbackWithin_mlieBracketWithin_aux [CompleteSpace E'] = (extChartAt I' (f x₀)).symm ((extChartAt I' (f x₀)) (f ((extChartAt I x₀).symm y))) := (PartialEquiv.left_inv (extChartAt I' (f x₀)) h'y).symm congr 2 - have : (mfderivWithin 𝓘(𝕜, E') I' ((extChartAt I' (f x₀)).symm) (range I') + have : (mfderiv[range I'] ((extChartAt I' (f x₀)).symm) (extChartAt I' (f x₀) (f ((extChartAt I x₀).symm y)))) ∘L - (mfderiv I' 𝓘(𝕜, E') (↑(extChartAt I' (f x₀))) (f ((extChartAt I x₀).symm y))) = + (mfderiv% (extChartAt I' (f x₀)) (f ((extChartAt I x₀).symm y))) = ContinuousLinearMap.id _ _ := by convert mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt ((PartialEquiv.map_source _ h'y)) @@ -754,16 +649,15 @@ set_option backward.isDefEq.respectTransparency false in diffeomorphisms. -/ lemma mpullbackWithin_mlieBracketWithin_of_isSymmSndFDerivWithinAt {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} - (hV : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (V x : TangentBundle I' M')) t (f x₀)) - (hW : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (W x : TangentBundle I' M')) t (f x₀)) - (hu : UniqueMDiffOn I s) (hf : ContMDiffWithinAt I I' 2 f s x₀) (hx₀ : x₀ ∈ s) + (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) + (hu : UniqueMDiffOn I s) (hf : CMDiffAt[s] 2 f x₀) (hx₀ : x₀ ∈ s) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (hsymm : IsSymmSndFDerivWithinAt 𝕜 ((extChartAt I' (f x₀)) ∘ f ∘ (extChartAt I x₀).symm) ((extChartAt I x₀).symm ⁻¹' s ∩ range I) (extChartAt I x₀ x₀)) : mpullbackWithin I I' f (mlieBracketWithin I' V W t) s x₀ = mlieBracketWithin I (mpullbackWithin I I' f V s) (mpullbackWithin I I' f W s) s x₀ := by have A : (extChartAt I x₀).symm (extChartAt I x₀ x₀) = x₀ := by simp - by_cases hfi : (mfderivWithin I I' f s x₀).IsInvertible; swap + by_cases hfi : (mfderiv[s] f x₀).IsInvertible; swap · simp only [mlieBracketWithin_apply, mpullbackWithin_apply, ContinuousLinearMap.inverse_of_not_isInvertible hfi, ContinuousLinearMap.zero_apply] rw [lieBracketWithin_eq_zero_of_eq_zero] @@ -782,9 +676,8 @@ lemma mpullbackWithin_mlieBracketWithin_of_isSymmSndFDerivWithinAt -- choose a small open set `v` around `x₀` where `f` is `C^2` obtain ⟨u, u_open, x₀u, ut, maps_u, u_smooth⟩ : ∃ u, IsOpen u ∧ x₀ ∈ u ∧ s ∩ u ⊆ f ⁻¹' t ∧ - s ∩ u ⊆ f ⁻¹' (extChartAt I' (f x₀)).source ∧ ContMDiffOn I I' 2 f (s ∩ u) := by - obtain ⟨u, u_open, x₀u, hu⟩ : - ∃ u, IsOpen u ∧ x₀ ∈ u ∧ ContMDiffOn I I' 2 f (insert x₀ s ∩ u) := + s ∩ u ⊆ f ⁻¹' (extChartAt I' (f x₀)).source ∧ CMDiff[s ∩ u] 2 f := by + obtain ⟨u, u_open, x₀u, hu⟩ : ∃ u, IsOpen u ∧ x₀ ∈ u ∧ CMDiff[insert x₀ s ∩ u] 2 f := hf.contMDiffOn' le_rfl (by simp) have : f ⁻¹' (extChartAt I' (f x₀)).source ∈ 𝓝[s] x₀ := hf.continuousWithinAt.preimage_mem_nhdsWithin (extChartAt_source_mem_nhds (f x₀)) @@ -845,10 +738,9 @@ condition `x₀ ∈ closure (interior u)`, needed to guarantee the symmetry of t becomes easier to check.) -/ lemma mpullbackWithin_mlieBracketWithin' {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s u : Set M} {t : Set M'} - (hV : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (V x : TangentBundle I' M')) t (f x₀)) - (hW : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (W x : TangentBundle I' M')) t (f x₀)) + (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) (hs : UniqueMDiffOn I s) (hu : UniqueMDiffOn I u) - (hf : ContMDiffWithinAt I I' n f u x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) + (hf : CMDiffAt[u] n f x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (h'x₀ : x₀ ∈ closure (interior u)) (hsu : s ⊆ u) : mpullbackWithin I I' f (mlieBracketWithin I' V W t) s x₀ = mlieBracketWithin I (mpullbackWithin I I' f V s) (mpullbackWithin I I' f W s) s x₀ := by @@ -882,21 +774,20 @@ lemma mpullbackWithin_mlieBracketWithin' /-- The pullback commutes with the Lie bracket of vector fields on manifolds. -/ lemma mpullbackWithin_mlieBracketWithin {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} - (hV : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (V x : TangentBundle I' M')) t (f x₀)) - (hW : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (W x : TangentBundle I' M')) t (f x₀)) - (hu : UniqueMDiffOn I s) (hf : ContMDiffWithinAt I I' n f s x₀) (hx₀ : x₀ ∈ s) + (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) + (hu : UniqueMDiffOn I s) (hf : CMDiffAt[s] n f x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) (h'x₀ : x₀ ∈ closure (interior s)) : mpullbackWithin I I' f (mlieBracketWithin I' V W t) s x₀ = mlieBracketWithin I (mpullbackWithin I I' f V s) (mpullbackWithin I I' f W s) s x₀ := mpullbackWithin_mlieBracketWithin' hV hW hu hu hf hx₀ hn hst h'x₀ Subset.rfl +set_option backward.isDefEq.respectTransparency false in /-- The pullback commutes with the Lie bracket of vector fields on manifolds. -/ lemma mpullback_mlieBracketWithin {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} - (hV : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (V x : TangentBundle I' M')) t (f x₀)) - (hW : MDifferentiableWithinAt I' I'.tangent (fun x ↦ (W x : TangentBundle I' M')) t (f x₀)) - (hu : UniqueMDiffOn I s) (hf : ContMDiffAt I I' n f x₀) (hx₀ : x₀ ∈ s) + (hV : MDiffAt[t] (T% V) (f x₀)) (hW : MDiffAt[t] (T% W) (f x₀)) + (hu : UniqueMDiffOn I s) (hf : CMDiffAt n f x₀) (hx₀ : x₀ ∈ s) (hn : minSmoothness 𝕜 2 ≤ n) (hst : f ⁻¹' t ∈ 𝓝[s] x₀) : mpullback I I' f (mlieBracketWithin I' V W t) x₀ = mlieBracketWithin I (mpullback I I' f V) (mpullback I I' f W) s x₀ := by @@ -926,9 +817,8 @@ lemma mpullback_mlieBracketWithin lemma mpullback_mlieBracket {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} - (hV : MDifferentiableAt I' I'.tangent (fun x ↦ (V x : TangentBundle I' M')) (f x₀)) - (hW : MDifferentiableAt I' I'.tangent (fun x ↦ (W x : TangentBundle I' M')) (f x₀)) - (hf : ContMDiffAt I I' n f x₀) (hn : minSmoothness 𝕜 2 ≤ n) : + (hV : MDiffAt (T% V) (f x₀)) (hW : MDiffAt (T% W) (f x₀)) + (hf : CMDiffAt n f x₀) (hn : minSmoothness 𝕜 2 ≤ n) : mpullback I I' f (mlieBracket I' V W) x₀ = mlieBracket I (mpullback I I' f V) (mpullback I I' f W) x₀ := by simp only [← mlieBracketWithin_univ, ← mdifferentiableWithinAt_univ] at hV hW ⊢ @@ -938,11 +828,9 @@ lemma mpullback_mlieBracket protected lemma _root_.ContMDiffWithinAt.mlieBracketWithin_vectorField [IsManifold I (n + 1) M] {m : WithTop ℕ∞} {U V : Π (x : M), TangentSpace I x} {s : Set M} {x : M} - (hU : ContMDiffWithinAt I I.tangent n (fun x ↦ (U x : TangentBundle I M)) s x) - (hV : ContMDiffWithinAt I I.tangent n (fun x ↦ (V x : TangentBundle I M)) s x) + (hU : CMDiffAt[s] n (T% U) x) (hV : CMDiffAt[s] n (T% V) x) (hs : UniqueMDiffOn I s) (hx : x ∈ s) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : - ContMDiffWithinAt I I.tangent m - (fun x ↦ (mlieBracketWithin I U V s x : TangentBundle I M)) s x := by + CMDiffAt[s] m (T% (mlieBracketWithin I U V s)) x := by /- The statement is not obvious, since at different points the Lie bracket is defined using different charts. However, since we know that the Lie bracket is invariant under diffeos, we can use a single chart to prove the statement. Let `U'` and `V'` denote the pullbacks of `U` and `V` @@ -973,14 +861,14 @@ protected lemma _root_.ContMDiffWithinAt.mlieBracketWithin_vectorField (contMDiffWithinAt_vectorSpace_iff_contDiffWithinAt.1 (contMDiffWithinAt_mpullbackWithin_extChartAt_symm hV hs hx le_rfl)) (hs.uniqueDiffOn_target_inter x) hm'n (by simp [hx]) - have B : ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent m' (fun y ↦ (mlieBracketWithin 𝓘(𝕜, E) U' V' - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x x) := by + have B : CMDiffAt[((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s)] m' + (T% (mlieBracketWithin 𝓘(𝕜, E) U' V' ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s))) + (extChartAt I x x) := by rw [← mlieBracketWithin_eq_lieBracketWithin] at A exact contMDiffWithinAt_vectorSpace_iff_contDiffWithinAt.2 A - have C : ContMDiffWithinAt I I.tangent m' (fun y ↦ (mpullback I 𝓘(𝕜, E) (extChartAt I x) + have C : CMDiffAt[s] m' (T% ((mpullback I 𝓘(𝕜, E) (extChartAt I x) ((mlieBracketWithin 𝓘(𝕜, E) U' V' - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s))) y : TangentBundle I M)) s x := + ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s)))))) x := ContMDiffWithinAt.mpullback_vectorField_of_mem_nhdsWithin_of_eq B (n := m' + 1) contMDiffAt_extChartAt (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x)) le_rfl pre_mem rfl @@ -1003,29 +891,25 @@ protected lemma _root_.ContMDiffWithinAt.mlieBracketWithin_vectorField /-- If two vector fields are `C^n` with `n ≥ m + 1`, then their Lie bracket is `C^m`. -/ lemma _root_.ContMDiffAt.mlieBracket_vectorField {m n : ℕ∞} [IsManifold I (n + 1) M] {U V : Π (x : M), TangentSpace I x} {x : M} - (hU : ContMDiffAt I I.tangent n (fun x ↦ (U x : TangentBundle I M)) x) - (hV : ContMDiffAt I I.tangent n (fun x ↦ (V x : TangentBundle I M)) x) + (hU : CMDiffAt n (T% U) x) (hV : CMDiffAt n (T% V) x) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : - ContMDiffAt I I.tangent m (fun x ↦ (mlieBracket I U V x : TangentBundle I M)) x := by + CMDiffAt m (T% (mlieBracket I U V)) x := by simp only [← contMDiffWithinAt_univ, ← mlieBracketWithin_univ] at hU hV ⊢ exact hU.mlieBracketWithin_vectorField hV uniqueMDiffOn_univ (mem_univ _) hmn /-- If two vector fields are `C^n` with `n ≥ m + 1`, then their Lie bracket is `C^m`. -/ lemma _root_.ContMDiffOn.mlieBracketWithin_vectorField {m n : ℕ∞} [IsManifold I (n + 1) M] {U V : Π (x : M), TangentSpace I x} - (hU : ContMDiffOn I I.tangent n (fun x ↦ (U x : TangentBundle I M)) s) - (hV : ContMDiffOn I I.tangent n (fun x ↦ (V x : TangentBundle I M)) s) + (hU : CMDiff[s] n (T% U)) (hV : CMDiff[s] n (T% V)) (hs : UniqueMDiffOn I s) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : - ContMDiffOn I I.tangent m (fun x ↦ (mlieBracketWithin I U V s x : TangentBundle I M)) s := + CMDiff[s] m (T% (mlieBracketWithin I U V s)) := fun x hx ↦ (hU x hx).mlieBracketWithin_vectorField (hV x hx) hs hx hmn /-- If two vector fields are `C^n` with `n ≥ m + 1`, then their Lie bracket is `C^m`. -/ lemma _root_.ContDiff.mlieBracket_vectorField {m n : ℕ∞} [IsManifold I (n + 1) M] {U V : Π (x : M), TangentSpace I x} - (hU : ContMDiff I I.tangent n (fun x ↦ (U x : TangentBundle I M))) - (hV : ContMDiff I I.tangent n (fun x ↦ (V x : TangentBundle I M))) - (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : - ContMDiff I I.tangent m (fun x ↦ (mlieBracket I U V x : TangentBundle I M)) := by + (hU : CMDiff n (T% U)) (hV : CMDiff n (T% V)) (hmn : minSmoothness 𝕜 (m + 1) ≤ n) : + CMDiff m (T% (mlieBracket I U V)) := by simp only [← contMDiffOn_univ] at hU hV ⊢ exact hU.mlieBracketWithin_vectorField hV uniqueMDiffOn_univ hmn @@ -1035,17 +919,15 @@ section Leibniz variable [IsManifold I (minSmoothness 𝕜 3) M] [CompleteSpace E] +set_option backward.isDefEq.respectTransparency false in /-- The Lie bracket of vector fields in manifolds satisfies the Leibniz identity `[U, [V, W]] = [[U, V], W] + [V, [U, W]]` (also called Jacobi identity). -/ theorem leibniz_identity_mlieBracketWithin_apply {U V W : Π (x : M), TangentSpace I x} {s : Set M} {x : M} (hs : UniqueMDiffOn I s) (h's : x ∈ closure (interior s)) (hx : x ∈ s) - (hU : ContMDiffWithinAt I I.tangent (minSmoothness 𝕜 2) - (fun x ↦ (U x : TangentBundle I M)) s x) - (hV : ContMDiffWithinAt I I.tangent (minSmoothness 𝕜 2) - (fun x ↦ (V x : TangentBundle I M)) s x) - (hW : ContMDiffWithinAt I I.tangent (minSmoothness 𝕜 2) - (fun x ↦ (W x : TangentBundle I M)) s x) : + (hU : CMDiffAt[s] (minSmoothness 𝕜 2) (T% U) x) + (hV : CMDiffAt[s] (minSmoothness 𝕜 2) (T% V) x) + (hW : CMDiffAt[s] (minSmoothness 𝕜 2) (T% W) x) : mlieBracketWithin I U (mlieBracketWithin I V W s) s x = mlieBracketWithin I (mlieBracketWithin I U V s) W s x + mlieBracketWithin I V (mlieBracketWithin I U W s) s x := by @@ -1065,29 +947,23 @@ theorem leibniz_identity_mlieBracketWithin_apply let V' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) let W' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm W (range I) -- register basic facts on the pullbacks in the vector space - have J0U : ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent (minSmoothness 𝕜 2) - (fun y ↦ (U' y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x x) := + have J0U : CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] (minSmoothness 𝕜 2) + (T% U') (extChartAt I x x) := contMDiffWithinAt_mpullbackWithin_extChartAt_symm hU hs hx A - have J0V : ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent (minSmoothness 𝕜 2) - (fun y ↦ (V' y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x x) := + have J0V : CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] (minSmoothness 𝕜 2) + (T% V') (extChartAt I x x) := contMDiffWithinAt_mpullbackWithin_extChartAt_symm hV hs hx A - have J0W : ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent (minSmoothness 𝕜 2) - (fun y ↦ (W' y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x x) := + have J0W : CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] (minSmoothness 𝕜 2) + (T% W') (extChartAt I x x) := contMDiffWithinAt_mpullbackWithin_extChartAt_symm hW hs hx A - have J1U : ∀ᶠ y in 𝓝[s] x, ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent (minSmoothness 𝕜 2) - (fun y ↦ (U' y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x y) := + have J1U : ∀ᶠ y in 𝓝[s] x, CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] + (minSmoothness 𝕜 2) (T% U') (extChartAt I x y) := eventually_contMDiffWithinAt_mpullbackWithin_extChartAt_symm hU hs hx A (by simp) - have J1V : ∀ᶠ y in 𝓝[s] x, ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent (minSmoothness 𝕜 2) - (fun y ↦ (V' y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x y) := + have J1V : ∀ᶠ y in 𝓝[s] x, CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] + (minSmoothness 𝕜 2) (T% V') (extChartAt I x y) := eventually_contMDiffWithinAt_mpullbackWithin_extChartAt_symm hV hs hx A (by simp) - have J1W : ∀ᶠ y in 𝓝[s] x, ContMDiffWithinAt 𝓘(𝕜, E) 𝓘(𝕜, E).tangent (minSmoothness 𝕜 2) - (fun y ↦ (W' y : TangentBundle 𝓘(𝕜, E) E)) - ((extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s) (extChartAt I x y) := + have J1W : ∀ᶠ y in 𝓝[s] x, CMDiffAt[(extChartAt I x).target ∩ (extChartAt I x).symm ⁻¹' s] + (minSmoothness 𝕜 2) (T% W') (extChartAt I x y) := eventually_contMDiffWithinAt_mpullbackWithin_extChartAt_symm hW hs hx A (by simp) have JU : U =ᶠ[𝓝[s] x] mpullback I 𝓘(𝕜, E) (extChartAt I x) U' := eventuallyEq_mpullback_mpullbackWithin_extChartAt U @@ -1175,9 +1051,9 @@ theorem leibniz_identity_mlieBracketWithin_apply `[U, [V, W]] = [[U, V], W] + [V, [U, W]]` (also called Jacobi identity). -/ lemma leibniz_identity_mlieBracket_apply {U V W : Π (x : M), TangentSpace I x} {x : M} - (hU : ContMDiffAt I I.tangent (minSmoothness 𝕜 2) (fun x ↦ (U x : TangentBundle I M)) x) - (hV : ContMDiffAt I I.tangent (minSmoothness 𝕜 2) (fun x ↦ (V x : TangentBundle I M)) x) - (hW : ContMDiffAt I I.tangent (minSmoothness 𝕜 2) (fun x ↦ (W x : TangentBundle I M)) x) : + (hU : CMDiffAt (minSmoothness 𝕜 2) (T% U) x) + (hV : CMDiffAt (minSmoothness 𝕜 2) (T% V) x) + (hW : CMDiffAt (minSmoothness 𝕜 2) (T% W) x) : mlieBracket I U (mlieBracket I V W) x = mlieBracket I (mlieBracket I U V) W x + mlieBracket I V (mlieBracket I U W) x := by simp only [← mlieBracketWithin_univ, ← contMDiffWithinAt_univ] at hU hV hW ⊢ @@ -1187,9 +1063,9 @@ lemma leibniz_identity_mlieBracket_apply `[U, [V, W]] = [[U, V], W] + [V, [U, W]]` (also called Jacobi identity). -/ lemma leibniz_identity_mlieBracket {U V W : Π (x : M), TangentSpace I x} - (hU : ContMDiff I I.tangent (minSmoothness 𝕜 2) (fun x ↦ (U x : TangentBundle I M))) - (hV : ContMDiff I I.tangent (minSmoothness 𝕜 2) (fun x ↦ (V x : TangentBundle I M))) - (hW : ContMDiff I I.tangent (minSmoothness 𝕜 2) (fun x ↦ (W x : TangentBundle I M))) : + (hU : CMDiff (minSmoothness 𝕜 2) (T% U)) + (hV : CMDiff (minSmoothness 𝕜 2) (T% V)) + (hW : CMDiff (minSmoothness 𝕜 2) (T% W)) : mlieBracket I U (mlieBracket I V W) = mlieBracket I (mlieBracket I U V) W + mlieBracket I V (mlieBracket I U W) := by ext x From e6b9a651dcb11b4a480ce9f1e2e1347b3c37299b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 16:56:49 +0000 Subject: [PATCH 437/601] Fix one torsion sorry; some clean-up One lemma seems to yield a contradiction (but is true). Very strange! --- .../CovariantDerivative/Torsion.lean | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 719f2173c26a08..dd3b701fa37618 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -61,40 +61,46 @@ variable [IsManifold I ∞ M] {U : Set M} (hf : IsCovariantDerivativeOn E cov U) variable (Y) in lemma torsion_add_left_apply [CompleteSpace E] - (hf : IsCovariantDerivativeOn E cov U) (hx : x ∈ U) - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : + (hcov : IsCovariantDerivativeOn E cov U) + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by - simp [torsion]--, hf.addX (x := x) (hx := sorry) hX hX'] - -- rw [hf.addσ Y hX hX', VectorField.mlieBracket_add_left hX hX'] - sorry -- module + simp [torsion, hcov.addσ hX hX', VectorField.mlieBracket_add_left hX hX'] + module -lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E cov U) (hx : x ∈ U) +lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) - (hX' : MDiffAt (T% X') x) : + (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by rw [torsion_antisymm, Pi.neg_apply, - hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] + hf.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] simp; abel variable (Y) in lemma torsion_smul_left_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} - (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) - -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below - {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : - torsion F (f • X) Y x = f x • torsion F X Y x := by + (hcov : IsCovariantDerivativeOn E cov U) + {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : + torsion cov (f • X) Y x = f x • torsion cov X Y x := by + simp only [torsion] + rw [hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] + simp? [bar, smul_sub] says + simp only [bar, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, + ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.coe_mk, + LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk, Function.comp_apply, + ContinuousLinearMap.toSpanSingleton_apply, Pi.smul_apply', map_smul, neg_smul, smul_sub] + set A := f x • (cov X x) (Y x) + set B := f x • (cov Y x) (X x) + set C := f x • VectorField.mlieBracket I X Y x sorry /-simp only [torsion, Pi.sub_apply, hF.smulX (X := X) (σ := Y) (f := f)] rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] simp [bar, smul_sub] abel -/ -variable (X) in lemma torsion_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} - (hF : IsCovariantDerivativeOn E F U) (hx : x ∈ U) - {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : + (hF : IsCovariantDerivativeOn E F U) + {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) (hx : x ∈ U := by trivial) : torsion F X (f • Y) x = f x • torsion F X Y x := by - rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] + rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hf hX, torsion_antisymm X] simp end IsCovariantDerivativeOn From 37981cd5f8f51c3b0080e393520240f028528e18 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 16:57:00 +0000 Subject: [PATCH 438/601] Make a partially applied torsion 1-tensor --- .../VectorBundle/CovariantDerivative/Torsion.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index dd3b701fa37618..6f28e3d4279960 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -105,6 +105,15 @@ lemma torsion_smul_right_apply [CompleteSpace E] end IsCovariantDerivativeOn +variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] + +noncomputable def torsionTensorRight (hcov : IsCovariantDerivativeOn E cov univ) + (X : (x : M) → TangentSpace I x) : + TangentSpace I x →L[ℝ] TangentSpace I x := + mkTensor I E E (Bundle.torsion cov X) + (fun _x _f _Y hf hY ↦ hcov.torsion_smul_right_apply hf hY) + (fun _x _f _σ hf hσ ↦ hcov.torsion_add_right_apply hf hσ) .. + /-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ noncomputable def IsTorsionFreeOn (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) From 20ad0646ef24a5a80979a32aeaf6f79a81da3000 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 17:00:30 +0000 Subject: [PATCH 439/601] Minor polish --- .../CovariantDerivative/Torsion.lean | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 6f28e3d4279960..a7947363f1c89c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -57,27 +57,24 @@ lemma torsion_antisymm : torsion cov X Y = - torsion cov Y X := by namespace IsCovariantDerivativeOn -variable [IsManifold I ∞ M] {U : Set M} (hf : IsCovariantDerivativeOn E cov U) +variable [IsManifold I ∞ M] {U : Set M} variable (Y) in -lemma torsion_add_left_apply [CompleteSpace E] - (hcov : IsCovariantDerivativeOn E cov U) +lemma torsion_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by simp [torsion, hcov.addσ hX hX', VectorField.mlieBracket_add_left hX hX'] module -lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E cov U) - (hX : MDiffAt (T% X) x) - (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : +lemma torsion_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by rw [torsion_antisymm, Pi.neg_apply, - hf.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] + hcov.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] simp; abel variable (Y) in -lemma torsion_smul_left_apply [CompleteSpace E] - (hcov : IsCovariantDerivativeOn E cov U) +lemma torsion_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : torsion cov (f • X) Y x = f x • torsion cov X Y x := by simp only [torsion] @@ -105,6 +102,8 @@ lemma torsion_smul_right_apply [CompleteSpace E] end IsCovariantDerivativeOn +section + variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] noncomputable def torsionTensorRight (hcov : IsCovariantDerivativeOn E cov univ) @@ -114,6 +113,8 @@ noncomputable def torsionTensorRight (hcov : IsCovariantDerivativeOn E cov univ) (fun _x _f _Y hf hY ↦ hcov.torsion_smul_right_apply hf hY) (fun _x _f _σ hf hσ ↦ hcov.torsion_add_right_apply hf hσ) .. +end + /-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ noncomputable def IsTorsionFreeOn (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) @@ -180,7 +181,7 @@ lemma torsion_add_left [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by ext x - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (hX x) (hX' x) lemma torsion_add_right [CompleteSpace E] (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : @@ -191,13 +192,13 @@ variable (Y) in lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : torsion cov (f • X) Y = f • torsion cov X Y := by ext x - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (hf x) (hX x) variable (X) in lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : torsion cov X (f • Y) = f • torsion cov X Y := by ext x - exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) (hf x) (hY x) + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply (hf x) (hY x) /-- The torsion of a covariant derivative is tensorial: the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ @@ -210,13 +211,13 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' · intro f σ τ hf hσ - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) hf hσ + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ hf hσ · intro σ σ' τ hσ hσ' - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) hσ hσ' + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ hσ hσ' · intros f σ σ' hf hσ' - exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) hf hσ' + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply hf hσ' · intro σ τ τ' hτ hτ' - exact cov.isCovariantDerivativeOn.torsion_add_right_apply (by trivial) hτ hτ' + exact cov.isCovariantDerivativeOn.torsion_add_right_apply hτ hτ' -- TODO: define a torsion tensor of a covariant derivative, -- and related torsion-freeness to this @@ -286,7 +287,7 @@ lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] congr with i have hsi : MDiffAt (hs.coeff i Y) x := sorry have hsi' : MDiffAt (T% (s i)) x := sorry - have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.coeff i) Y) hx hsi hsi' + have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.coeff i) Y) hsi hsi' rw [← this] congr From 43dd3960105ced1b2f41eb2c14147e6aa1a1d38b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 17:11:04 +0000 Subject: [PATCH 440/601] Torsion as a 2-tensor --- .../VectorBundle/CovariantDerivative/Torsion.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index a7947363f1c89c..f7fc8d88e073d8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -113,6 +113,15 @@ noncomputable def torsionTensorRight (hcov : IsCovariantDerivativeOn E cov univ) (fun _x _f _Y hf hY ↦ hcov.torsion_smul_right_apply hf hY) (fun _x _f _σ hf hσ ↦ hcov.torsion_add_right_apply hf hσ) .. +noncomputable def torsionTensor (hcov : IsCovariantDerivativeOn E cov univ) : + TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := + mk2TensorAt I E E (Bundle.torsion cov) + (fun {f σ τ} hf hσ ↦ hcov.torsion_smul_left_apply τ hf hσ) + (fun {f σ τ} hf hσ ↦ hcov.torsion_add_left_apply τ hf hσ) + (fun {f σ τ} hf hτ ↦ hcov.torsion_smul_right_apply hf hτ) + (fun {f σ τ} hσ hτ ↦ hcov.torsion_add_right_apply hσ hτ) + + end /-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ From 6082ae32a1892c7566056e898c443a1a25b52672 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 17:20:41 +0000 Subject: [PATCH 441/601] start new approach to levi-civita --- .../CovariantDerivative/LeviCivita.lean | 201 ++++++------------ 1 file changed, 69 insertions(+), 132 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 18af8b7b543046..29cec09c1b924b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -5,6 +5,7 @@ Authors: Patrick Massot, Michael Rothgang -/ module +public import Mathlib.Analysis.InnerProductSpace.Dual public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame public import Mathlib.Geometry.Manifold.VectorBundle.Tangent @@ -637,6 +638,12 @@ lemma leviCivitaRhs_smulZ [CompleteSpace E] {f : M → ℝ} simp only [leviCivitaRhs] rw [smul_comm, leviCivitaRhs'_smulZ I hf hX hY hZ] +lemma leviCivitaRhs_smulZ_apply [CompleteSpace E] {f : M → ℝ} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X Y (f • Z) x = f x * leviCivitaRhs I X Y Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_smulZ_apply I hf hX hY hZ] + ring + end leviCivitaRhs variable (X Y Z) in @@ -734,142 +741,72 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] · exact hcov.eq_leviCivitaRhs I X σ Z · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm -/-- Auxiliary definition towards defining the Levi-Civita connection on `M`: -given a trivialisation `e` and a choice `o` of linear order on the standard basis of `E`, -we take the expression defined by the Koszul formula (using the orthonormal frame determined by `e` -and `o`). -/ -noncomputable def lcCandidateAux' [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] - (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : - ((x : M) → TangentSpace I x) → ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x := - open scoped Classical in - fun X Y x ↦ - if hE : Subsingleton E then X x else - -- Choose a trivialisation of `TM` near `x`. - -- Since `E` is non-trivial, `b` is non-empty. - let b := Basis.ofVectorSpace ℝ E - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - letI frame := b.orthonormalFrame e - -- The coefficient of the desired tangent vector `∇ X Y x` w.r.t. `s i` - -- is given by `leviCivitaRhs X Y (s i)`. - ∑ i, ((leviCivitaRhs I X Y (frame i)) x) • (frame i x) - -noncomputable def lcCandidateAux [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] - (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) - (Y : (x : M) → TangentSpace I x) (x : M) : +open Classical in +noncomputable def lcCandidateAux₀ [FiniteDimensional ℝ E] + {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : + TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] ℝ := + mk2TensorAt I E ℝ (fun (X Z : Π x : M, TangentSpace I x) ↦ + if hX : MDiffAt (T% X) x then if hZ : MDiffAt (T% Z) x then + leviCivitaRhs I X Y Z + else 0 else 0) (x := x) + (fun {f X Z} hf hX ↦ by + dsimp + rw [if_pos hX, if_pos] + · split_ifs with hZ + · exact leviCivitaRhs_smulX_apply hf hX hY hZ + · simp + · exact hf.smul_section hX) + (fun {X₁ X₂ Z} hX₁ hX₂ ↦ by + dsimp + rw [if_pos hX₁, if_pos hX₂, if_pos] + · split_ifs with hZ + · exact leviCivitaRhs_addX_apply I hX₁ hX₂ hY hZ + · simp + · exact mdifferentiableAt_add_section hX₁ hX₂) + (fun {f X Z} hf hZ ↦ by + dsimp + rw [if_pos hZ] + nth_rw 2 [if_pos] + · split_ifs with hX + · exact leviCivitaRhs_smulZ_apply I hf hX hY hZ + · simp + · exact hf.smul_section hZ) + (fun {X Z₁ Z₂} hZ₁ hZ₂ ↦ by + dsimp + rw [if_pos hZ₁, if_pos hZ₂] + nth_rw 2 [if_pos] + · split_ifs with hX + · exact leviCivitaRhs_addZ_apply I hX hY hZ₁ hZ₂ + · simp + · exact mdifferentiableAt_add_section hZ₁ hZ₂) + +noncomputable def lcCandidateAux₁ [FiniteDimensional ℝ E] + {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x := + -- use the musical isomorphism to produce a candidate ∇ Y as a (1,1)-tensor + -- (rather than a 2-tensor) have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) - LinearMap.toContinuousLinearMap <| - { toFun X₀ := lcCandidateAux' I e o Y (_root_.extend I E X₀) x - map_add' X₀ Y₀ := by - sorry - -- simp only [lcCandidateAux', hE, ↓reduceDIte] - -- simp only [← Finset.sum_add_distrib, ← add_smul] - -- congr; ext i - -- rw [leviCivitaRhs_addX_apply] <;> try assumption - -- let b := Basis.ofVectorSpace ℝ E - -- have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - -- exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx - map_smul' a X₀ := by - sorry - -- simp only [lcCandidateAux', hE, ↓reduceDIte] - -- rw [Finset.smul_sum] - -- congr; ext i - -- rw [leviCivitaRhs_smulX_apply] <;> try assumption - -- · simp [← smul_assoc] - -- · let b := Basis.ofVectorSpace ℝ E - -- have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - -- exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx } - } - -variable (M) in --- TODO: make g part of the notation! -/-- Given two vector fields X and Y on TM, compute -the candidate definition for the Levi-Civita connection on `TM`. -/ -noncomputable def lcCandidate [FiniteDimensional ℝ E] - (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : - (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x) := - -- Use the preferred trivialisation at `x` to write down a candidate for the existence. - fun X x ↦ lcCandidateAux I (trivializationAt E (TangentSpace I : M → Type _) x) o X x - -variable (X Y) in -/-- The definition `lcCandidate` behaves well: for each compatible trivialisation `e`, -the candidate definition using `e` agrees with `lcCandidate` on `e.baseSet`. -/ -lemma lcCandidate_eq_lcCandidateAux [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] - {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} {x : M} (hx : x ∈ e.baseSet) : - lcCandidate I M o X x = lcCandidateAux I e o X x := by - by_cases hE : Subsingleton E - · simp [lcCandidate, lcCandidateAux, hE] - · simp only [lcCandidate, lcCandidateAux, hE, ↓reduceDIte] - -- Now, start the real proof. - sorry + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ + (InnerProductSpace.toDual ℝ _).symm.toContinuousLinearEquiv.toContinuousLinearMap ∘L + (lcCandidateAux₀ I x hY) -lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ E] - (hE : ¬(Subsingleton E)) [Nontrivial E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] - {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : - IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet where - addσ {σ σ' x} hσ hσ' hx := by - simp only [lcCandidateAux, hE, ↓reduceDIte] - simp only [← Finset.sum_add_distrib, ← add_smul] - congr; ext i - rw [leviCivitaRhs_addY_apply] <;> try assumption - let b := Basis.ofVectorSpace ℝ E - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx - leibniz {σ g x} hσ hg hx := by - simp only [lcCandidateAux, hE, ↓reduceDIte] - let b := Basis.ofVectorSpace ℝ E - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - let Z (i : (Basis.ofVectorSpaceIndex ℝ E)) := ((Basis.ofVectorSpace ℝ E).orthonormalFrame e i) - have hZ : IsOrthonormalFrameOn I E 1 Z e.baseSet := - (Basis.ofVectorSpace ℝ E).orthonormalFrame_isOrthonormalFrameOn e - have hZ' : ∑ i, ⟪σ, Z i⟫ x • Z i x = σ x := by - calc _ - _ = ∑ i, hZ.coeff i σ x • Z i x := by - congr; ext i - rw [hZ.coeff_eq_inner' σ hx i, product_swap] - _ = σ x := (hZ.toIsLocalFrameOn.coeff_sum_eq _ hx).symm - trans ∑ i, leviCivitaRhs I X (g • σ) (Z i) x • (Z i) x - · congr - have (i : (Basis.ofVectorSpaceIndex ℝ E)) : MDiffAt (T% (Z i)) x := - mdifferentiableAt_orthonormalFrame_of_mem _ _ i hx - have aux (i) := leviCivitaRhs_smulY_apply I hg hX hσ (this i) - simp_rw [aux] - trans ∑ i, (g x • leviCivitaRhs I X σ (Z i) x • Z i x) - + ∑ i, ((bar (g x)) ((mfderiv I 𝓘(ℝ, ℝ) g x) (X x)) • ⟪σ, Z i⟫ x) • Z i x - · simp only [← Finset.sum_add_distrib, add_smul, smul_assoc] - dsimp - have : ∑ i, g x • leviCivitaRhs I X σ (Z i) x • Z i x = (g • lcCandidateAux I e o X σ) x := by - simp only [lcCandidateAux, hE, ↓reduceDIte, Pi.smul_apply', Finset.smul_sum] - congr - rw [this] - simp_rw [← hZ', smul_assoc, Finset.smul_sum] +open Classical in +noncomputable def lcCandidateAux [FiniteDimensional ℝ E] + (Y : Π x : M, TangentSpace I x) (x : M) : + TangentSpace I x →L[ℝ] TangentSpace I x := + if hY : MDiffAt (T% Y) x then lcCandidateAux₁ I x hY else 0 + +lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : + IsCovariantDerivativeOn E (lcCandidateAux I (M := M)) where + addσ {Y Y'} x hY hY' _ := by + unfold lcCandidateAux + rw [dif_pos hY, dif_pos hY', dif_pos (mdifferentiableAt_add_section hY hY')] + unfold lcCandidateAux₁ dsimp - -/-- The candidate definition `lcCandidateAux` is a covariant derivative -on each local trivialisation's domain. -/ -lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] - {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : - IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet := by - by_cases hE : Subsingleton E - · exact (IsCovariantDerivativeOn.of_subsingleton E _).mono (Set.subset_univ _) - · have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - exact isCovariantDerivativeOn_lcCandidateAux_of_nonempty I hE e - --- The candidate definition is a covariant derivative on each local frame's domain. -lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional ℝ E] - (e : Trivialization E (TotalSpace.proj : TangentBundle I M → M)) [MemTrivializationAtlas e] - {o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)} : - IsCovariantDerivativeOn E (lcCandidate I M o) e.baseSet := by - apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidateAux I e (o := o)) - intro X σ x hx - exact (lcCandidate_eq_lcCandidateAux I X σ e hx).symm + rw [← ContinuousLinearMap.comp_add] + congr! 1 + sorry + leibniz := sorry end From 00b1995a5805c02461bc8cdf02170ab563141fb3 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 17:46:28 +0000 Subject: [PATCH 442/601] addition theorem for tensor construction --- .../CovariantDerivative/Prelim.lean | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 1a300d58e16024..37c13cac3a391b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -526,6 +526,36 @@ noncomputable def mk2TensorAt · exact mdifferentiable_extend .. } H.toContinuousLinearMap +theorem mk2TensorAt_add + (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} + (φ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (φ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (φ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (φ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) + (ψ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + ψ (f • σ) τ x = f x • ψ σ τ x) + (ψ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) + (ψ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + ψ σ (f • τ) x = f x • ψ σ τ x) + (ψ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : + mk2TensorAt I F F' (φ + ψ) + (fun {_ _ τ} hf hσ ↦ + (congr($(φ_σ_smul hf hσ (τ := τ)) + $(ψ_σ_smul hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) + sorry + (fun {_ σ _} hf hτ ↦ + (congr($(φ_τ_smul hf hτ (σ := σ)) + $(ψ_τ_smul hf hτ (σ := σ)))).trans (smul_add _ _ _).symm) + sorry + = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add + + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by + sorry + end tensoriality section trivilization_topology From c7c2212334c68f7d771e6447c285419fc062c429 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 18:00:26 +0000 Subject: [PATCH 443/601] finish proof of addition lemma --- .../VectorBundle/CovariantDerivative/Prelim.lean | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 37c13cac3a391b..5b64b937901e57 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -548,13 +548,20 @@ theorem mk2TensorAt_add mk2TensorAt I F F' (φ + ψ) (fun {_ _ τ} hf hσ ↦ (congr($(φ_σ_smul hf hσ (τ := τ)) + $(ψ_σ_smul hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) - sorry + (fun {σ₁ σ₂} τ hσ₁ hσ₂ ↦ + (congr($(φ_σ_add hσ₁ hσ₂ (τ := τ)) + $(ψ_σ_add hσ₁ hσ₂ (τ := τ)))).trans <| by + dsimp + abel) (fun {_ σ _} hf hτ ↦ (congr($(φ_τ_smul hf hτ (σ := σ)) + $(ψ_τ_smul hf hτ (σ := σ)))).trans (smul_add _ _ _).symm) - sorry + (fun σ {τ₁ τ₂} hτ₁ hτ₂ ↦ + (congr($(φ_τ_add hτ₁ hτ₂ (σ := σ)) + $(ψ_τ_add hτ₁ hτ₂ (σ := σ)))).trans <| by + dsimp + abel) = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by - sorry + ext + simp [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap] end tensoriality From a84d21fbb93b041302227a4ed8ad5433b3fa8a66 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 3 Mar 2026 18:01:06 +0000 Subject: [PATCH 444/601] Progress towards LC being a connection --- .../CovariantDerivative/LeviCivita.lean | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 29cec09c1b924b..0e681231bfa628 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -798,13 +798,25 @@ noncomputable def lcCandidateAux [FiniteDimensional ℝ E] lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : IsCovariantDerivativeOn E (lcCandidateAux I (M := M)) where - addσ {Y Y'} x hY hY' _ := by + addσ {Y Y'} x hY hY' _hx := by unfold lcCandidateAux rw [dif_pos hY, dif_pos hY', dif_pos (mdifferentiableAt_add_section hY hY')] unfold lcCandidateAux₁ dsimp rw [← ContinuousLinearMap.comp_add] congr! 1 + simp only [lcCandidateAux₀] + rw [← mk2TensorAt_add] + congr 1 + ext1 X --Z --_x + ext1 Z + by_cases hX : MDiffAt (T% X) x; swap + · simp [hX] + by_cases hZ : MDiffAt (T% Z) x; swap + · simp [hZ] + simp only [hX, hZ, ↓reduceDIte, dite_eq_ite, Pi.add_apply] + simp only [↓reduceIte] + refine leviCivitaRhs_addY_apply I ?_ ?_ ?_ ?_ sorry leibniz := sorry From 410bb87b139f2dd10b16d186d00ab2af1a61ef97 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 21:06:30 +0000 Subject: [PATCH 445/601] construct difference of connections using tensoriality constructor --- .../CovariantDerivative/Basic.lean | 95 +++---------------- .../CovariantDerivative/Prelim.lean | 13 +++ 2 files changed, 24 insertions(+), 84 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 5eb115d55f1e93..5ae43a2f0af339 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -525,84 +525,9 @@ noncomputable def differenceAux (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x) := fun σ ↦ cov σ - cov' σ -@[simp] -lemma differenceAux_apply - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) - (σ : Π x : M, V x) : - differenceAux cov cov' σ = cov σ - cov' σ := rfl - -lemma differenceAux_smul_eq [IsManifold I 1 M] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) - (hcov' : IsCovariantDerivativeOn F cov' u) - (σ : Π x : M, V x) (f : M → ℝ) - {x : M} (hx : x ∈ u := by trivial) - (hσ : MDiffAt (T% σ) x) - (hf : MDiffAt f x) : - differenceAux cov cov' ((f : M → ℝ) • σ) x = f x • differenceAux cov cov' σ x := by - simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf] - module - -/-- The value of `differenceAux cov cov' σ` at `x₀` depends only on `σ x₀`. -/ -lemma differenceAux_tensorial - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] - {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) - (hcov' : IsCovariantDerivativeOn F cov' u) - [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {σ σ' : Π x : M, V x} {x₀ : M} - (hσ : MDiffAt (T% σ) x₀) - (hσ' : MDiffAt (T% σ') x₀) - (hσσ' : σ x₀ = σ' x₀) (hx : x₀ ∈ u := by trivial) : - differenceAux cov cov' σ x₀ = differenceAux cov cov' σ' x₀ := by - apply tensoriality_criterion (I := I) F V (E →L[ℝ] F) - (fun x ↦ TangentSpace I x →L[ℝ] V x) hσ hσ' hσσ' - · intro f σ hf hσ - rw [hcov.differenceAux_smul_eq hcov' σ f hx hσ hf] - · intro σ σ' hσ hσ' - unfold differenceAux - simp only [Pi.sub_apply] - rw [hcov.addσ, hcov'.addσ] <;> try assumption - abel - -lemma isLinearMap_differenceAux - [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] - [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - {s : Set M} {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {x : M} - (hcov : IsCovariantDerivativeOn F cov s) - (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) : - IsLinearMap ℝ (fun (σ₀ : V x) ↦ - differenceAux cov cov' (extend I F σ₀) x) where - map_add u v := by - simp only [differenceAux, extend_add, Pi.sub_apply] - rw [hcov.addσ, hcov'.addσ]; · abel - all_goals apply mdifferentiable_extend - map_smul a u := by - simp only [differenceAux, extend_smul, Pi.sub_apply] - rw [hcov.smul_const_σ, hcov'.smul_const_σ]; · module - all_goals apply mdifferentiable_extend - --- TODO this should be unnecessary, kept for now to minimize refactor -lemma isBilinearMap_differenceAux - [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] - [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - {s : Set M} {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} {x : M} - (hcov : IsCovariantDerivativeOn F cov s) - (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x ∈ s := by trivial) : - IsBilinearMap ℝ (fun (σ₀ : V x) ↦ - differenceAux cov cov' (extend I F σ₀) x) where - add_left u v := by rw [(isLinearMap_differenceAux hcov hcov').map_add]; simp - add_right u v w := by rw [map_add] - smul_left u v := by rw [(isLinearMap_differenceAux hcov hcov').map_smul]; simp - smul_right a u := by simp [map_smul] - variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] +open Classical in /-- The difference of two covariant derivatives, as a tensorial map -/ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] @@ -612,12 +537,14 @@ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Spac (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) (x : M) : V x →L[ℝ] TangentSpace I x →L[ℝ] V x := - -- TODO give a construction which doesn't pass through `IsBilinearMap`, only `IsLinearMap` - haveI : FiniteDimensional ℝ (TangentSpace I x) := by assumption - open Classical in - if hx : x ∈ s then (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap - else 0 - + if hxs : x ∈ s then + mkTensorAt I F (E →L[ℝ] F) (differenceAux cov cov') x + (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) + (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.addσ hσ hσ', hcov'.addσ hσ hσ']; abel) + else + 0 + +-- do we need this? lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] @@ -644,8 +571,8 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by simp only [difference, hx, reduceDIte] - exact hcov.differenceAux_tensorial hcov' - (mdifferentiable_extend ..) hσ (extend_apply_self _) hx + rw [mkTensorAt_apply _ _ _ _ hσ] + rfl -- The classification of real connections over a trivial bundle section classification diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 5b64b937901e57..27a6df4ec10c7e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -435,6 +435,19 @@ noncomputable def mkTensorAt · exact mdifferentiable_const .. · exact mdifferentiable_extend .. } +variable {I} in +theorem mkTensorAt_apply + -- `φ` explicit to make it easier to generate the side conditions at point of use + {φ : (Π x : M, V x) → (Π x, V' x)} {x} + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') x = φ σ x + φ σ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : + mkTensorAt I F F' φ x φ_smul φ_add (σ x) = φ σ x := by + apply tensoriality_criterion I F _ F' _ _ hσ _ φ_smul φ_add + · exact mdifferentiable_extend .. + · simp + noncomputable def mkTensor -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x, V' x)) From 876ce4ff934e570f0b9d067d373473ca616738f7 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Tue, 3 Mar 2026 22:47:29 +0000 Subject: [PATCH 446/601] tensor apply lemmas --- .../CovariantDerivative/LeviCivita.lean | 24 ++++++++++++++ .../CovariantDerivative/Prelim.lean | 20 ++++++++++++ .../CovariantDerivative/Torsion.lean | 32 ++++++++++--------- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0e681231bfa628..438e7bbc2962e8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -780,6 +780,14 @@ noncomputable def lcCandidateAux₀ [FiniteDimensional ℝ E] · simp · exact mdifferentiableAt_add_section hZ₁ hZ₂) +theorem lcCandidateAux₀_apply [FiniteDimensional ℝ E] {x : M} + {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + lcCandidateAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by + unfold lcCandidateAux₀ + rw [mk2TensorAt_apply _ _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] + noncomputable def lcCandidateAux₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x := @@ -790,12 +798,28 @@ noncomputable def lcCandidateAux₁ [FiniteDimensional ℝ E] (InnerProductSpace.toDual ℝ _).symm.toContinuousLinearEquiv.toContinuousLinearMap ∘L (lcCandidateAux₀ I x hY) +theorem lcCandidateAux₁_apply [FiniteDimensional ℝ E] {x : M} + {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + inner ℝ (lcCandidateAux₁ I x hY (X x)) (Z x) = leviCivitaRhs I X Y Z x := by + simpa [lcCandidateAux₁] using lcCandidateAux₀_apply I hX hY hZ + open Classical in noncomputable def lcCandidateAux [FiniteDimensional ℝ E] (Y : Π x : M, TangentSpace I x) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x := if hY : MDiffAt (T% Y) x then lcCandidateAux₁ I x hY else 0 +theorem lcCandidateAux_apply [FiniteDimensional ℝ E] {x : M} + {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + inner ℝ (lcCandidateAux I Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := by + unfold lcCandidateAux + rw [dif_pos hY] + simpa [lcCandidateAux] using lcCandidateAux₁_apply I hX hY hZ + lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : IsCovariantDerivativeOn E (lcCandidateAux I (M := M)) where addσ {Y Y'} x hY hY' _hx := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 27a6df4ec10c7e..25a0054377e808 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -539,6 +539,26 @@ noncomputable def mk2TensorAt · exact mdifferentiable_extend .. } H.toContinuousLinearMap +variable {I} in +theorem mk2TensorAt_apply + -- `φ` explicit to make it easier to generate the side conditions at point of use + {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : + mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by + apply tensoriality_criterion₂ I F _ F' _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · simp + theorem mk2TensorAt_add (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} (φ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index f7fc8d88e073d8..3f47ebb86128ae 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -106,21 +106,24 @@ section variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] -noncomputable def torsionTensorRight (hcov : IsCovariantDerivativeOn E cov univ) - (X : (x : M) → TangentSpace I x) : - TangentSpace I x →L[ℝ] TangentSpace I x := - mkTensor I E E (Bundle.torsion cov X) - (fun _x _f _Y hf hY ↦ hcov.torsion_smul_right_apply hf hY) - (fun _x _f _σ hf hσ ↦ hcov.torsion_add_right_apply hf hσ) .. - -noncomputable def torsionTensor (hcov : IsCovariantDerivativeOn E cov univ) : +noncomputable def torsionTensor (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := mk2TensorAt I E E (Bundle.torsion cov) - (fun {f σ τ} hf hσ ↦ hcov.torsion_smul_left_apply τ hf hσ) - (fun {f σ τ} hf hσ ↦ hcov.torsion_add_left_apply τ hf hσ) - (fun {f σ τ} hf hτ ↦ hcov.torsion_smul_right_apply hf hτ) - (fun {f σ τ} hσ hτ ↦ hcov.torsion_add_right_apply hσ hτ) - + (fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ) + (fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ) + (hcov.torsion_smul_right_apply) + (hcov.torsion_add_right_apply) + +theorem torsionTensor_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} + {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : + torsionTensor hcov x (X x) (Y x) = Bundle.torsion cov X Y x := by + rw [torsionTensor] + refine mk2TensorAt_apply _ _ ?_ ?_ ?_ ?_ hX hY + · exact fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ + · exact fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ + · exact hcov.torsion_smul_right_apply + · exact hcov.torsion_add_right_apply end @@ -228,8 +231,7 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] · intro σ τ τ' hτ hτ' exact cov.isCovariantDerivativeOn.torsion_add_right_apply hτ hτ' --- TODO: define a torsion tensor of a covariant derivative, --- and related torsion-freeness to this +-- TODO: relate torsion-freeness to torsion tensor -- (That will not work for torsion-freeness on a set, though.) -- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, From f195851a473a6d2b3bee05ea03757117c097596b Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:29:12 +0000 Subject: [PATCH 447/601] hacky proofs --- .../CovariantDerivative/LeviCivita.lean | 66 +++++++++++++++---- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 438e7bbc2962e8..b45bb7c1ff3b36 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -822,7 +822,7 @@ theorem lcCandidateAux_apply [FiniteDimensional ℝ E] {x : M} lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : IsCovariantDerivativeOn E (lcCandidateAux I (M := M)) where - addσ {Y Y'} x hY hY' _hx := by + addσ {Y Y'} x hY hY' _ := by unfold lcCandidateAux rw [dif_pos hY, dif_pos hY', dif_pos (mdifferentiableAt_add_section hY hY')] unfold lcCandidateAux₁ @@ -830,19 +830,57 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : rw [← ContinuousLinearMap.comp_add] congr! 1 simp only [lcCandidateAux₀] - rw [← mk2TensorAt_add] - congr 1 - ext1 X --Z --_x - ext1 Z - by_cases hX : MDiffAt (T% X) x; swap - · simp [hX] - by_cases hZ : MDiffAt (T% Z) x; swap - · simp [hZ] - simp only [hX, hZ, ↓reduceDIte, dite_eq_ite, Pi.add_apply] - simp only [↓reduceIte] - refine leviCivitaRhs_addY_apply I ?_ ?_ ?_ ?_ - sorry - leibniz := sorry + ext X₀ Y₀ + simp only [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap, + dite_eq_ite, LinearMap.coe_toContinuousLinearMap', IsLinearMap.mk'_apply, LinearMap.mk₂_apply, + ContinuousLinearMap.add_apply] + rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] + · apply leviCivitaRhs_addY_apply + · exact mdifferentiable_extend .. + · exact hY + · exact hY' + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + leibniz {Y f x} hY hf _ := by + unfold lcCandidateAux + dsimp + rw [dif_pos hY, dif_pos] + · unfold lcCandidateAux₁ + dsimp + rw [← ContinuousLinearMap.comp_smul] + have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ + set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) + ext X₀ + apply Φ.injective + simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, + LinearIsometryEquiv.coe_symm_toContinuousLinearEquiv, comp_apply, + LinearIsometryEquiv.apply_symm_apply, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, + ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, + ContinuousLinearMap.toSpanSingleton_apply, map_add, map_smul] + ext Z₀ + simp only [lcCandidateAux₀, mk2TensorAt, IsBilinearMap.toContinuousLinearMap, + IsBilinearMap.toLinearMap, dite_eq_ite, LinearMap.coe_toContinuousLinearMap', + IsLinearMap.mk'_apply, LinearMap.mk₂_apply, ContinuousLinearMap.add_apply, + ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] + rw [if_pos, if_pos, if_pos, if_pos] + · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend I E X₀) (Y := Y) + (Z := _root_.extend I E Z₀) (x := x) (f := f) + convert key hf ?_ hY ?_ + · simp + · simp [Φ, product] + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + exact MDifferentiableAt.smul_section hf hY end From 12255d04e0eb0fcf6ebfac398386da85c86f405f Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:33:41 +0000 Subject: [PATCH 448/601] make this the definition of levi-civita connection --- .../CovariantDerivative/LeviCivita.lean | 74 ++++++++----------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index b45bb7c1ff3b36..aad4193eed53ee 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -742,7 +742,7 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm open Classical in -noncomputable def lcCandidateAux₀ [FiniteDimensional ℝ E] +noncomputable def lcAux₀ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] ℝ := mk2TensorAt I E ℝ (fun (X Z : Π x : M, TangentSpace I x) ↦ @@ -780,15 +780,15 @@ noncomputable def lcCandidateAux₀ [FiniteDimensional ℝ E] · simp · exact mdifferentiableAt_add_section hZ₁ hZ₂) -theorem lcCandidateAux₀_apply [FiniteDimensional ℝ E] {x : M} +theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : - lcCandidateAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by - unfold lcCandidateAux₀ + lcAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by + unfold lcAux₀ rw [mk2TensorAt_apply _ _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] -noncomputable def lcCandidateAux₁ [FiniteDimensional ℝ E] +noncomputable def lcAux₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x := -- use the musical isomorphism to produce a candidate ∇ Y as a (1,1)-tensor @@ -796,40 +796,40 @@ noncomputable def lcCandidateAux₁ [FiniteDimensional ℝ E] have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ (InnerProductSpace.toDual ℝ _).symm.toContinuousLinearEquiv.toContinuousLinearMap ∘L - (lcCandidateAux₀ I x hY) + (lcAux₀ I x hY) -theorem lcCandidateAux₁_apply [FiniteDimensional ℝ E] {x : M} +theorem lcAux₁_apply [FiniteDimensional ℝ E] {x : M} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : - inner ℝ (lcCandidateAux₁ I x hY (X x)) (Z x) = leviCivitaRhs I X Y Z x := by - simpa [lcCandidateAux₁] using lcCandidateAux₀_apply I hX hY hZ + inner ℝ (lcAux₁ I x hY (X x)) (Z x) = leviCivitaRhs I X Y Z x := by + simpa [lcAux₁] using lcAux₀_apply I hX hY hZ open Classical in -noncomputable def lcCandidateAux [FiniteDimensional ℝ E] +noncomputable def lcAux [FiniteDimensional ℝ E] (Y : Π x : M, TangentSpace I x) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x := - if hY : MDiffAt (T% Y) x then lcCandidateAux₁ I x hY else 0 + if hY : MDiffAt (T% Y) x then lcAux₁ I x hY else 0 -theorem lcCandidateAux_apply [FiniteDimensional ℝ E] {x : M} +theorem lcAux_apply [FiniteDimensional ℝ E] {x : M} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : - inner ℝ (lcCandidateAux I Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := by - unfold lcCandidateAux + inner ℝ (lcAux I Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := by + unfold lcAux rw [dif_pos hY] - simpa [lcCandidateAux] using lcCandidateAux₁_apply I hX hY hZ + simpa [lcAux] using lcAux₁_apply I hX hY hZ -lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : - IsCovariantDerivativeOn E (lcCandidateAux I (M := M)) where +lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : + IsCovariantDerivativeOn E (lcAux I (M := M)) where addσ {Y Y'} x hY hY' _ := by - unfold lcCandidateAux + unfold lcAux rw [dif_pos hY, dif_pos hY', dif_pos (mdifferentiableAt_add_section hY hY')] - unfold lcCandidateAux₁ + unfold lcAux₁ dsimp rw [← ContinuousLinearMap.comp_add] congr! 1 - simp only [lcCandidateAux₀] + simp only [lcAux₀] ext X₀ Y₀ simp only [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap, dite_eq_ite, LinearMap.coe_toContinuousLinearMap', IsLinearMap.mk'_apply, LinearMap.mk₂_apply, @@ -847,10 +847,10 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. leibniz {Y f x} hY hf _ := by - unfold lcCandidateAux + unfold lcAux dsimp rw [dif_pos hY, dif_pos] - · unfold lcCandidateAux₁ + · unfold lcAux₁ dsimp rw [← ContinuousLinearMap.comp_smul] have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) @@ -864,7 +864,7 @@ lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional ℝ E] : ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.toSpanSingleton_apply, map_add, map_smul] ext Z₀ - simp only [lcCandidateAux₀, mk2TensorAt, IsBilinearMap.toContinuousLinearMap, + simp only [lcAux₀, mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap, dite_eq_ite, LinearMap.coe_toContinuousLinearMap', IsLinearMap.mk'_apply, LinearMap.mk₂_apply, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] @@ -886,31 +886,17 @@ end variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -variable (M) in -/-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: -this is unique up to the value on non-differentiable vector fields. -If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ -@[no_expose] noncomputable def LeviCivitaConnection_aux [FiniteDimensional ℝ E] - (o : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E)) : - CovariantDerivative I E (TangentSpace I : M → Type _) where - -- This is the existence part of the proof: take the formula derived above - -- and prove it satisfies all the conditions. - toFun := lcCandidate I M o - isCovariantDerivativeOn := by - rw [← iUnion_source_chartAt H M] - let t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x - apply IsCovariantDerivativeOn.iUnion (s := fun i ↦ (t i).baseSet) fun i ↦ ?_ - exact isCovariantDerivativeOn_lcCandidate I _ - -- TODO: make g part of the notation! variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: this is unique up to the value on non-differentiable vector fields. If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : - CovariantDerivative I E (TangentSpace I : M → Type _) := - LeviCivitaConnection_aux I M (Classical.choose (exists_wellOrder _)) + CovariantDerivative I E (TangentSpace I : M → Type _) where + toFun := lcAux I + isCovariantDerivativeOn := isCovariantDerivativeOn_lcAux I +#exit -- TODO: move this section to `Torsion.lean` section @@ -1089,7 +1075,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x intro x'' hx'' i j k simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate - simp only [lcCandidateAux, hE, ↓reduceDIte] + simp only [lcAux, hE, ↓reduceDIte] letI t := trivializationAt E (TangentSpace I) x; letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t @@ -1113,7 +1099,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x simp only [LeviCivitaConnection, LeviCivitaConnection_aux] unfold lcCandidate rw [product_apply, product_apply] - simp only [lcCandidateAux, hE, ↓reduceDIte] + simp only [lcAux, hE, ↓reduceDIte] -- Choose a linear order on ι: which one really does not matter for our result. have : LinearOrder ι := by choose r wo using exists_wellOrder _ @@ -1181,7 +1167,7 @@ lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaCon refine ⟨?_, ?_⟩ · intro X Y Z x unfold LeviCivitaConnection LeviCivitaConnection_aux lcCandidate - simp only [lcCandidateAux, hE, ↓reduceDIte] + simp only [lcAux, hE, ↓reduceDIte] --simp [product_apply] sorry -- compatible · let s : M → Set M := fun x ↦ (trivializationAt E (fun (x : M) ↦ TangentSpace I x) x).baseSet From bee9d66ddde95d422aadc1e542cd48f443fbcbb6 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:44:59 +0000 Subject: [PATCH 449/601] bit of cleanup --- .../CovariantDerivative/LeviCivita.lean | 62 +++++++------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index aad4193eed53ee..dfb31d164582b9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -7,8 +7,6 @@ module public import Mathlib.Analysis.InnerProductSpace.Dual public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion -public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame -public import Mathlib.Geometry.Manifold.VectorBundle.Tangent public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian public import Mathlib.Util.PrintSorries @@ -534,7 +532,6 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} · simp only [bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul]; rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] rw [h1, h2, product_swap I Y Z] - set A := rhs_aux I X Y Z x set B := rhs_aux I Y Z X x set C := rhs_aux I Z X Y x @@ -652,7 +649,8 @@ lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = trans ⟪∇ X, Y, Z⟫ + ⟪Y, ∇ X, Z⟫ · ext x exact h.1 X Y Z x - · simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] + · sorry + -- simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] lemma isolate_aux {α : Type*} [AddCommGroup α] (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : @@ -688,43 +686,21 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : section -attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder - -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] - variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ -- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! lemma congr_of_forall_product [FiniteDimensional ℝ E] (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by - obtain (_hE | hE) := subsingleton_or_nontrivial E - · ext x - have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - apply Subsingleton.allEq _ - ext x - let b := Basis.ofVectorSpace ℝ E - let t := trivializationAt E (TangentSpace I : M → Type _) x - have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - have : Nonempty ↑(Basis.ofVectorSpaceIndex ℝ E) := b.index_nonempty - -- The linear ordering on the indexing set of `b` is only used in this proof, - -- so our choice does not matter. - have : LinearOrder ↑(Basis.ofVectorSpaceIndex ℝ E) := by - choose r wo using exists_wellOrder _ - exact r - have : LocallyFiniteOrderBot ↑(Basis.ofVectorSpaceIndex ℝ E) := inferInstance - -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g - let real := b.orthonormalFrame t - have hframe := b.orthonormalFrame_isOrthonormalFrameOn t (F := E) (IB := I) (n := 1) - rw [hframe.eq_iff_coeff hx] - intro i - have h₁ : ⟪X, real i⟫ x = (hframe.coeff i) X x := by - rw [hframe.coeff_eq_inner' _ hx] - simp [real, real_inner_comm] - have h₂ : ⟪X', real i⟫ x = (hframe.coeff i) X' x := by - rw [hframe.coeff_eq_inner' _ hx] - simp [real, real_inner_comm] - rw [← h₁, ← h₂, h (real i)] + ext1 x + have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ + set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) + apply Φ.injective + ext Z₀ + simpa [Φ, product] using congr($(h (_root_.extend I E Z₀)) x) + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ @@ -736,10 +712,11 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] cov = cov' := by ext X σ x apply congrFun - apply congr_of_forall_product fun Z ↦ ?_ - trans leviCivitaRhs I X σ Z - · exact hcov.eq_leviCivitaRhs I X σ Z - · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm + sorry + -- apply congr_of_forall_product fun Z ↦ ?_ + -- trans leviCivitaRhs I X σ Z + -- · exact hcov.eq_leviCivitaRhs I X σ Z + -- · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] @@ -896,6 +873,13 @@ noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : toFun := lcAux I isCovariantDerivativeOn := isCovariantDerivativeOn_lcAux I +theorem leviCivitaConnection_apply [FiniteDimensional ℝ E] {x : M} + {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + inner ℝ (LeviCivitaConnection I M Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := + lcAux_apply _ hX hY hZ + #exit -- TODO: move this section to `Torsion.lean` section From 4dd83df5c801f70b25b44d031d8c8ac09cc391fb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 11:05:29 +0000 Subject: [PATCH 450/601] First round of fixes --- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 2 + .../Geometry/Manifold/PartitionOfUnity.lean | 2 +- .../Geometry/Manifold/VectorBundle/Misc.lean | 1 + .../VectorBundle/OrthonormalFrame.lean | 19 ++++----- .../Manifold/VectorBundle/Tensoriality.lean | 40 ++++++++++--------- .../Manifold/VectorField/LieBracket.lean | 13 +++--- 6 files changed, 43 insertions(+), 34 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index 39ad73ccb15588..0545512b2ba8a7 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -403,6 +403,7 @@ lemma mfderiv_extChartAt_self : ext v simpa using (tangentBundleCore I M).coordChange_self (achart H x) x (mem_chart_source H x) v +set_option backward.isDefEq.respectTransparency false in -- TODO: should there be a version for `extChartAt`? /-- The manifold derivative within `range I` of `(extChartAt I x).symm` at the chart point is the identity. -/ @@ -414,6 +415,7 @@ lemma mfderivWithin_range_extChartAt_symm : rw [mfderiv_extChartAt_self, ContinuousLinearMap.comp_id] at hcomp simpa using hcomp +set_option backward.isDefEq.respectTransparency false in /-- The inverse of the derivative of `(extChartAt I x).symm` at the chart point, applied to a tangent vector, gives back the tangent vector. -/ lemma mfderivWithin_extChartAt_symm_inverse_apply (v : TangentSpace I x) : diff --git a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean index dacf8ed23d4180..f1b3169950633e 100644 --- a/Mathlib/Geometry/Manifold/PartitionOfUnity.lean +++ b/Mathlib/Geometry/Manifold/PartitionOfUnity.lean @@ -623,7 +623,7 @@ theorem exists_contMDiffSection_forall_mem_convex_of_local -- Prove that `s`, when viewed as a map to the total space, is smooth. have (j : M) : ContMDiff I (I.prod 𝓘(ℝ, F_fiber)) n (fun x ↦ TotalSpace.mk' F_fiber x ((ρ j x) • (s_loc j x))) := by - refine .smul_section_of_tsupport ?_ isOpen_interior (hρU j) + refine ContMDiffOn.smul_section_of_tsupport ?_ isOpen_interior (hρU j) ((s_smooth j).mono interior_subset) exact ((ρ j).contMDiff).of_le (sup_eq_left.mp rfl) |>.contMDiffOn have hs : ContMDiff I (I.prod 𝓘(ℝ, F_fiber)) n (fun x ↦ TotalSpace.mk' F_fiber x (s x)) := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean index c0b812eee40f77..f751f402d1a17a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -99,6 +99,7 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiberBundle F V] [VectorBundle 𝕜 F V] -- `V` vector bundle +set_option backward.isDefEq.respectTransparency false in def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where toFun v := v invFun v := v diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 6f84fe2a8b6278..c40c1046cd0331 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -114,7 +114,7 @@ omit [VectorBundle ℝ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in variable (t) in lemma coeff_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : ι) : - hs.coeff i t x = ⟪s i x, t x⟫ := by + hs.coeff i x (t x) = ⟪s i x, t x⟫ := by let b := VectorBundle.gramSchmidtOrthonormalBasis (hs.linearIndependent hx) (hs.generating hx) have beq (i : ι) : b i = s i x := by simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] @@ -133,13 +133,13 @@ lemma coeff_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x ∈ u) (i : /-- If `t` is `C^k` at `x`, so is its coefficient `hs.coeff i t` in a local frame s near `x` -/ lemma contMDiffWithinAt_coeff (ht : CMDiffAt[u] n (T% t) x) (hx : x ∈ u) (i : ι) : - CMDiffAt[u] n (hs.coeff i t) x := + CMDiffAt[u] n (LinearMap.piApply (hs.coeff i) t) x := ((hs.contMDiffOn i x hx).inner_bundle ht).congr_of_mem (fun _ hy ↦ hs.coeff_eq_inner' _ hy _) hx omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] in /-- If `t` is `C^k` at `x`, so is its coefficient `hs.coeff i t` in a local frame s near `x` -/ lemma contMDiffAt_coeff (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) : - CMDiffAt n (hs.coeff i t) x := + CMDiffAt n (LinearMap.piApply (hs.coeff i) t) x := (((hs.contMDiffOn i).contMDiffAt hu).inner_bundle ht).congr_of_eventuallyEq <| Filter.eventually_of_mem hu fun _ hx ↦ hs.coeff_eq_inner' _ hx _ @@ -152,19 +152,20 @@ lemma contMDiffAt_coeff (hu : u ∈ 𝓝 x) (ht : CMDiffAt n (T% t) x) (i : ι) /-- If `{s i}` is an orthogonal local frame on a neighbourhood `u` of `x` and `t` is `C^k` on `u`, so is its coefficient in the frame `{s i}`. -/ -lemma contMDiffOn_coeff (ht : CMDiff[u] n (T% t)) (i : ι) : CMDiff[u] n (hs.coeff i t) := +lemma contMDiffOn_coeff (ht : CMDiff[u] n (T% t)) (i : ι) : + CMDiff[u] n (LinearMap.piApply (hs.coeff i) t) := fun x' hx ↦ hs.contMDiffWithinAt_coeff (ht x' hx) hx _ /-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal local frame near `x` is. -/ lemma contMDiffAt_iff_coeff [FiniteDimensional ℝ F] (hu : u ∈ 𝓝 x) : - CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (hs.coeff i t) x := + CMDiffAt n (T% t) x ↔ ∀ i, CMDiffAt n (LinearMap.piApply (hs.coeff i) t) x := ⟨fun h i ↦ hs.contMDiffAt_coeff hu h i, fun h ↦ hs.contMDiffAt_of_coeff h hu⟩ /-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff each of its coefficients `hs.coeff i s` w.r.t. the local frame `{s i}` is. -/ lemma contMDiffOn_iff_coeff [FiniteDimensional ℝ F] : - CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (hs.coeff i t) := + CMDiff[u] n (T% t) ↔ ∀ i, CMDiff[u] n (LinearMap.piApply (hs.coeff i) t) := ⟨fun h i ↦ hs.contMDiffOn_coeff h i, fun hi ↦ hs.contMDiffOn_of_coeff hi⟩ -- unused, just stating for convenience/nice API @@ -196,14 +197,14 @@ variable (b e) in this is obtained by applying the Gram-Schmidt orthonormalisation procedure to `b.localFrame e`. In particular, if x is outside of `e.baseSet`, this returns the junk value 0. -/ noncomputable def orthonormalFrame : ι → (x : B) → E x := - VectorBundle.gramSchmidtNormed (b.localFrame e) + VectorBundle.gramSchmidtNormed (e.localFrame b) omit [IsManifold IB n B] in variable (b e) in /-- An orthonormal frame w.r.t. a local trivialisation is an orthonormal local frame. -/ lemma orthonormalFrame_isOrthonormalFrameOn : IsOrthonormalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := - (b.localFrame_isLocalFrameOn_baseSet IB n e).gramSchmidtNormed + (e.isLocalFrameOn_localFrame_baseSet IB n b).gramSchmidtNormed omit [IsManifold IB n B] in variable (b e) in @@ -237,6 +238,6 @@ lemma orthonormalFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : simp only [orthonormalFrame, VectorBundle.gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed, RCLike.ofReal_real_eq_id, id_eq, smul_eq_zero, inv_eq_zero, norm_eq_zero, or_self] convert InnerProductSpace.gramSchmidt_zero ℝ i - apply localFrame_apply_of_notMem e b hx + exact e.localFrame_apply_of_notMem b hx end Module.Basis diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index b1e227b3a80b8a..1724d328a05604 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -89,26 +89,27 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x - let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_coeff I t b + let s := t.localFrame b + let c := t.localFrame_coeff I b have hs (i) : MDiffAt (T% (s i)) x:= (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt (by simp) have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : - MDiffAt ((c i) σ) x := - mdifferentiableAt_localFrame_coeff x_mem b hσ i + MDiffAt (LinearMap.piApply (c i) σ) x := + mdifferentiableAt_localFrame_coeff b x_mem hσ i have hφ {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) : - φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by + φ σ x = φ (fun x' ↦ ∑ i, LinearMap.piApply (c i) σ x' • s i x') x := by exact locality hσ (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) - (Basis.localFrame_eventually_eq_sum_coeff_smul b x_mem σ) + (t.eventually_eq_localFrame_sum_coeff_smul b x_mem) rw [hφ hσ, hφ hσ', sum_phi, sum_phi] - · change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x + · change ∑ i, φ ((LinearMap.piApply (c i) σ) • (s i)) x = + ∑ i, φ ((LinearMap.piApply (c i) σ') • (s i)) x congr ext i - rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i), - Basis.localFrame_coeff_congr b hσσ'] + rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i)] + simp [hσσ'] · exact fun i ↦ (hc hσ' i).smul_section (hs i) · exact fun i ↦ (hc hσ i).smul_section (hs i) @@ -149,17 +150,18 @@ lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDi have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) let b := Basis.ofVectorSpace ℝ F let t := trivializationAt F V x - let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_coeff (I := I) t b - rw [locality (b.localFrame_eventually_eq_sum_coeff_smul (I := I) x_mem σ), - locality (b.localFrame_eventually_eq_sum_coeff_smul (I := I) x_mem σ'), sum_phi, sum_phi] - change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x - congr - ext i - rw [φ_smul, φ_smul] + let s := t.localFrame b + let c := t.localFrame_coeff (I := I) b + rw [locality (t.eventually_eq_localFrame_sum_coeff_smul (I := I) b x_mem)] + nth_rw 2 [locality (t.eventually_eq_localFrame_sum_coeff_smul (I := I) b x_mem)] + rw [sum_phi, sum_phi] + -- FIXME: the `erw` below can be made an `rw` by uncommenting this `change` + --change ∑ i, φ (((LinearMap.piApply (c i)) σ) • (s i)) x = + -- ∑ i, φ (((LinearMap.piApply (c i)) σ') • (s i)) x + congr with i + -- `erw?` says this is because of smul with a constant vs. a function `M → ℝ` + erw [φ_smul, φ_smul] congr - apply b.localFrame_coeff_congr - assumption include I in omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index c6ae407398bef5..c5ba9c17cd84b1 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -10,7 +10,7 @@ public import Mathlib.Geometry.Manifold.ContMDiffMFDeriv public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable public import Mathlib.Geometry.Manifold.VectorField.Pullback -public import Mathlib.Geometry.Manifold.Notation +import Mathlib.Geometry.Manifold.Notation /-! # Lie brackets of vector fields on manifolds @@ -315,6 +315,7 @@ lemma _root_.MDifferentiableWithinAt.differentiableWithinAt_mpullbackWithin_vect exact (contMDiff_snd_tangentBundle_modelSpace E 𝓘(𝕜, E)).contMDiffAt.mdifferentiableAt one_ne_zero |>.comp_mdifferentiableWithinAt _ this +set_option backward.isDefEq.respectTransparency false in lemma mfderiv_extChartAt_inverse_comp_mfderivWithin_extChartAT_symm (Y : TangentSpace I x) : letI φ := extChartAt I x ((mfderiv% φ x).inverse.comp ((mfderiv[range I] φ.symm (φ x)).inverse) Y) = Y := by @@ -332,6 +333,7 @@ private lemma mfderiv_extChart_inverse_comp_aux : ((mfderiv[range I] φ.symm (φ x)).inverse) (W (φ.symm (φ x))) = W x := by rw [mfderiv_extChartAt_inverse_comp_mfderivWithin_extChartAT_symm, extChartAt_to_inv] +set_option backward.isDefEq.respectTransparency false in /-- Pulling back through `extChartAt` the scalar multiplication of a vector field by the derivative of a scalar function equals the scalar multiplication by the manifold derivative. -/ lemma mpullback_mfderivWithin_apply_smul {f : M → 𝕜} @@ -350,6 +352,7 @@ lemma mpullback_mfderivWithin_apply_smul {f : M → 𝕜} variable [CompleteSpace E] +set_option backward.isDefEq.respectTransparency false in /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. Version within a set. @@ -380,18 +383,19 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDiffAt[s] f x) · simpa only [A] using mpullback_mfderivWithin_apply_smul hf · simp [B, ← Pi.smul_def', mpullback_smul (V := lieBracketWithin 𝕜 V' W' s'), f'] +set_option backward.isDefEq.respectTransparency false in /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[V, f • W] = (df V) • W + f • [V, W]`. -/ lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDiffAt f x) (hW : MDiffAt (fun x ↦ (W x : TangentBundle I M)) x) : - mlieBracket I V (f • W) x = - (mfderiv% f x) (V x) • (W x) + (f x) • mlieBracket I V W x := by + mlieBracket I V (f • W) x = (mfderiv% f x) (V x) • (W x) + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hW rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I) +set_option backward.isDefEq.respectTransparency false in /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[f • V, W] = -(df W) • V + f • [V, W]`. Version within a set. @@ -405,6 +409,7 @@ lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDiffAt[s] f x) mlieBracketWithin_swap] simp; abel +set_option backward.isDefEq.respectTransparency false in /-- Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function `f : M → 𝕜`, we have `[f • V, W] = -(df W) • V + f • [V, W]`. @@ -782,7 +787,6 @@ lemma mpullbackWithin_mlieBracketWithin mlieBracketWithin I (mpullbackWithin I I' f V s) (mpullbackWithin I I' f W s) s x₀ := mpullbackWithin_mlieBracketWithin' hV hW hu hu hf hx₀ hn hst h'x₀ Subset.rfl -set_option backward.isDefEq.respectTransparency false in /-- The pullback commutes with the Lie bracket of vector fields on manifolds. -/ lemma mpullback_mlieBracketWithin {f : M → M'} {V W : Π (x : M'), TangentSpace I' x} {x₀ : M} {s : Set M} {t : Set M'} @@ -919,7 +923,6 @@ section Leibniz variable [IsManifold I (minSmoothness 𝕜 3) M] [CompleteSpace E] -set_option backward.isDefEq.respectTransparency false in /-- The Lie bracket of vector fields in manifolds satisfies the Leibniz identity `[U, [V, W]] = [[U, V], W] + [V, [U, W]]` (also called Jacobi identity). -/ theorem leibniz_identity_mlieBracketWithin_apply From 6ac17e720262691e8a27dd52fa5703cbe257b734 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 11:37:08 +0000 Subject: [PATCH 451/601] Further --- .../CovariantDerivative/Prelim.lean | 86 ++++++++++--------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 25a0054377e808..3e873e0319d335 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -109,6 +109,7 @@ lemma surjective_mfderiv_of_eventually_rightInverse variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] +set_option backward.isDefEq.respectTransparency false in lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by by_cases hs : MDiffAt s x @@ -331,15 +332,15 @@ variable {I F} @[simp] lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : extend I F (v + v') = extend I F v + extend I F v' := by - simp [extend, localExtensionOn_add] + simp [extend] @[simp] lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : - extend I F (a • v) = a • extend I F v := by simp [extend, localExtensionOn_smul]; module + extend I F (a • v) = a • extend I F v := by simp [extend]; module @[simp] lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : - extend I F (0 : V x) = 0 := by simp [extend, localExtensionOn_zero] + extend I F (0 : V x) = 0 := by simp [extend] @[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : extend I F v x = v := by @@ -357,7 +358,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht let hψ := Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - exact .smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 + exact ContMDiffOn.smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 (contMDiffOn_localExtensionOn _ hx _) lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] @@ -598,6 +599,8 @@ theorem mk2TensorAt_add end tensoriality +namespace Bundle.Trivialization + section trivilization_topology variable {B F Z : Type*} [TopologicalSpace B] @@ -605,15 +608,15 @@ variable {B F Z : Type*} [TopologicalSpace B] section any_proj variable [TopologicalSpace Z] {proj : Z → B} (e : Trivialization F proj) -lemma Trivialization.baseSet_mem_nhds {x : B} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := +lemma baseSet_mem_nhds {x : B} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := e.open_baseSet.mem_nhds_iff.mpr hx -lemma Trivialization.baseSet_prod_univ_mem_nhds {v : Z} +lemma baseSet_prod_univ_mem_nhds {v : Z} (hv : proj v ∈ e.baseSet) : e.baseSet ×ˢ univ ∈ 𝓝 (e v) := by rw [← mk_proj_snd' e hv] exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem -lemma Trivialization.comp_invFun_eventuallyEq +lemma comp_invFun_eventuallyEq {v : Z} (hv : proj v ∈ e.baseSet) : e ∘ e.invFun =ᶠ[𝓝 (e v)] id := by filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp using apply_symm_apply e <| (mem_target e).2 hp.1 @@ -624,41 +627,41 @@ section fiber_bundle variable {E : B → Type*} [TopologicalSpace (TotalSpace F E)] (e : Trivialization F (π F E)) -lemma Trivialization.proj_invFun_eventuallyEq +lemma proj_invFun_eventuallyEq {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ exact symm_coe_proj e hx -lemma Trivialization.injective_symm [(x : B) → Zero (E x)] +lemma injective_symm [(x : B) → Zero (E x)] {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : Function.Injective (e.symm v.proj) := by intro f f' hff' simpa [hv] using congr(e $hff') -lemma Trivialization.surjective_symm [(x : B) → Zero (E x)] +lemma surjective_symm [(x : B) → Zero (E x)] {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : Function.Surjective (e.symm v.proj) := fun u ↦ ⟨(e u).2, symm_apply_apply_mk e hv u⟩ -lemma Trivialization.bijective_symm [(x : B) → Zero (E x)] +lemma bijective_symm [(x : B) → Zero (E x)] {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : Function.Bijective (e.symm v.proj) := ⟨e.injective_symm hv, e.surjective_symm hv⟩ variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] -lemma Trivialization.preimage_baseSet_mem_nhds +lemma preimage_baseSet_mem_nhds {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := FiberBundle.continuous_proj F E |>.continuousAt <| e.baseSet_mem_nhds hv -lemma Trivialization.fst_comp_eventuallyEq +lemma fst_comp_eventuallyEq {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : Prod.fst ∘ e =ᶠ[𝓝 v] (π F E) := by filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using coe_fst' e hy -lemma Trivialization.invFun_comp_eventuallyEq +lemma invFun_comp_eventuallyEq {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : e.invFun ∘ e =ᶠ[𝓝 v] id := by filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw using @@ -672,7 +675,7 @@ variable {B F : Type*} {E : B → Type*} [TopologicalSpace B] [(x : B) → Zero (E x)] (e : Trivialization F (π F E)) -lemma Trivialization.eq_of {x : B} {v v' : E x} +lemma eq_of {x : B} {v v' : E x} (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : v = v' := by have := e.symm_proj_apply v hx @@ -680,7 +683,7 @@ lemma Trivialization.eq_of {x : B} {v v' : E x} grind [e.symm_proj_apply v' hx] @[simp] -lemma Trivialization.apply_symm_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : +lemma apply_symm_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : (fun x ↦ (e ⟨x, e.symm x (s x)⟩).2) =ᶠ[𝓝 x] s := by filter_upwards [e.baseSet_mem_nhds hx] with y hy rw [e.apply_mk_symm hy] @@ -690,7 +693,7 @@ variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] -- FIXME super weird elaborator bug: removing the -- omitted assumption from the variable line breaks the lemma omit [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in -lemma Trivialization.symm_apply_apply_mk_eventuallyEq +lemma symm_apply_apply_mk_eventuallyEq {b : B} (hb : b ∈ e.baseSet) (σ : Π x, E x) : (T% fun x' ↦ e.symm x' (e (T% σ x')).2) =ᶠ[𝓝 b] T% σ := by filter_upwards [e.baseSet_mem_nhds hb] with y hy @@ -699,7 +702,7 @@ lemma Trivialization.symm_apply_apply_mk_eventuallyEq -- FIXME super weird elaborator bug: removing the -- omitted assumption from the variable line breaks the lemma omit [(x : B) → Zero (E x)] [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in -lemma Trivialization.apply_section_eventuallyEq +lemma apply_section_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (σ : Π x, E x) : e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by filter_upwards [e.baseSet_mem_nhds hx] with y hy @@ -719,14 +722,14 @@ variable {R B F : Type*} {E : B → Type*} [Semiring R] (e : Trivialization F (π F E)) [AddCommMonoid F] [Module R F] [(x : B) → AddCommMonoid (E x)] [(x : B) → Module R (E x)] -lemma Trivialization.map_smul [Trivialization.IsLinear R e] +lemma map_smul [Trivialization.IsLinear R e] {b : B} (hb : b ∈ e.baseSet) (a : R) (v : E b) : (e ⟨b, a • v⟩).2 = a • (e ⟨b, v⟩).2 := e.linear R hb |>.map_smul a v variable (R) -lemma Trivialization.map_add [Trivialization.IsLinear R e] +lemma map_add [Trivialization.IsLinear R e] {b : B} (hb : b ∈ e.baseSet) (v v' : E b) : (e ⟨b, v + v'⟩).2 = (e ⟨b, v⟩).2 + (e ⟨b, v'⟩).2 := e.linear R hb |>.map_add v v' @@ -742,19 +745,19 @@ variable (R : Type*) {B F : Type*} {E : B → Type*} [(x : B) → TopologicalSpace (E x)] [FiberBundle F E] (e : Trivialization F (π F E)) -lemma Trivialization.symm_map_add [Trivialization.IsLinear R e] {x : B} +lemma symm_map_add [Trivialization.IsLinear R e] {x : B} (f f' : F) : e.symm x (f + f') = e.symm x f + e.symm x f' := (symmL R e x).map_add f f' @[simp] -lemma Trivialization.symm_map_zero [Trivialization.IsLinear R e] {x : B} : +lemma symm_map_zero [Trivialization.IsLinear R e] {x : B} : e.symm x 0 = 0 := (symmL R e x).map_zero variable {R} -lemma Trivialization.symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : +lemma symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : e.symm x (a • f) = a • e.symm x f := (symmL R e x).map_smul a f @@ -777,8 +780,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] - -lemma Trivialization.mdifferentiableAt +lemma mdifferentiableAt [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {x : M} (hx : x ∈ e.baseSet) (v : V x) : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by @@ -787,7 +789,7 @@ MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by have := foo.contMDiffAt (e.open_source.mem_nhds this) exact this.mdifferentiableAt zero_ne_one.symm -lemma Trivialization.mdifferentiableAt_invFun +lemma mdifferentiableAt_invFun [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {x : M} (hx : x ∈ e.baseSet) (f : F) : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (x, f) := by @@ -802,18 +804,19 @@ lemma Trivialization.mdifferentiableAt_invFun -- which is $T_{π(v)} M × F$. variable (I) in noncomputable -def Trivialization.deriv (v : TotalSpace F V) : +def deriv (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] TangentSpace I v.proj × F := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v variable (I) in noncomputable -def Trivialization.derivInv (v : TotalSpace F V) : +def derivInv (v : TotalSpace F V) : TangentSpace I v.proj × F →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, F)) v := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (e v) +set_option backward.isDefEq.respectTransparency false in @[simp] -lemma Trivialization.derivInv_deriv +lemma derivInv_deriv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : (e.derivInv I v) ∘L (e.deriv I v) = .id ℝ _ := by @@ -825,7 +828,7 @@ lemma Trivialization.derivInv_deriv simp [deriv, derivInv, comp] @[simp] -lemma Trivialization.derivInv_deriv_apply +lemma derivInv_deriv_apply [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : @@ -833,7 +836,7 @@ lemma Trivialization.derivInv_deriv_apply show ((e.derivInv I v) ∘L (e.deriv I v)) u = u by simp [hv] @[simp] -lemma Trivialization.mfderiv_proj_fst_deriv +lemma mfderiv_proj_fst_deriv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : @@ -843,8 +846,9 @@ lemma Trivialization.mfderiv_proj_fst_deriv simp rfl -- TODO: understand why `simp` does not handle `ContinuousLinearMap.fst` +set_option backward.isDefEq.respectTransparency false in @[simp] -lemma Trivialization.mfderiv_proj_derivInv_apply +lemma mfderiv_proj_derivInv_apply [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : @@ -869,9 +873,9 @@ lemma Trivialization.mfderiv_proj_derivInv_apply simp rfl - +set_option backward.isDefEq.respectTransparency false in @[simp] -lemma Trivialization.deriv_derivInv +lemma deriv_derivInv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : (e.deriv I v) ∘L (e.derivInv I v) = .id ℝ _ := by @@ -887,14 +891,14 @@ lemma Trivialization.deriv_derivInv convert comp <;> rw [this] @[simp] -lemma Trivialization.deriv_derivInv_apply +lemma deriv_derivInv_apply [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) (u : TangentSpace I v.proj × F) : e.deriv I v (e.derivInv I v u) = u := show ((e.deriv I v) ∘L (e.derivInv I v)) u = u by simp [hv] -lemma Trivialization.bijective_deriv +lemma bijective_deriv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : Function.Bijective (e.deriv I v) := by @@ -903,7 +907,7 @@ lemma Trivialization.bijective_deriv constructor all_goals { intro u; simp [hv] } -lemma Trivialization.mdifferentiableAt_section_of_function +lemma mdifferentiableAt_section_of_function [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {x : M} (hx : x ∈ e.baseSet) {s : M → F} (hs : MDiffAt s x) : @@ -916,7 +920,7 @@ noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker -lemma Trivialization.comap_vert +lemma comap_vert [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap @@ -931,7 +935,7 @@ lemma Trivialization.comap_vert simp rfl -lemma Trivialization.mfderiv_comp_section +lemma mfderiv_comp_section [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) (u : TangentSpace I x) (hx : x ∈ e.baseSet) : @@ -957,14 +961,14 @@ lemma Trivialization.mfderiv_comp_section · exact (mdifferentiableAt_section_iff I e σ hx).mp hσ @[simp] -lemma mdifferentiableAt_section_trivial_iff {s : M → F} {x : M} : +lemma _root_.mdifferentiableAt_section_trivial_iff {s : M → F} {x : M} : MDiffAt (T% s) x ↔ MDiffAt s x := by rw [mdifferentiableAt_section I] simp - end to_trivialization +end Bundle.Trivialization section linear_algebra_isCompl lemma LinearMap.comap_isCompl {R R₂ M M₂ : Type*} From 5c96bb7f75641a73ff7746240d42fa6761b54219 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 11:43:52 +0000 Subject: [PATCH 452/601] Further --- .../CovariantDerivative/Basic.lean | 36 +++++++++++-------- .../CovariantDerivative/Lift.lean | 2 -- .../CovariantDerivative/Torsion.lean | 30 ++++++++-------- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 5ae43a2f0af339..95e8e1ec1656ff 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -653,6 +653,7 @@ lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f use u - (0, hcov.projection x f u), ?_, (0, hcov.projection x f u), ?_, ?_ all_goals simp [horiz] +set_option backward.isDefEq.respectTransparency false in lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : F} {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ ∃ σ : M → F, MDiffAt (T% σ) x ∧ @@ -688,19 +689,21 @@ end projection_trivial_bundle end IsCovariantDerivativeOn +namespace Bundle.Trivialization + section to_trivialization variable (e : Trivialization F (π F V)) [VectorBundle ℝ F V] [MemTrivializationAtlas e] [IsManifold I 1 M] - noncomputable -def Trivialization.pushCovDer +def pushCovDer (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (fun x' ↦ e.symm x' <| σ x') x) -lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] +set_option backward.isDefEq.respectTransparency false in +lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] [ContMDiffVectorBundle 1 F V I] @@ -717,13 +720,13 @@ lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensio exact hσ unfold pushCovDer rw [this] - simp [Trivialization.coe_linearMapAt, hx] + simp [coe_linearMapAt, hx] variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) -lemma Trivialization.pushCovDer_isCovariantDerivativeOn +lemma pushCovDer_isCovariantDerivativeOn [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] [ContMDiffVectorBundle 1 F V I] {u : Set M} (hu : u ⊆ e.baseSet) @@ -737,7 +740,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn have hs' : MDiffAt (T% s') x := e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' - unfold Trivialization.pushCovDer + unfold pushCovDer rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] congr ext y @@ -746,7 +749,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold Trivialization.pushCovDer + unfold pushCovDer have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by ext y simp [s, e.symm_map_smul] @@ -761,7 +764,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn exact e.linearMapAt_symmₗ (R := ℝ) (hu hx) (σ x) variable {e} in -lemma Trivialization.coordChangeL_pushCovDer +lemma coordChangeL_pushCovDer [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -773,7 +776,7 @@ lemma Trivialization.coordChangeL_pushCovDer e'.pushCovDer cov (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by ext1 X₀ simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, Function.comp_apply] - unfold Trivialization.pushCovDer + unfold pushCovDer let σ := (fun x' ↦ e.symm x' (s x')) rw [coordChangeL_apply e e' hx] simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, coe_linearMapAt, hx.1, @@ -805,7 +808,7 @@ lemma Trivialization.coordChangeL_pushCovDer variable {e} in -lemma Trivialization.coordChangeL_mem_horiz +lemma coordChangeL_mem_horiz [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -837,7 +840,7 @@ lemma Trivialization.coordChangeL_mem_horiz -- This is PAIIIIINNNN variable {e} in -lemma Trivialization.coordChangeL_coordChangeL +lemma coordChangeL_coordChangeL {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : e'.coordChangeL ℝ e x (e.coordChangeL ℝ e' x v) = v := by @@ -866,7 +869,7 @@ lemma Trivialization.coordChangeL_coordChangeL simp variable {e} in -lemma Trivialization.coordChangeL_mem_horiz_iff +lemma coordChangeL_mem_horiz_iff [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] @@ -893,6 +896,8 @@ lemma Trivialization.coordChangeL_mem_horiz_iff end to_trivialization +end Bundle.Trivialization + section horiz namespace CovariantDerivative @@ -938,8 +943,9 @@ noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (cov.proj v).ker -lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : - u ∈ cov.horiz v ↔ cov.proj v u = 0 := by +lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} + (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + u ∈ cov.horiz v ↔ cov.proj v u = 0 := by simp [horiz] lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : @@ -974,6 +980,7 @@ lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} +set_option backward.isDefEq.respectTransparency false in omit [ContMDiffVectorBundle 1 F V I] in lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] {σ : Π x : M, V x} (x : M) @@ -1002,7 +1009,6 @@ end horiz end real - -- variable (E E') in -- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ -- @[simps] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 225d1df7e40e6c..4113d3c058cd14 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -63,7 +63,6 @@ def Bundle.pullback_diag (e : TotalSpace F E) : (TotalSpace.proj *ᵖ E) e := e.2 end - section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] @@ -377,4 +376,3 @@ lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} rw [ht'.proj_acceleration cov ht] end geodesics - diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 3f47ebb86128ae..03137fcd71aed2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -269,15 +269,15 @@ lemma aux1 {ι : Type*} [Fintype ι] {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.coeff i) X x • torsion f (s i) Y x := + torsion f X Y x = ∑ i, (hs.coeff i) x (X x) • torsion f (s i) Y x := have hU : U ∈ 𝓝 x := sorry have aux := hs.eventually_eq_sum_coeff_smul X hU - have hX : X x = ∑ i, (hs.coeff i) X x • s i x := sorry + have hX : X x = ∑ i, (hs.coeff i) x (X x) • s i x := sorry calc torsion f X Y x - _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) X x • s i x) Y x := by + _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) x (X x) • s i x) Y x := by sorry -- tensoriality and [hX] - _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) X x • s i x) Y x) := sorry - _ = ∑ i, (hs.coeff i) X x • (torsion f (s i) Y x) := sorry + _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) x (X x) • s i x) Y x) := sorry + _ = ∑ i, (hs.coeff i) x (X x) • (torsion f (s i) Y x) := sorry -- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x variable {n} in @@ -286,20 +286,20 @@ lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.coeff i) Y x • torsion f X (s i) x := + torsion f X Y x = ∑ i, (hs.coeff i) x (Y x) • torsion f X (s i) x := have hU : U ∈ 𝓝 x := sorry have aux := hs.eventually_eq_sum_coeff_smul Y hU - have hY : Y x = ∑ i, (hs.coeff i) Y x • s i x := hs.coeff_sum_eq Y hx + have hY : Y x = ∑ i, (hs.coeff i) x (Y x) • s i x := hs.coeff_sum_eq Y hx calc torsion f X Y x - _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by + _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) x (Y x) • s i x) x := by sorry -- tensoriality and [hY] - _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) Y x • s i x) x) := sorry - _ = ∑ i, (hs.coeff i) Y x • (torsion f X (s i) x) := by + _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) x (Y x) • s i x) x) := sorry + _ = ∑ i, (hs.coeff i) x (Y x) • (torsion f X (s i) x) := by congr with i - have hsi : MDiffAt (hs.coeff i Y) x := sorry + have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry have hsi' : MDiffAt (T% (s i)) x := sorry - have := hf.torsion_smul_right_apply (X := X) (Y := s i) (f := (hs.coeff i) Y) hsi hsi' - rw [← this] + have := hf.torsion_smul_right_apply (X := X) (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' + erw [← this] congr /-- We can test torsion-freeness on a set using a local frame. -/ @@ -314,10 +314,10 @@ lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame intro x hx X Y rw [aux1 hs hx] calc - _ = ∑ i, (hs.coeff i) X x • ∑ j, (hs.coeff j) Y x • torsion f (s i) (s j) x := by + _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • torsion f (s i) (s j) x := by congr! rw [aux2 hf hs hx] - _ = ∑ i, (hs.coeff i) X x • ∑ j, (hs.coeff j) Y x • 0 := by + _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • 0 := by congr! with i _ j _ exact h i j x hx _ = 0 := by simp From 83643af2e679b2f53272609857ecbf7628f96c2d Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:06:20 +0000 Subject: [PATCH 453/601] down to one sorry --- .../CovariantDerivative/LeviCivita.lean | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index dfb31d164582b9..44907bc5e8474f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -700,8 +700,6 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] ext Z₀ simpa [Φ, product] using congr($(h (_root_.extend I E Z₀)) x) -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] - /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ -- (probably not everywhere, as addition rules apply only for differentiable vector fields?) @@ -710,13 +708,20 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) : -- almost, only agree on smooth functions cov = cov' := by - ext X σ x - apply congrFun - sorry - -- apply congr_of_forall_product fun Z ↦ ?_ - -- trans leviCivitaRhs I X σ Z - -- · exact hcov.eq_leviCivitaRhs I X σ Z - -- · exact (hcov'.eq_leviCivitaRhs I X σ Z ).symm + ext X x Y₀ + have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ + set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) + apply Φ.injective + ext Z₀ + let Y := _root_.extend I E Y₀ + let Z := _root_.extend I E Z₀ + suffices inner ℝ (cov X x (Y x)) (Z x) = inner ℝ (cov' X x (Y x)) (Z x) by simpa [Φ, Y, Z] + trans leviCivitaRhs I X Y Z x + · exact congr($(hcov.eq_leviCivitaRhs I X Y Z) x) + · exact congr($((hcov'.eq_leviCivitaRhs I X Y Z).symm) x) + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] From a19ae150e7cfba2d859aa569138f0f4ccb0f8cdf Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:33:06 +0000 Subject: [PATCH 454/601] last sorry in lc file --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 44907bc5e8474f..306c8c48f0de50 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -649,8 +649,8 @@ lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = trans ⟪∇ X, Y, Z⟫ + ⟪Y, ∇ X, Z⟫ · ext x exact h.1 X Y Z x - · sorry - -- simp [← isTorsionFree_iff.mp h.2 X Z, product_sub_right] + · ext x + simp [← isTorsionFree_iff.mp h.2 X Z, product, inner_sub_right] lemma isolate_aux {α : Type*} [AddCommGroup α] (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : From b4d4d128de11c4ffff003d747e71fb6310555467 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:41:27 +0000 Subject: [PATCH 455/601] golf using linear_combination --- .../CovariantDerivative/LeviCivita.lean | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 306c8c48f0de50..efcefb561543da 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -652,11 +652,6 @@ lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = · ext x simp [← isTorsionFree_iff.mp h.2 X Z, product, inner_sub_right] -lemma isolate_aux {α : Type*} [AddCommGroup α] - (A D E F X Y Z : α) (h : X + Y - Z = A + A + D + E - F) : - A + A = X + Y - Z - D - E + F := by - rw [h]; abel - variable (X Y Z) {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ @@ -665,6 +660,7 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : set A := ⟪∇ X, Y, Z⟫ set B := ⟪∇ Z, X, Y⟫ set C := ⟪∇ Y, Z, X⟫ + unfold leviCivitaRhs leviCivitaRhs' set D := ⟪Y, VectorField.mlieBracket I X Z⟫ with D_eq set E := ⟪Z, VectorField.mlieBracket I Y X⟫ with E_eq set F := ⟪X, VectorField.mlieBracket I Z Y⟫ with F_eq @@ -674,15 +670,7 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : simp only [aux I Y Z X cov h, A, C, E, product_swap _ (∇ X, Y) Z] have eq3 : rhs_aux I Z X Y = B + C + F := by simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (∇ Y, Z)] - -- Add eq1 and eq2 and subtract eq3. - have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by - rw [eq1, eq2, eq3]; abel - -- Solve for ⟪∇ X, Y, Z⟫ and obtain the claim. - have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) - (by simp [this]) - have almoster : A + A = leviCivitaRhs' I X Y Z := by simp only [leviCivitaRhs', *] - simp only [leviCivitaRhs, ← almoster, smul_add] - ext; simp; ring + linear_combination (norm := module) -(2:ℝ)⁻¹ • (eq1 + eq2 - eq3) section From 51a83800dcc3a866891084e401ee7c96c6c4f27e Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:45:15 +0000 Subject: [PATCH 456/601] golf --- .../CovariantDerivative/LeviCivita.lean | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index efcefb561543da..f87c275938ba44 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -657,19 +657,11 @@ variable (X Y Z) {cov} in ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : ⟪∇ X, Y, Z⟫ = leviCivitaRhs I X Y Z := by - set A := ⟪∇ X, Y, Z⟫ - set B := ⟪∇ Z, X, Y⟫ - set C := ⟪∇ Y, Z, X⟫ unfold leviCivitaRhs leviCivitaRhs' - set D := ⟪Y, VectorField.mlieBracket I X Z⟫ with D_eq - set E := ⟪Z, VectorField.mlieBracket I Y X⟫ with E_eq - set F := ⟪X, VectorField.mlieBracket I Z Y⟫ with F_eq - have eq1 : rhs_aux I X Y Z = A + B + D := by - simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (∇ Z, X)] - have eq2 : rhs_aux I Y Z X = C + A + E := by - simp only [aux I Y Z X cov h, A, C, E, product_swap _ (∇ X, Y) Z] - have eq3 : rhs_aux I Z X Y = B + C + F := by - simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (∇ Y, Z)] + have eq1 := aux I X Y Z cov h + have eq2 := aux I Y Z X cov h + have eq3 := aux I Z X Y cov h + simp [product_swap] at * linear_combination (norm := module) -(2:ℝ)⁻¹ • (eq1 + eq2 - eq3) section From f35725277f48dbbc1b975dd288008da934d2e1e2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 11:49:48 +0000 Subject: [PATCH 457/601] Fix the build of LeviCivita --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index f87c275938ba44..4ccbd183ca742d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -30,6 +30,9 @@ open scoped Bundle Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! +-- TODO: revisit and fix this once the dust has settled +set_option backward.isDefEq.respectTransparency false + -- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. variable {n : WithTop ℕ∞} {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] From 58e15e94b798051609a9b2ccbb074532e19c9187 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 12:11:10 +0000 Subject: [PATCH 458/601] Fix Lift --- .../VectorBundle/CovariantDerivative/Lift.lean | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 4113d3c058cd14..5fd1508b0baf90 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -70,18 +70,18 @@ variable [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - {cov : ((x : M) → TangentSpace I x) → (M → F) → M → F} + {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) noncomputable def IsCovariantDerivativeOn.lift_vec (x : M) (f : F) : TangentSpace I x →L[ℝ] TangentSpace I x × F := - .prod (.id ℝ _) (-evalL ℝ F F f ∘L hcov.one_form x) + .prod (.id ℝ _) (-hcov.one_form x f) @[simp] lemma IsCovariantDerivativeOn.lift_vec_apply (x : M) (f : F) (u : TangentSpace I x) : - hcov.lift_vec x f u = (u , -hcov.one_form x u f) := + hcov.lift_vec x f u = (u , -hcov.one_form x f u) := rfl @[simp] @@ -116,6 +116,7 @@ variable [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [FiniteDimensional ℝ E] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] {cov : CovariantDerivative I F V} [ContMDiffVectorBundle 1 F V I] @@ -230,6 +231,7 @@ lemma IsMIntegralCurveAt.mdifferentiableAt (h : IsMIntegralCurveAt γ v t₀) : filter_upwards [h] with t ht exact ht.mdifferentiableAt +set_option backward.isDefEq.respectTransparency false in protected lemma IsMIntegralCurveAt.mfderiv (hγ : IsMIntegralCurveAt γ v t₀) : ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by filter_upwards [hγ] with t ht @@ -315,8 +317,9 @@ I γ t).2 := by lemma IsMIntegralCurveAt.proj_acceleration {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) (hγX : IsMIntegralCurveAt γ X t₀) : - cov.proj _ (velocity I.tangent (velocity I γ) t₀).2 = cov X X (γ t₀) := by - rw [hγX.acceleration hX, cov.proj_mderiv _ hX hX] + cov.proj _ (velocity I.tangent (velocity I γ) t₀).2 = cov X (γ t₀) (X (γ t₀)) := by + rw [hγX.acceleration hX, cov.proj_mderiv _ hX] + simp noncomputable def CovariantDerivative.geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : @@ -338,6 +341,7 @@ Remember: `IsMIntegralCurveAt` is local, not pointwise. -/ def CovariantDerivative.isGeodAt (γ : ℝ → M) (t : ℝ) := IsMIntegralCurveAt (velocity I γ) cov.geodVF t +set_option backward.isDefEq.respectTransparency false in lemma CovariantDerivative.isGeodAt_iff_horiz {γ : ℝ → M} {t₀ : ℝ} (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : cov.isGeodAt γ t₀ ↔ @@ -365,11 +369,12 @@ lemma CovariantDerivative.isGeodAt_iff_proj {γ : ℝ → M} {t₀ : ℝ} def CovariantDerivative.isGeod (γ : ℝ → M) := ∀ t, cov.isGeodAt γ t +set_option backward.isDefEq.respectTransparency false in lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) (hγX : IsMIntegralCurveAt γ X t₀) : - cov.isGeodAt γ t₀ ↔ ∀ᶠ t in 𝓝 t₀, cov X X (γ t) = 0 := by + cov.isGeodAt γ t₀ ↔ ∀ᶠ t in 𝓝 t₀, cov X (γ t) (X (γ t)) = 0 := by rw [cov.isGeodAt_iff_proj hγ] refine eventually_congr ?_ filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t ht ht' From 32a6e229da6c14879d38753438141557a8d8ddaf Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 4 Mar 2026 13:20:55 +0100 Subject: [PATCH 459/601] Try to catch up --- .../CovariantDerivative/Basic.lean | 33 +- .../CovariantDerivative/Prelim.lean | 461 +------------- .../CovariantDerivative/TrivPrelim.lean | 579 ++++++++++++++++++ 3 files changed, 624 insertions(+), 449 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 95e8e1ec1656ff..354855e22de640 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -62,7 +62,7 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] leibniz {σ : Π x : M, V x} {g : M → 𝕜} {x} (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): f (g • σ) x = g x • f σ x - + ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L + + .toSpanSingleton 𝕜 (σ x) ∘L (((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜) g x))) /-- @@ -248,10 +248,7 @@ noncomputable def trivial [IsManifold I 1 M] : IsCovariantDerivativeOn F (V := Trivial M F) (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where addσ {σ σ' x} hσ hσ' hx := by - rw [mdifferentiableAt_section] at hσ hσ' - -- TODO: specialize mdifferentiableAt_section to trivial bundles? - change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ - change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' + rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' rw [mfderiv_add hσ hσ'] leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ @@ -385,10 +382,7 @@ noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial toFun s x := mfderiv I 𝓘(𝕜, F) s x isCovariantDerivativeOn := -- TODO use previous work { addσ {σ σ' x} hσ hσ' hx := by - rw [mdifferentiableAt_section] at hσ hσ' - -- TODO: specialize mdifferentiableAt_section to trivial bundles? - change MDifferentiableAt I 𝓘(𝕜, F) σ x at hσ - change MDifferentiableAt I 𝓘(𝕜, F) σ' x at hσ' + rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' rw [mfderiv_add hσ hσ'] leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ @@ -700,7 +694,7 @@ noncomputable def pushCovDer (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := - fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (fun x' ↦ e.symm x' <| σ x') x) + fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (e.funToSec σ) x) set_option backward.isDefEq.respectTransparency false in lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] @@ -716,9 +710,11 @@ lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] have : cov (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov σ x := by apply hcov.congr_σ_of_eqOn _ hσ (e.baseSet_mem_nhds hx) · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? - · rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] + · stop + rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] exact hσ unfold pushCovDer + stop rw [this] simp [coe_linearMapAt, hx] @@ -735,12 +731,12 @@ lemma pushCovDer_isCovariantDerivativeOn addσ {σ σ' x} hσ hσ' hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ set s' := (fun x' ↦ e.symm x' (σ' x')) have hs' : MDiffAt (T% s') x := - e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 - hσ' - unfold pushCovDer + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' + unfold Trivialization.pushCovDer + stop rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] congr ext y @@ -748,11 +744,12 @@ lemma pushCovDer_isCovariantDerivativeOn leibniz {σ g x} hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold pushCovDer + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ + unfold Trivialization.pushCovDer have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by ext y simp [s, e.symm_map_smul] + stop rw [this, hcov.leibniz hs hg hx] ext X₀ simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, @@ -785,6 +782,7 @@ lemma coordChangeL_pushCovDer have : e.symm x (e ⟨x, cov σ x X₀⟩).2 = cov σ x X₀ := by -- TODO fix `simp [hx.1]` not working exact symm_apply_apply_mk e hx.1 (cov σ x X₀) + stop rw [this] -- TODO: extract lemma? have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = @@ -987,6 +985,7 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] (hσ : MDiffAt (T% σ) x) : cov σ x = cov.proj (σ x) ∘L (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x) := by + stop let t := trivializationAt F V x let s := fun x ↦ (t (σ x)).2 let Tσx := mfderiv% (T% σ) x diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 3e873e0319d335..6a1743e902c460 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -15,6 +15,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim /-! # Supporting lemmas for CovariantDerivative.Basic @@ -27,38 +28,6 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff -@[expose] public section delaborators - --- TODO: decide whether we want this and move --- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` -open Lean PrettyPrinter Delaborator SubExpr - -@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do - whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - -@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do - whenPPOption getPPNotation do - let args := (← getExpr).getAppArgs - if args.size < 22 then failure - let pt : Term ← withNaryArg 21 <| delab - let f := args[20]! - try - if let .lam _ _ b _ := f then - if b.isAppOf ``Bundle.TotalSpace.mk' then - let s := b.getAppArgs[4]!.getAppFn - if s matches .fvar .. then - let ss ← PrettyPrinter.delab s - return ← `(MDiffAt (T% $ss) $pt) - throwError "nope" - catch _ => - let x : Term ← withNaryArg 20 <| delab - return ← `(MDiffAt $x $pt) - -end delaborators @[expose] public section tangent_bundle_normedSpace @@ -67,7 +36,7 @@ variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] instance (f : F) : CoeOut (TangentSpace 𝓘(ℝ, F) f) F := ⟨fun x ↦ x⟩ -end tangent_bundle_normedSpace +end tangent_bundle_normedSpace @[expose] public section mfderiv @@ -81,27 +50,27 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] --- Note: this lemma is no longer used, but still pretty nice +-- unused; could move to `SpecificFunctions` lemma injective_mfderiv_of_eventually_leftInverse {f : M → M'} (x : M) {g : M' → M} - (hg : MDifferentiableAt I' I g (f x)) (hf : MDifferentiableAt I I' f x) - (hfg : g ∘ f =ᶠ[𝓝 x] id) : Injective (mfderiv I I' f x) := by + (hg : MDiffAt g (f x)) (hf : MDiffAt f x) + (hfg : g ∘ f =ᶠ[𝓝 x] id) : Injective (mfderiv% f x) := by have := mfderiv_comp x hg hf rw [hfg.mfderiv_eq] at this - have : LeftInverse (mfderiv I' I g (f x)) (mfderiv I I' f x) := by + have : LeftInverse (mfderiv% g (f x)) (mfderiv% f x) := by intro u simpa using congr($this u).symm exact LeftInverse.injective this --- Note: this lemma is no longer used, but still pretty nice +-- unused; could move to `SpecificFunctions` lemma surjective_mfderiv_of_eventually_rightInverse {f : M → M'} {x : M} {y : M'} (hxy : y = f x) {g : M' → M} - (hg : MDifferentiableAt I' I g y) (hf : MDifferentiableAt I I' f x) - (hfg : g ∘ f =ᶠ[𝓝 x] id) : Surjective (mfderiv I' I g y) := by + (hg : MDiffAt g y) (hf : MDiffAt f x) + (hfg : g ∘ f =ᶠ[𝓝 x] id) : Surjective (mfderiv% g y) := by rw [hxy] at hg have := mfderiv_comp x hg hf rw [hfg.mfderiv_eq] at this - have : RightInverse (mfderiv I I' f x) (mfderiv I' I g (f x)) := by + have : RightInverse (mfderiv% f x) (mfderiv% g (f x)) := by intro u simpa using congr($this u).symm rw [← hxy] at this @@ -110,8 +79,9 @@ lemma surjective_mfderiv_of_eventually_rightInverse variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] set_option backward.isDefEq.respectTransparency false in +-- cleaned up and PRed in #34262 lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : - mfderiv I 𝓘(𝕜, F) (a • s) x v = a • mfderiv I 𝓘(𝕜, F) s x v := by + mfderiv% (a • s) x v = a • mfderiv% s x v := by by_cases hs : MDiffAt s x · have hs' := hs.const_smul a suffices @@ -126,18 +96,19 @@ lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) rw [this, ha] change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ simp - have hs' : ¬ MDifferentiableAt I 𝓘(𝕜, F) (a • s) x := + have hs' : ¬ MDiffAt (a • s) x := fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] simp rfl +-- PRed and cleaned up in #34263 set_option linter.flexible false in -- FIXME lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) (hs : MDiffAt s x) (v : TangentSpace I x) : - letI dsxv : 𝕜 := mfderiv I 𝓘(𝕜, 𝕜) s x v - letI dfxv : F := mfderiv I 𝓘(𝕜, F) f x v - mfderiv I 𝓘(𝕜, F) (s • f) x v = (s x) • dfxv + dsxv • f x := by + letI dsxv : 𝕜 := mfderiv% s x v + letI dfxv : F := mfderiv% f x v + mfderiv% (s • f) x v = (s x) • dfxv + dsxv • f x := by set φ := chartAt H x -- TODO: the next two have should be special cases of the same lemma have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by @@ -230,7 +201,7 @@ def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I letI ψ := extChartAt I' x' letI φ := extChartAt I x ψ.symm ∘ - (map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u')) ∘ + (map_of_loc_one_jet 𝕜 (φ x) (mfderiv% φ x u) (ψ x') (mfderiv% ψ x' u')) ∘ φ -- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. @@ -247,22 +218,19 @@ lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] (u' : TangentSpace I' x') (hu : u = 0 → u' = 0) : map_of_one_jet u u' x = x' ∧ MDiffAt (map_of_one_jet u u') x ∧ - mfderiv I I' (map_of_one_jet u u') x u = u' := by + mfderiv% (map_of_one_jet u u') x u = u' := by let ψ := extChartAt I' x' let φ := extChartAt I x - let g := map_of_loc_one_jet 𝕜 (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') - let Ψ : M' → E' := ψ -- FIXME: this is working around a limitation of MDiffAt elaborator - have hψ : MDiffAt Ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') - let Φ : M → E := φ -- FIXME: this is working around a limitation of MDiffAt elaborator - have hφ : MDiffAt Φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) - replace hu : mfderiv I 𝓘(𝕜, E) φ x u = 0 → mfderiv I' 𝓘(𝕜, E') ψ x' u' = 0 := by - have : Function.Injective (mfderiv I 𝓘(𝕜, E) φ x) := + let g := map_of_loc_one_jet 𝕜 (φ x) (mfderiv% φ x u) (ψ x') (mfderiv% ψ x' u') + have hψ : MDiffAt ψ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') + have hφ : MDiffAt φ x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) + replace hu : mfderiv% φ x u = 0 → mfderiv% ψ x' u' = 0 := by + have : Function.Injective (mfderiv% φ x) := (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x)).injective rw [injective_iff_map_eq_zero] at this - have := map_zero (mfderiv I' 𝓘(𝕜, E') ψ x') + have := map_zero (mfderiv% ψ x') grind - rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) - (φ x) (mfderiv I 𝓘(𝕜, E) φ x u) (ψ x') (mfderiv I' 𝓘(𝕜, E') ψ x' u') hu with + rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) (φ x) (mfderiv% φ x u) (ψ x') (mfderiv% ψ x' u') hu with ⟨h : g (φ x) = ψ x', h', h''⟩ have hg : MDiffAt g (φ x) := mdifferentiableAt_iff_differentiableAt.mpr h' have hgφ : MDiffAt (g ∘ φ) x := h'.comp_mdifferentiableAt hφ @@ -276,7 +244,7 @@ lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] refold_let g φ ψ at * refine ⟨by simp [h, ψ], hψi.comp x hgφ, ?_⟩ rw [mfderiv_comp x hψi hgφ, mfderiv_comp x hg hφ, mfderiv_eq_fderiv] - change (mfderiv 𝓘(𝕜, E') I' Ψi (g (φ x))) (fderiv 𝕜 g (φ x) <| mfderiv I 𝓘(𝕜, E) φ x u) = u' + change (mfderiv% Ψi (g (φ x))) (fderiv 𝕜 g (φ x) <| mfderiv% φ x u) = u' rw [h] at hψi rw [h'', h, ← mfderiv_comp_apply x' hψi hψ] have : Ψi ∘ ψ =ᶠ[𝓝 x'] id := by @@ -351,7 +319,7 @@ variable (I F) lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - ContMDiff I (I.prod 𝓘(ℝ, F)) ∞ (T% (extend I F σ₀)) := by + CMDiff ∞ (T% (extend I F σ₀)) := by letI t := trivializationAt F V x letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x @@ -599,377 +567,6 @@ theorem mk2TensorAt_add end tensoriality -namespace Bundle.Trivialization - -section trivilization_topology - -variable {B F Z : Type*} [TopologicalSpace B] - [TopologicalSpace F] - -section any_proj -variable [TopologicalSpace Z] {proj : Z → B} (e : Trivialization F proj) -lemma baseSet_mem_nhds {x : B} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := - e.open_baseSet.mem_nhds_iff.mpr hx - -lemma baseSet_prod_univ_mem_nhds {v : Z} - (hv : proj v ∈ e.baseSet) : e.baseSet ×ˢ univ ∈ 𝓝 (e v) := by - rw [← mk_proj_snd' e hv] - exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem - -lemma comp_invFun_eventuallyEq - {v : Z} (hv : proj v ∈ e.baseSet) : e ∘ e.invFun =ᶠ[𝓝 (e v)] id := by - filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp using - apply_symm_apply e <| (mem_target e).2 hp.1 - -end any_proj - -section fiber_bundle -variable {E : B → Type*} [TopologicalSpace (TotalSpace F E)] - (e : Trivialization F (π F E)) - -lemma proj_invFun_eventuallyEq - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by - filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ - exact symm_coe_proj e hx - -lemma injective_symm [(x : B) → Zero (E x)] - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - Function.Injective (e.symm v.proj) := by - intro f f' hff' - simpa [hv] using congr(e $hff') - -lemma surjective_symm [(x : B) → Zero (E x)] - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - Function.Surjective (e.symm v.proj) := - fun u ↦ ⟨(e u).2, symm_apply_apply_mk e hv u⟩ - -lemma bijective_symm [(x : B) → Zero (E x)] - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - Function.Bijective (e.symm v.proj) := - ⟨e.injective_symm hv, e.surjective_symm hv⟩ - -variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] - -lemma preimage_baseSet_mem_nhds - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := - FiberBundle.continuous_proj F E |>.continuousAt <| e.baseSet_mem_nhds hv - -lemma fst_comp_eventuallyEq - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - Prod.fst ∘ e =ᶠ[𝓝 v] (π F E) := by - filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using coe_fst' e hy - -lemma invFun_comp_eventuallyEq - {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : - e.invFun ∘ e =ᶠ[𝓝 v] id := by - filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw using - symm_apply_apply e <| (mem_source e).mpr hw - -end fiber_bundle - -section -variable {B F : Type*} {E : B → Type*} [TopologicalSpace B] - [TopologicalSpace F] [TopologicalSpace (TotalSpace F E)] - [(x : B) → Zero (E x)] - (e : Trivialization F (π F E)) - -lemma eq_of {x : B} {v v' : E x} - (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : - v = v' := by - have := e.symm_proj_apply v hx - rw [hvv'] at this - grind [e.symm_proj_apply v' hx] - -@[simp] -lemma apply_symm_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : - (fun x ↦ (e ⟨x, e.symm x (s x)⟩).2) =ᶠ[𝓝 x] s := by - filter_upwards [e.baseSet_mem_nhds hx] with y hy - rw [e.apply_mk_symm hy] - -variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] - --- FIXME super weird elaborator bug: removing the --- omitted assumption from the variable line breaks the lemma -omit [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in -lemma symm_apply_apply_mk_eventuallyEq - {b : B} (hb : b ∈ e.baseSet) (σ : Π x, E x) : - (T% fun x' ↦ e.symm x' (e (T% σ x')).2) =ᶠ[𝓝 b] T% σ := by - filter_upwards [e.baseSet_mem_nhds hb] with y hy - simp [symm_apply_apply_mk e hy (σ y)] - --- FIXME super weird elaborator bug: removing the --- omitted assumption from the variable line breaks the lemma -omit [(x : B) → Zero (E x)] [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in -lemma apply_section_eventuallyEq - {x : B} (hx : x ∈ e.baseSet) (σ : Π x, E x) : - e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ ⟨x, (e (σ x)).2⟩ := by - filter_upwards [e.baseSet_mem_nhds hx] with y hy - ext - · exact coe_coe_fst e hy - · simp - -end - -end trivilization_topology - -section topological_vector_bundle - -section -variable {R B F : Type*} {E : B → Type*} [Semiring R] - [TopologicalSpace F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] - (e : Trivialization F (π F E)) - [AddCommMonoid F] [Module R F] [(x : B) → AddCommMonoid (E x)] [(x : B) → Module R (E x)] - -lemma map_smul [Trivialization.IsLinear R e] - {b : B} (hb : b ∈ e.baseSet) (a : R) (v : E b) : - (e ⟨b, a • v⟩).2 = a • (e ⟨b, v⟩).2 := - e.linear R hb |>.map_smul a v - -variable (R) - -lemma map_add [Trivialization.IsLinear R e] - {b : B} (hb : b ∈ e.baseSet) (v v' : E b) : - (e ⟨b, v + v'⟩).2 = (e ⟨b, v⟩).2 + (e ⟨b, v'⟩).2 := - e.linear R hb |>.map_add v v' - -end - -section - -variable (R : Type*) {B F : Type*} {E : B → Type*} - [NontriviallyNormedField R] [(x : B) → AddCommMonoid (E x)] - [(x : B) → Module R (E x)] [NormedAddCommGroup F] - [NormedSpace R F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] - [(x : B) → TopologicalSpace (E x)] - [FiberBundle F E] (e : Trivialization F (π F E)) - -lemma symm_map_add [Trivialization.IsLinear R e] {x : B} - (f f' : F) : - e.symm x (f + f') = e.symm x f + e.symm x f' := - (symmL R e x).map_add f f' - -@[simp] -lemma symm_map_zero [Trivialization.IsLinear R e] {x : B} : - e.symm x 0 = 0 := - (symmL R e x).map_zero - -variable {R} - -lemma symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : - e.symm x (a • f) = a • e.symm x f := - (symmL R e x).map_smul a f - -end - -end topological_vector_bundle - -section to_trivialization -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] - -- `F` model fiber - (n : WithTop ℕ∞) - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] - -variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] - -lemma mdifferentiableAt - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {x : M} (hx : x ∈ e.baseSet) (v : V x) : -MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := by - have : ⟨x, v⟩ ∈ e.source := (coe_mem_source e).mpr hx - have foo := e.contMDiffOn (IB := I) (n := 1) v this - have := foo.contMDiffAt (e.open_source.mem_nhds this) - exact this.mdifferentiableAt zero_ne_one.symm - -lemma mdifferentiableAt_invFun - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {x : M} (hx : x ∈ e.baseSet) (f : F) : - MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (x, f) := by - have : ⟨x, f⟩ ∈ e.target := (mk_mem_target e).mpr hx - have foo := e.contMDiffOn_symm (IB := I) (n := 1) _ this - have := foo.contMDiffAt (e.open_target.mem_nhds this) - exact this.mdifferentiableAt zero_ne_one.symm - --- Note: The definition below (ab)uses definitional --- equality of `TangentSpace (I.prod 𝓘(ℝ, F)) (↑t v)` --- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` --- which is $T_{π(v)} M × F$. -variable (I) in -noncomputable -def deriv (v : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] TangentSpace I v.proj × F := - mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v - -variable (I) in -noncomputable -def derivInv (v : TotalSpace F V) : - TangentSpace I v.proj × F →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, F)) v := - mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e.invFun (e v) - -set_option backward.isDefEq.respectTransparency false in -@[simp] -lemma derivInv_deriv - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - (e.derivInv I v) ∘L (e.deriv I v) = .id ℝ _ := by - have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 - have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 - rw [mk_proj_snd' e hv] at D₁ - have comp := mfderiv_comp v D₁ D₂ - rw [(invFun_comp_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp - simp [deriv, derivInv, comp] - -@[simp] -lemma derivInv_deriv_apply - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) - (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : - (e.derivInv I v (e.deriv I v u)) = u := - show ((e.derivInv I v) ∘L (e.deriv I v)) u = u by simp [hv] - -@[simp] -lemma mfderiv_proj_fst_deriv - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) - (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : - mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v u = (e.deriv I v u).1 := by - have := e.fst_comp_eventuallyEq hv - rw [← this.mfderiv_eq, mfderiv_comp v mdifferentiableAt_fst (e.mdifferentiableAt (I := I) hv v.2)] - simp - rfl -- TODO: understand why `simp` does not handle `ContinuousLinearMap.fst` - -set_option backward.isDefEq.respectTransparency false in -@[simp] -lemma mfderiv_proj_derivInv_apply - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) - (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : - mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v (e.derivInv I v u) = u.1 := by - have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 - rw [mk_proj_snd' e hv] at D₁ - have diff : MDifferentiableAt (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v := - mdifferentiableAt_proj _ - have eq : e.invFun (e v) = v := by - simp [symm_apply_apply e ((mem_source e).mpr hv)] - rw [← eq] at diff - have := mfderiv_comp (e v) diff D₁ - have C : (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by - filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ - exact symm_coe_proj e hx - rw [C.mfderiv_eq, eq] at this - have := congr($this u).symm - change mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v _ = _ at this - -- Why all this pain?? - convert this - ext x - simp - rfl - -set_option backward.isDefEq.respectTransparency false in -@[simp] -lemma deriv_derivInv - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - (e.deriv I v) ∘L (e.derivInv I v) = .id ℝ _ := by - have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 - rw [mk_proj_snd' e hv] at D₁ - have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 - have : e.invFun (e v) = v := by - simp [symm_apply_apply e ((mem_source e).mpr hv)] - rw [← this] at D₂ - have comp := mfderiv_comp (e v) D₂ D₁ - rw [(comp_invFun_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp - symm - convert comp <;> rw [this] - -@[simp] -lemma deriv_derivInv_apply - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) - (u : TangentSpace I v.proj × F) : - e.deriv I v (e.derivInv I v u) = u := - show ((e.deriv I v) ∘L (e.derivInv I v)) u = u by simp [hv] - -lemma bijective_deriv - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Function.Bijective (e.deriv I v) := by - refine Function.bijective_iff_has_inverse.mpr ?_ - use e.derivInv I v - constructor - all_goals { intro u; simp [hv] } - -lemma mdifferentiableAt_section_of_function - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {x : M} (hx : x ∈ e.baseSet) {s : M → F} - (hs : MDiffAt s x) : - MDiffAt ((fun x' ↦ (⟨x', e.symm x' (s x')⟩ : TotalSpace F V))) x := by - rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] - have := e.apply_symm_eventuallyEq hx s - exact hs.congr_of_eventuallyEq this - -noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := - (mfderiv (I.prod 𝓘(ℝ, F)) I Bundle.TotalSpace.proj v).ker - -lemma comap_vert - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : - Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap - (Submodule.prod ⊥ ⊤) := by - ext x - have : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := e.fst_comp_eventuallyEq hv - unfold vert - rw [← this.mfderiv_eq] - have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e v := - e.mdifferentiableAt hv _ - rw [mfderiv_comp v mdifferentiableAt_fst mdiffe] - simp - rfl - -lemma mfderiv_comp_section - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) - (u : TangentSpace I x) (hx : x ∈ e.baseSet) : - letI s := fun x ↦ (e (σ x)).2 - (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv I 𝓘(ℝ, F) s x u) := by - have mdiffe : MDifferentiableAt (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) e (σ x) := - e.mdifferentiableAt hx _ - have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x = - (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := - mfderiv_comp x mdiffe hσ - have : mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = - e.deriv I (σ x) ((mfderiv% T%σ x) u) := by - rw [this] - rfl - erw [← this] - let s := fun x ↦ (e (σ x)).2 - change mfderiv I (I.prod 𝓘(ℝ, F)) (e ∘ T%σ) x u = (u, mfderiv% s x u) - rw [(e.apply_section_eventuallyEq hx _).mfderiv_eq] - erw [mfderiv_prodMk, mfderiv_id] - · change (ContinuousLinearMap.id _ _).prod (mfderiv% s x) u = _ - simp - · apply mdifferentiableAt_id - · exact (mdifferentiableAt_section_iff I e σ hx).mp hσ - -@[simp] -lemma _root_.mdifferentiableAt_section_trivial_iff {s : M → F} {x : M} : - MDiffAt (T% s) x ↔ MDiffAt s x := by - rw [mdifferentiableAt_section I] - simp - -end to_trivialization - -end Bundle.Trivialization - section linear_algebra_isCompl lemma LinearMap.comap_isCompl {R R₂ M M₂ : Type*} [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] @@ -1006,4 +603,4 @@ lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} · simp · simp -end linear_algebra_isCompl +end linear_algebra_isCompl diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean new file mode 100644 index 00000000000000..7f9f4e3f373974 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -0,0 +1,579 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary + +/-! +# Supporting lemmas for CovariantDerivative.Basic trivialization stuff + +TODO: PR all this to appropriate places. + +-/ + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +@[expose] public section + +section delaborators + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` +open Lean PrettyPrinter Delaborator SubExpr + +@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do + whenPPOption getPPNotation do + let args := (← getExpr).getAppArgs + if args.size < 22 then failure + let pt : Term ← withNaryArg 21 <| delab + let f := args[20]! + try + if let .lam _ _ b _ := f then + if b.isAppOf ``Bundle.TotalSpace.mk' then + let s := b.getAppArgs[4]!.getAppFn + if s matches .fvar .. then + let ss ← PrettyPrinter.delab s + return ← `(MDiffAt (T% $ss) $pt) + throwError "nope" + catch _ => + let x : Term ← withNaryArg 20 <| delab + return ← `(MDiffAt $x $pt) + +end delaborators + +namespace Bundle.Trivialization + +section trivilization_topology + +variable {B F Z : Type*} [TopologicalSpace B] + [TopologicalSpace F] + +section any_proj + +variable [TopologicalSpace Z] {proj : Z → B} (e : Trivialization F proj) +lemma baseSet_mem_nhds {x : B} (hx : x ∈ e.baseSet) : e.baseSet ∈ 𝓝 x := + e.open_baseSet.mem_nhds_iff.mpr hx + +lemma baseSet_prod_univ_mem_nhds {v : Z} + (hv : proj v ∈ e.baseSet) : e.baseSet ×ˢ univ ∈ 𝓝 (e v) := by + rw [← e.mk_proj_snd' hv] + exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem + +lemma comp_invFun_eventuallyEq + {v : Z} (hv : proj v ∈ e.baseSet) : e ∘ e.invFun =ᶠ[𝓝 (e v)] id := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp + simp [(e.mem_target).2 hp.1] + +end any_proj + +section fiber_bundle +variable {E : B → Type*} [TopologicalSpace (TotalSpace F E)] + (e : Trivialization F (π F E)) + +lemma proj_invFun_eventuallyEq + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ + simp [hx] + +lemma injective_symm [(x : B) → Zero (E x)] + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Function.Injective (e.symm v.proj) := by + intro f f' hff' + simpa [hv] using congr(e $hff') + +lemma surjective_symm [(x : B) → Zero (E x)] + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Function.Surjective (e.symm v.proj) := + fun u ↦ ⟨(e u).2, by simp [hv]⟩ + +lemma bijective_symm [(x : B) → Zero (E x)] + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Function.Bijective (e.symm v.proj) := + ⟨e.injective_symm hv, e.surjective_symm hv⟩ + +/-- Turn sections of a fiber bundle into function into the model fiber using a trivialization. -/ +def secToFun (σ : (b : B) → E b) : B → F := + fun b ↦ e (σ b) |>.2 + +lemma secToFun_congr {σ σ' : (b : B) → E b} {b : B} (h : σ b = σ' b) : + e.secToFun σ b = e.secToFun σ' b := by + simp [secToFun, h] + +-- @[congr] +-- lemma secToFun_congr {σ σ' : (b : B) → E b} {b : B} (h : ∀ x, x = b → σ x = σ' x) : +-- e.secToFun σ b = e.secToFun σ' b := by +-- simp [secToFun, h] +-- +-- example {σ σ' : (b : B) → E b} {b : B} (h : ∀ x, x = b → σ x = σ' x) : +-- e.secToFun σ b = e.secToFun σ' b := by +-- simp? +contextual [h] +section +variable [(x : B) → Zero (E x)] + +/-- Turn functions into the model fiber of a fiber bundle into sections using a trivialization. -/ +noncomputable def funToSec (s : B → F) : (b : B) → E b := + fun b ↦ e.symm b (s b) + +lemma funToSec_congr {s s' : B → F} {b : B} (h : s b = s' b) : + e.funToSec s b = e.funToSec s' b := by + simp [funToSec, h] + +lemma totalSpace_mk'_funToSec {v : TotalSpace F E} (s : B → F) : + (T% (e.funToSec s) v.proj) = e.symm v.proj (s v.proj) := + rfl + +@[simp] +lemma secToFun_funToSec_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + e.secToFun (e.funToSec s) =ᶠ[𝓝 x] s := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma secToFun_funToSec {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + e.secToFun (e.funToSec s) x = s x := + (e.secToFun_funToSec_eventuallyEq hx s).eq_of_nhds + -- TODO: understand why the following fails + -- by + -- have := e.secToFun_funToSec_eventuallyEq hx s + -- apply? + +@[simp] +lemma funToSec_secToFun_eventually_eq {x : B} (hx : x ∈ e.baseSet) (σ : (b : B) → E b) : + ∀ᶠ x' in 𝓝 x, e.funToSec (e.secToFun σ) x' = σ x' := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma funToSec_secToFun {x : B} (hx : x ∈ e.baseSet) (σ : (b : B) → E b) : + e.funToSec (e.secToFun σ) x = σ x := + (e.funToSec_secToFun_eventually_eq hx σ).self_of_nhds + +section +variable (σ : (b : B) → E b) [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] + +set_option linter.unusedSectionVars false in +@[simp] +lemma total_funToSec_secToFun_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (σ : (b : B) → E b) : + T% (e.funToSec <| e.secToFun σ) =ᶠ[𝓝 x] T% σ := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma total_funToSec_secToFun_eq {x : B} (hx : x ∈ e.baseSet) (σ : (b : B) → E b) : + T% (e.funToSec <| e.secToFun σ) x = T% σ x := + e.total_funToSec_secToFun_eventuallyEq hx σ |>.self_of_nhds + +end + +@[simp] +lemma total_secToFun_funToSeq_eventually_eq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + ∀ᶠ x' in 𝓝 x, T% (e.secToFun <| e.funToSec s) x' = T% s x' := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma total_secToFun_funToSeq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + T% (e.secToFun <| e.funToSec s) x = T% s x := + e.total_secToFun_funToSeq_eventually_eq hx s |>.self_of_nhds + +end + +variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] + +lemma preimage_baseSet_mem_nhds + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + TotalSpace.proj ⁻¹' e.baseSet ∈ 𝓝 v := + FiberBundle.continuous_proj F E |>.continuousAt <| e.baseSet_mem_nhds hv + +lemma fst_comp_eventuallyEq + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + Prod.fst ∘ e =ᶠ[𝓝 v] (π F E) := by + filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using e.coe_fst' hy + +lemma invFun_comp_eventuallyEq + {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : + e.invFun ∘ e =ᶠ[𝓝 v] id := by + filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw + simp [e.mem_source.mpr hw] + +end fiber_bundle + +section +variable {B F : Type*} {E : B → Type*} [TopologicalSpace B] + [TopologicalSpace F] [TopologicalSpace (TotalSpace F E)] + [(x : B) → Zero (E x)] + (e : Trivialization F (π F E)) + +lemma eq_of {x : B} {v v' : E x} (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v').2) : + v = v' := by + have := e.symm_proj_apply v hx + rw [hvv'] at this + grind [e.symm_proj_apply v' hx] + +variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] + + +-- FIXME super weird elaborator bug: removing the +-- omitted assumption from the variable line breaks the lemma +set_option linter.unusedSectionVars false in +lemma apply_total_eventuallyEq + {x : B} (hx : x ∈ e.baseSet) (σ : Π x, E x) : + e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ (x, e.secToFun σ x) := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + ext + · exact e.coe_coe_fst hy + · simp [secToFun] + +end + +end trivilization_topology + +section topological_vector_bundle + +section +variable {R B F : Type*} {E : B → Type*} [Semiring R] + [TopologicalSpace F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + (e : Trivialization F (π F E)) + [AddCommMonoid F] [Module R F] [(x : B) → AddCommMonoid (E x)] [(x : B) → Module R (E x)] + +lemma map_smul [Trivialization.IsLinear R e] + {b : B} (hb : b ∈ e.baseSet) (a : R) (v : E b) : + (e ⟨b, a • v⟩).2 = a • (e ⟨b, v⟩).2 := + e.linear R hb |>.map_smul a v + +lemma secToFun_map_smul [Trivialization.IsLinear R e] {σ : (b : B) → E b} + {b : B} (hb : b ∈ e.baseSet) (a : R) : + e.secToFun (a • σ) b = a • e.secToFun σ b := by + simp [secToFun, e.map_smul hb] + +variable (R) + +lemma map_add [Trivialization.IsLinear R e] + {b : B} (hb : b ∈ e.baseSet) (v v' : E b) : + (e ⟨b, v + v'⟩).2 = (e ⟨b, v⟩).2 + (e ⟨b, v'⟩).2 := + e.linear R hb |>.map_add v v' + +lemma secToFun_map_add [Trivialization.IsLinear R e] (σ σ' : (b : B) → E b) + {b : B} (hb : b ∈ e.baseSet) : + e.secToFun (σ + σ') b = e.secToFun σ b + e.secToFun σ' b := by + simp [secToFun, e.map_add R hb] + +lemma map_zero [Trivialization.IsLinear R e] + {b : B} (hb : b ∈ e.baseSet) : + (e ⟨b, 0⟩).2 = 0 := + e.linear R hb |>.map_zero + +lemma secToFun_map_zero [Trivialization.IsLinear R e] {b : B} (hb : b ∈ e.baseSet) : + e.secToFun 0 b = 0 := by + simp [secToFun, e.map_zero R hb] +end + +section + +variable (R : Type*) {B F : Type*} {E : B → Type*} + [NontriviallyNormedField R] [(x : B) → AddCommMonoid (E x)] + [(x : B) → Module R (E x)] [NormedAddCommGroup F] + [NormedSpace R F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + [(x : B) → TopologicalSpace (E x)] + [FiberBundle F E] (e : Trivialization F (π F E)) + +lemma symm_map_add [Trivialization.IsLinear R e] {x : B} + (f f' : F) : + e.symm x (f + f') = e.symm x f + e.symm x f' := + (e.symmL R x).map_add f f' + +lemma funToSec_map_add [Trivialization.IsLinear R e] {s s' : B → F} : + e.funToSec (s + s') = e.funToSec s + e.funToSec s' := by + ext b + simp [funToSec, e.symm_map_add R] + +@[simp] +lemma symm_map_zero [Trivialization.IsLinear R e] {x : B} : + e.symm x 0 = 0 := + (e.symmL R x).map_zero + +@[simp] +lemma funToSec_map_zero [Trivialization.IsLinear R e] : + e.funToSec (0 : B → F) = 0 := by + ext b + simp [funToSec, e.symm_map_zero R] + +variable {R} + +lemma symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : + e.symm x (a • f) = a • e.symm x f := + (e.symmL R x).map_smul a f + +lemma funToSec_map_smul [Trivialization.IsLinear R e] (a : R) (s : B → F) : + e.funToSec (a • s) = a • e.funToSec s := by + ext b + simp [funToSec, e.symm_map_smul] + +end + +end topological_vector_bundle + +section to_trivialization +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] + +variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] + +lemma mdifferentiableAt + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) (v : V x) : + MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e v := by + have : ⟨x, v⟩ ∈ e.source := e.coe_mem_source.mpr hx + have foo := e.contMDiffOn (IB := I) (n := 1) v this + have := foo.contMDiffAt (e.open_source.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +lemma mdifferentiableAt_invFun + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) (f : F) : + MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e.invFun (x, f) := by + have : ⟨x, f⟩ ∈ e.target := e.mk_mem_target.mpr hx + have foo := e.contMDiffOn_symm (IB := I) (n := 1) _ this + have := foo.contMDiffAt (e.open_target.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +-- Note: The definition below (ab)uses definitional +-- equality of `TangentSpace (I.prod 𝓘(𝕜, F)) (↑t v)` +-- which is $T_{t(v)} (M × F)$ and `TM v.proj × F` +-- which is $T_{π(v)} M × F$. +variable (I) in +noncomputable +def deriv (v : TotalSpace F V) : + TangentSpace (I.prod 𝓘(𝕜, F)) v →L[𝕜] TangentSpace I v.proj × F := + mfderiv (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e v + +variable (I) in +noncomputable +def derivInv (v : TotalSpace F V) : + TangentSpace I v.proj × F →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) v := + mfderiv (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e.invFun (e v) + + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma derivInv_deriv + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + (e.derivInv I v) ∘L (e.deriv I v) = .id 𝕜 _ := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + have D1' := D₁ + simp only [PartialEquiv.invFun_as_coe, OpenPartialHomeomorph.coe_coe_symm] at D1' + rw [e.mk_proj_snd' hv] at D₁ + have comp := mfderiv_comp v D₁ D₂ + rw [(invFun_comp_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp + simp [deriv, derivInv, comp] + +@[simp] +lemma derivInv_deriv_apply + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace (I.prod 𝓘(𝕜, F)) v) : + (e.derivInv I v (e.deriv I v u)) = u := + show ((e.derivInv I v) ∘L (e.deriv I v)) u = u by simp [hv] + +@[simp] +lemma mfderiv_proj_fst_deriv + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace (I.prod 𝓘(𝕜, F)) v) : + mfderiv (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v u = (e.deriv I v u).1 := by + have := e.fst_comp_eventuallyEq hv + rw [← this.mfderiv_eq, mfderiv_comp v mdifferentiableAt_fst (e.mdifferentiableAt (I := I) hv v.2)] + simp + rfl -- TODO: understand why `simp` does not handle `ContinuousLinearMap.fst` + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma mfderiv_proj_derivInv_apply + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace (I.prod 𝓘(𝕜, F)) v) : + mfderiv (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v (e.derivInv I v u) = u.1 := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [e.mk_proj_snd' hv] at D₁ + have diff : MDifferentiableAt (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v := + mdifferentiableAt_proj _ + have eq : e.invFun (e v) = v := by simp [e.mem_source.mpr hv] + rw [← eq] at diff + have := mfderiv_comp (e v) diff D₁ + have C : (TotalSpace.proj ∘ e.invFun) =ᶠ[𝓝 (e v)] Prod.fst := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with ⟨x, f⟩ ⟨hx, hf⟩ + simp [hx] + rw [C.mfderiv_eq, eq] at this + have := congr($this u).symm + change mfderiv (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v _ = _ at this + -- Why all this pain?? + convert this + ext x + simp + rfl + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma deriv_derivInv + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + (e.deriv I v) ∘L (e.derivInv I v) = .id 𝕜 _ := by + have D₁ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [e.mk_proj_snd' hv] at D₁ + have D₂ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + have : e.invFun (e v) = v := by simp [e.mem_source.mpr hv] + rw [← this] at D₂ + have comp := mfderiv_comp (e v) D₂ D₁ + rw [(comp_invFun_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp + symm + convert comp <;> rw [this] + +@[simp] +lemma deriv_derivInv_apply + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) + (u : TangentSpace I v.proj × F) : + e.deriv I v (e.derivInv I v u) = u := + show ((e.deriv I v) ∘L (e.derivInv I v)) u = u by simp [hv] + +lemma bijective_deriv + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Function.Bijective (e.deriv I v) := by + refine Function.bijective_iff_has_inverse.mpr ?_ + use e.derivInv I v + constructor + all_goals { intro u; simp [hv] } + +lemma mdifferentiableAt_funToSec + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) {s : M → F} + (hs : MDiffAt s x) : + MDiffAt (T% (e.funToSec s)) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] + change MDiffAt (e.secToFun <| e.funToSec s) x + have := e.secToFun_funToSec_eventuallyEq hx s + exact hs.congr_of_eventuallyEq this + +lemma mdifferentiableAt_secToFun + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) {σ : (x : M) → V x} + (hσ : MDiffAt (T% σ) x) : + MDiffAt (e.secToFun σ) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] at hσ + exact hσ + +omit [MemTrivializationAtlas e] [(x : M) → Module 𝕜 (V x)] in +@[simp] +lemma mdifferentiableAt_total_funToSec_secToFun + {x : M} (hx : x ∈ e.baseSet) {σ : (x : M) → V x} : + MDiffAt (T% (e.funToSec <| e.secToFun σ)) x ↔ MDiffAt (T%σ) x := by + rw [e.total_funToSec_secToFun_eventuallyEq hx σ |>.mdifferentiableAt_iff] + +omit [(x : M) → Module 𝕜 (V x)] [(x : M) → TopologicalSpace (V x)] + [FiberBundle F V] [MemTrivializationAtlas e] in +@[simp] +lemma mdifferentiableAt_secToFun_funToSec + {x : M} (hx : x ∈ e.baseSet) {s : M → F} : + MDiffAt (e.secToFun <| e.funToSec s) x ↔ MDiffAt s x := + e.secToFun_funToSec_eventuallyEq hx s |>.mdifferentiableAt_iff + +lemma mfderiv_total_funToSec_fst_deriv {s : M → F} + (v : TotalSpace F V) (w : TangentSpace (I.prod 𝓘(𝕜, F)) v) : + mfderiv% (T% (e.funToSec s)) v.proj (e.deriv I v w).1 = w := by + sorry + +noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : + Submodule 𝕜 (TangentSpace (I.prod 𝓘(𝕜, F)) v) := + (mfderiv (I.prod 𝓘(𝕜, F)) I Bundle.TotalSpace.proj v).ker + +lemma comap_vert + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj ∈ e.baseSet) : + Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap + (Submodule.prod ⊥ ⊤) := by + ext x + have : Prod.fst ∘ e =ᶠ[𝓝 v] TotalSpace.proj := e.fst_comp_eventuallyEq hv + unfold vert + rw [← this.mfderiv_eq] + have mdiffe : MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e v := + e.mdifferentiableAt hv _ + rw [mfderiv_comp v mdifferentiableAt_fst mdiffe] + simp + rfl + +lemma mfderiv_comp_section + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) + (u : TangentSpace I x) (hx : x ∈ e.baseSet) : + (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv% (e.secToFun σ) x u) := by + have mdiffe : MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e (σ x) := + e.mdifferentiableAt hx _ + have : mfderiv% (e ∘ T%σ) x = (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := + mfderiv_comp x mdiffe hσ + have : mfderiv% (e ∘ T%σ) x u = e.deriv I (σ x) ((mfderiv% T%σ x) u) := by + rw [this] + rfl + erw [← this] + rw [(e.apply_total_eventuallyEq hx _).mfderiv_eq] + erw [mfderiv_prodMk, mfderiv_id] + · -- TODO make sure the `change` below isn’t needed. + -- Uncommenting the next lines is meant to help understanding the issue. + -- have : ((ContinuousLinearMap.id 𝕜 (TangentSpace I x)).prod + -- (mfderiv I 𝓘(𝕜, F) (e.secToFun σ) x)) u = + -- (u, (mfderiv I 𝓘(𝕜, F) (e.secToFun σ) x) u) := sorry + -- with_reducible exact this + change (ContinuousLinearMap.id _ _).prod _ _ = _ + simp + · apply mdifferentiableAt_id + · exact (e.mdifferentiableAt_section_iff I σ hx).mp hσ + +@[simp] +lemma _root_.mdifferentiableAt_total_trivial_iff {s : M → F} {x : M} : + MDiffAt (T% s) x ↔ MDiffAt s x := by + rw [mdifferentiableAt_section I] + simp + +@[simp] +lemma _root_.mdifferentiableAt_section_trivial_iff {σ : (x : M) → Trivial M F x} {x : M} : + MDiffAt (T% σ) x ↔ MDifferentiableAt I 𝓘(𝕜, F) σ x := by + rw [mdifferentiableAt_section I] + simp + +end to_trivialization + +end Bundle.Trivialization From 20a011e48a60431f9e2a80b7e97ba7a4f0f8dfb7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 13:57:48 +0000 Subject: [PATCH 460/601] chore: split out Extend --- Mathlib.lean | 2 + .../CovariantDerivative/Prelim.lean | 89 +------------- .../Manifold/VectorBundle/Extend.lean | 109 ++++++++++++++++++ 3 files changed, 112 insertions(+), 88 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Extend.lean diff --git a/Mathlib.lean b/Mathlib.lean index 92156ce96df213..4107173f89fed1 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4411,6 +4411,8 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCiv public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim +public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho public import Mathlib.Geometry.Manifold.VectorBundle.Hom diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 6a1743e902c460..e1ca0719ae91f3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -5,6 +5,7 @@ Authors: Patrick Massot, Michael Rothgang -/ module +public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tangent public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv @@ -257,94 +258,6 @@ end end general_lemmas -section extend -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] - -- `F` model fiber - (n : WithTop ℕ∞) - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] - -- `V` vector bundle - --- TODO: either change `localFrame` to make sure it is everywhere smooth --- or introduce a cut-off here. First option is probaly better. --- TODO: comment why we chose the second option in the end, and adapt the definition accordingly --- new definition: smooth a bump function, then smul with localExtensionOn -/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. -The details of the extension are mostly unspecified: for covariant derivatives, the value of -`s` at points other than `x` will not matter (except for shorter proofs). -Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. --/ -noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - (x' : M) → V x' := - letI b := Basis.ofVectorSpace ℝ F - letI t := trivializationAt F V x - -- Choose a smooth bump function ψ near `x`, supported within t.baseSet - -- and return ψ • V₀ instead. - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - ψ.toFun • localExtensionOn b t v - -variable {I F} - --- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for --- *well-chosen* extensions (such as ours). --- so, one may argue this is mathematically wrong, but it encodes the "choice some extension --- with this and that property" nicely --- a different proof would be to argue only the value at a point matters for cov -@[simp] -lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : - extend I F (v + v') = extend I F v + extend I F v' := by - simp [extend] - -@[simp] -lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : - extend I F (a • v) = a • extend I F v := by simp [extend]; module - -@[simp] -lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : - extend I F (0 : V x) = 0 := by simp [extend] - -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - extend I F v x = v := by - simpa [extend] using - localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v - -variable (I F) - -lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - CMDiff ∞ (T% (extend I F σ₀)) := by - letI t := trivializationAt F V x - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - let hψ := - Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - exact ContMDiffOn.smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 - (contMDiffOn_localExtensionOn _ hx _) - -lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDiff (T% (extend I F σ₀)) := - contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) - -theorem contDiff_extend - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] - (x : E) (y : E') : ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by - rw [contDiff_iff_contDiffAt] - intro x' - rw [← contMDiffAt_iff_contDiffAt] - simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' - -end extend - section tensoriality variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean new file mode 100644 index 00000000000000..8be3307cbe1d65 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -0,0 +1,109 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.MFDeriv.Defs +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame + +/-! +# Extending an element of a vector bundle to a smooth section + +-/ + +public section + +open Bundle Filter Module Topology Set +open scoped Manifold ContDiff + +section extend +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] + -- `V` vector bundle + +-- TODO: either change `localFrame` to make sure it is everywhere smooth +-- or introduce a cut-off here. First option is probaly better. +-- TODO: comment why we chose the second option in the end, and adapt the definition accordingly +-- new definition: smooth a bump function, then smul with localExtensionOn +/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ +noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + (x' : M) → V x' := + letI b := Basis.ofVectorSpace ℝ F + letI t := trivializationAt F V x + -- Choose a smooth bump function ψ near `x`, supported within t.baseSet + -- and return ψ • V₀ instead. + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + ψ.toFun • localExtensionOn b t v + +variable {I F} + +-- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for +-- *well-chosen* extensions (such as ours). +-- so, one may argue this is mathematically wrong, but it encodes the "choice some extension +-- with this and that property" nicely +-- a different proof would be to argue only the value at a point matters for cov +@[simp] +lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : + extend I F (v + v') = extend I F v + extend I F v' := by + simp [extend] + +@[simp] +lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : + extend I F (a • v) = a • extend I F v := by simp [extend]; module + +@[simp] +lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : + extend I F (0 : V x) = 0 := by simp [extend] + +@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : + extend I F v x = v := by + simpa [extend] using + localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v + +variable (I F) + +lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + CMDiff ∞ (T% (extend I F σ₀)) := by + letI t := trivializationAt F V x + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + let hψ := + Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + exact ContMDiffOn.smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 + (contMDiffOn_localExtensionOn _ hx _) + +lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : + MDiff (T% (extend I F σ₀)) := + contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) + +theorem contDiff_extend + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] + (x : E) (y : E') : ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by + rw [contDiff_iff_contDiffAt] + intro x' + rw [← contMDiffAt_iff_contDiffAt] + simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' + +end extend From 5b94048dddb3e81619d7246ec7f7d9ee5a64bbc5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:00:13 +0000 Subject: [PATCH 461/601] chore: move tensor definitions to tensoriality --- .../CovariantDerivative/Prelim.lean | 222 ----------------- .../Manifold/VectorBundle/Tensoriality.lean | 232 +++++++++++++++++- 2 files changed, 227 insertions(+), 227 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index e1ca0719ae91f3..f032d610c28a8d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -258,228 +258,6 @@ end end general_lemmas -section tensoriality - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] - (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [T2Space M] [ChartedSpace H M] [IsManifold I ∞ M] - -variable - (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] [FiniteDimensional ℝ F] - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] - -- TODO can probably remove the next two hypotheses, by transport - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - -variable - (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] - {V' : M → Type*} [TopologicalSpace (TotalSpace F' V')] [(x : M) → AddCommGroup (V' x)] - [(x : M) → Module ℝ (V' x)] [(x : M) → TopologicalSpace (V' x)] - -- TODO can probably remove the next two hypotheses, by transport - [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] - [FiberBundle F' V'] [VectorBundle ℝ F' V'] - -noncomputable def mkTensorAt - -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x, V' x)) (x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') x = φ σ x + φ σ' x) : - V x →L[ℝ] V' x := - let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional - LinearMap.toContinuousLinearMap { - toFun v := φ (_root_.extend I F v) x - map_add' v₁ v₂ := by - rw [← φ_add] - · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add - · exact mdifferentiable_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · simp - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - map_smul' c v := by - dsimp - rw [← φ_smul (fun _ ↦ c)] - · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add - · exact mdifferentiable_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiable_extend .. - · simp - · exact mdifferentiable_const .. - · exact mdifferentiable_extend .. } - -variable {I} in -theorem mkTensorAt_apply - -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x, V' x)} {x} - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') x = φ σ x + φ σ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : - mkTensorAt I F F' φ x φ_smul φ_add (σ x) = φ σ x := by - apply tensoriality_criterion I F _ F' _ _ hσ _ φ_smul φ_add - · exact mdifferentiable_extend .. - · simp - -noncomputable def mkTensor - -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x, V' x)) - -- TODO could weaken `φ_smul` and `φ_add` to require the property only globally, is it useful? - (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) - (x : M) : - V x →L[ℝ] V' x := - mkTensorAt I F F' φ x (φ_smul x) (φ_add x) - -theorem contMDiff_mkTensor - (φ : (Π x : M, V x) → (Π x, V' x)) - (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) - -- hopefully this is the correct smoothness criterion! - {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : - -- elaborators not working here - let T (x : M) : TotalSpace (F →L[ℝ] F') (fun x ↦ V x →L[ℝ] V' x) := - ⟨x, mkTensor I F F' φ φ_smul φ_add x⟩ - ContMDiff I (I.prod 𝓘(ℝ, F →L[ℝ] F')) k T := by - sorry - --- TODO allow the two input types to differ -noncomputable def mk2TensorAt - -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : - V x →L[ℝ] V x →L[ℝ] V' x := - let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional - have H : IsBilinearMap ℝ - (fun (v w : V x) ↦ φ (_root_.extend I F v) (_root_.extend I F w) x) := - { add_left v₁ v₂ w := by - rw [← σ_add] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · simp - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - smul_left c v w := by - rw [← σ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · simp - · exact mdifferentiable_const .. - · exact mdifferentiable_extend .. - add_right v w₁ w₂ := by - rw [← τ_add] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · simp - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - smul_right c v w := by - rw [← τ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiable_extend .. - · simp - · exact mdifferentiable_const .. - · exact mdifferentiable_extend .. } - H.toContinuousLinearMap - -variable {I} in -theorem mk2TensorAt_apply - -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) - {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : - mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by - apply tensoriality_criterion₂ I F _ F' _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · simp - · simp - -theorem mk2TensorAt_add - (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (φ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (φ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (φ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (φ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) - (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) - (ψ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → - ψ (f • σ) τ x = f x • ψ σ τ x) - (ψ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → - ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) - (ψ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → - ψ σ (f • τ) x = f x • ψ σ τ x) - (ψ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → - ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : - mk2TensorAt I F F' (φ + ψ) - (fun {_ _ τ} hf hσ ↦ - (congr($(φ_σ_smul hf hσ (τ := τ)) + $(ψ_σ_smul hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) - (fun {σ₁ σ₂} τ hσ₁ hσ₂ ↦ - (congr($(φ_σ_add hσ₁ hσ₂ (τ := τ)) + $(ψ_σ_add hσ₁ hσ₂ (τ := τ)))).trans <| by - dsimp - abel) - (fun {_ σ _} hf hτ ↦ - (congr($(φ_τ_smul hf hτ (σ := σ)) + $(ψ_τ_smul hf hτ (σ := σ)))).trans (smul_add _ _ _).symm) - (fun σ {τ₁ τ₂} hτ₁ hτ₂ ↦ - (congr($(φ_τ_add hτ₁ hτ₂ (σ := σ)) + $(ψ_τ_add hτ₁ hτ₂ (σ := σ)))).trans <| by - dsimp - abel) - = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add - + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by - ext - simp [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap] - -end tensoriality - section linear_algebra_isCompl lemma LinearMap.comap_isCompl {R R₂ M M₂ : Type*} [Semiring R] [AddCommMonoid M] [Module R M] [Semiring R₂] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 1724d328a05604..243d8a227f5d80 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -5,11 +5,10 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.BumpFunction -public import Mathlib.Geometry.Manifold.MFDeriv.Basic -public import Mathlib.Geometry.Manifold.Notation -public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame -public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +public import Mathlib.Geometry.Manifold.VectorBundle.Hom +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Extend +import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame /-! # The tensoriality criterion @@ -267,3 +266,226 @@ lemma tensoriality_criterion'' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteD apply b.localFrame_coeff_congr assumption -/ + + +section tensoriality + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] + (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [T2Space M] [ChartedSpace H M] [IsManifold I ∞ M] + +variable + (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] [FiniteDimensional ℝ F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [FiberBundle F V] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] + +variable + (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] + {V' : M → Type*} [TopologicalSpace (TotalSpace F' V')] [(x : M) → AddCommGroup (V' x)] + [(x : M) → Module ℝ (V' x)] [(x : M) → TopologicalSpace (V' x)] + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] + [FiberBundle F' V'] [VectorBundle ℝ F' V'] + +noncomputable def mkTensorAt + -- `φ` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x, V' x)) (x) + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') x = φ σ x + φ σ' x) : + V x →L[ℝ] V' x := + let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space + have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + LinearMap.toContinuousLinearMap { + toFun v := φ (_root_.extend I F v) x + map_add' v₁ v₂ := by + rw [← φ_add] + · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add + · exact mdifferentiable_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + map_smul' c v := by + dsimp + rw [← φ_smul (fun _ ↦ c)] + · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add + · exact mdifferentiable_extend .. + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. } + +variable {I} in +theorem mkTensorAt_apply + -- `φ` explicit to make it easier to generate the side conditions at point of use + {φ : (Π x : M, V x) → (Π x, V' x)} {x} + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') x = φ σ x + φ σ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : + mkTensorAt I F F' φ x φ_smul φ_add (σ x) = φ σ x := by + apply tensoriality_criterion I F _ F' _ _ hσ _ φ_smul φ_add + · exact mdifferentiable_extend .. + · simp + +noncomputable def mkTensor + -- `φ` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x, V' x)) + -- TODO could weaken `φ_smul` and `φ_add` to require the property only globally, is it useful? + (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) + (x : M) : + V x →L[ℝ] V' x := + mkTensorAt I F F' φ x (φ_smul x) (φ_add x) + +theorem contMDiff_mkTensor + (φ : (Π x : M, V x) → (Π x, V' x)) + (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) + -- hopefully this is the correct smoothness criterion! + {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : + -- elaborators not working here + let T (x : M) : TotalSpace (F →L[ℝ] F') (fun x ↦ V x →L[ℝ] V' x) := + ⟨x, mkTensor I F F' φ φ_smul φ_add x⟩ + ContMDiff I (I.prod 𝓘(ℝ, F →L[ℝ] F')) k T := by + sorry + +-- TODO allow the two input types to differ +noncomputable def mk2TensorAt + -- `φ` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} + (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : + V x →L[ℝ] V x →L[ℝ] V' x := + let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space + have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + have H : IsBilinearMap ℝ + (fun (v w : V x) ↦ φ (_root_.extend I F v) (_root_.extend I F w) x) := + { add_left v₁ v₂ w := by + rw [← σ_add] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + smul_left c v w := by + rw [← σ_smul (f := fun _ ↦ c)] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. + add_right v w₁ w₂ := by + rw [← τ_add] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + smul_right c v w := by + rw [← τ_smul (f := fun _ ↦ c)] + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiable_extend .. + · simp + · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. } + H.toContinuousLinearMap + +variable {I} in +theorem mk2TensorAt_apply + -- `φ` explicit to make it easier to generate the side conditions at point of use + {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : + mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by + apply tensoriality_criterion₂ I F _ F' _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add + · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. + · simp + · simp + +theorem mk2TensorAt_add + (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} + (φ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (φ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (φ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (φ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) + (ψ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + ψ (f • σ) τ x = f x • ψ σ τ x) + (ψ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) + (ψ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + ψ σ (f • τ) x = f x • ψ σ τ x) + (ψ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : + mk2TensorAt I F F' (φ + ψ) + (fun {_ _ τ} hf hσ ↦ + (congr($(φ_σ_smul hf hσ (τ := τ)) + $(ψ_σ_smul hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) + (fun {σ₁ σ₂} τ hσ₁ hσ₂ ↦ + (congr($(φ_σ_add hσ₁ hσ₂ (τ := τ)) + $(ψ_σ_add hσ₁ hσ₂ (τ := τ)))).trans <| by + dsimp + abel) + (fun {_ σ _} hf hτ ↦ + (congr($(φ_τ_smul hf hτ (σ := σ)) + $(ψ_τ_smul hf hτ (σ := σ)))).trans (smul_add _ _ _).symm) + (fun σ {τ₁ τ₂} hτ₁ hτ₂ ↦ + (congr($(φ_τ_add hτ₁ hτ₂ (σ := σ)) + $(ψ_τ_add hτ₁ hτ₂ (σ := σ)))).trans <| by + dsimp + abel) + = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add + + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by + ext + simp [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap] + +end tensoriality From feaaa2b9d0bcf182d167c1e08ed6289774fb1789 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:02:11 +0000 Subject: [PATCH 462/601] chore: move torsion lemmas using local frames to a separate file They will be refactored later anyway. --- Mathlib.lean | 1 + .../CovariantDerivative/Torsion.lean | 71 ----------- .../CovariantDerivative/Torsion2.lean | 116 ++++++++++++++++++ 3 files changed, 117 insertions(+), 71 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4107173f89fed1..2392df3075b333 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4411,6 +4411,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCiv public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 03137fcd71aed2..2e79073e37afbf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -264,75 +264,4 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ unfold IsTorsionFree torsion simp [funext_iff, sub_eq_iff_eq_add'] -variable {n} in -lemma aux1 {ι : Type*} [Fintype ι] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) - (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.coeff i) x (X x) • torsion f (s i) Y x := - have hU : U ∈ 𝓝 x := sorry - have aux := hs.eventually_eq_sum_coeff_smul X hU - have hX : X x = ∑ i, (hs.coeff i) x (X x) • s i x := sorry - calc torsion f X Y x - _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) x (X x) • s i x) Y x := by - sorry -- tensoriality and [hX] - _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) x (X x) • s i x) Y x) := sorry - _ = ∑ i, (hs.coeff i) x (X x) • (torsion f (s i) Y x) := sorry - --- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x -variable {n} in -lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} - (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) - (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.coeff i) x (Y x) • torsion f X (s i) x := - have hU : U ∈ 𝓝 x := sorry - have aux := hs.eventually_eq_sum_coeff_smul Y hU - have hY : Y x = ∑ i, (hs.coeff i) x (Y x) • s i x := hs.coeff_sum_eq Y hx - calc torsion f X Y x - _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) x (Y x) • s i x) x := by - sorry -- tensoriality and [hY] - _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) x (Y x) • s i x) x) := sorry - _ = ∑ i, (hs.coeff i) x (Y x) • (torsion f X (s i) x) := by - congr with i - have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry - have hsi' : MDiffAt (T% (s i)) x := sorry - have := hf.torsion_smul_right_apply (X := X) (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' - erw [← this] - congr - -/-- We can test torsion-freeness on a set using a local frame. -/ -lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame - {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} - (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : - IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by - rw [IsTorsionFreeOn] - refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ - intro x hx X Y - rw [aux1 hs hx] - calc - _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • torsion f (s i) (s j) x := by - congr! - rw [aux2 hf hs hx] - _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • 0 := by - congr! with i _ j _ - exact h i j x hx - _ = 0 := by simp - --- lemma the trivial connection on a normed space is torsion-free --- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry - --- lemma: tangent bundle of E is trivial -> there exists a single trivialisation with baseSet univ --- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, --- w.r.t. to this trivialisation --- add lemmas: globalFrame is contMDiff globally - --- proof of above lemma: write sections s and t in the global frame above --- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) --- compute: their Lie bracket is zero --- compute: the other two terms cancel, done - end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean new file mode 100644 index 00000000000000..aa6e6a1e6cac8e --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean @@ -0,0 +1,116 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame + +/-! +# More properties about torsion of a covariant derivative + +- might and should be refactored! +- prove: torsion-freeness on `s` can be checked using a local frame on `s` + +TODO: add a more complete doc-string + +-/ + +@[expose] public section -- TODO: think if we want to expose all definitions! + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] + {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] (n : WithTop ℕ∞) {V : M → Type*} + [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + +variable + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {X X' Y : Π x : M, TangentSpace I x} + +namespace CovariantDerivative + +variable [IsManifold I ∞ M] +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} + {U : Set M} (hf : IsCovariantDerivativeOn E cov U) + +variable {n} in +lemma aux1 {ι : Type*} [Fintype ι] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (X Y : (x : M) → TangentSpace I x) : + torsion f X Y x = ∑ i, (hs.coeff i) x (X x) • torsion f (s i) Y x := + have hU : U ∈ 𝓝 x := sorry + have aux := hs.eventually_eq_sum_coeff_smul X hU + have hX : X x = ∑ i, (hs.coeff i) x (X x) • s i x := sorry + calc torsion f X Y x + _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) x (X x) • s i x) Y x := by + sorry -- tensoriality and [hX] + _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) x (X x) • s i x) Y x) := sorry + _ = ∑ i, (hs.coeff i) x (X x) • (torsion f (s i) Y x) := sorry + +-- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x +variable {n} in +lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} + (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) + (X Y : (x : M) → TangentSpace I x) : + torsion f X Y x = ∑ i, (hs.coeff i) x (Y x) • torsion f X (s i) x := + have hU : U ∈ 𝓝 x := sorry + have aux := hs.eventually_eq_sum_coeff_smul Y hU + have hY : Y x = ∑ i, (hs.coeff i) x (Y x) • s i x := hs.coeff_sum_eq Y hx + calc torsion f X Y x + _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) x (Y x) • s i x) x := by + sorry -- tensoriality and [hY] + _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) x (Y x) • s i x) x) := sorry + _ = ∑ i, (hs.coeff i) x (Y x) • (torsion f X (s i) x) := by + congr with i + have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry + have hsi' : MDiffAt (T% (s i)) x := sorry + have := hf.torsion_smul_right_apply (X := X) (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' + erw [← this] + congr + +/-- We can test torsion-freeness on a set using a local frame. -/ +lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame + {ι : Type*} [Fintype ι] [CompleteSpace E] + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {U : Set M} {s : ι → (x : M) → TangentSpace I x} + (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : + IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by + rw [IsTorsionFreeOn] + refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ + intro x hx X Y + rw [aux1 hs hx] + calc + _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • torsion f (s i) (s j) x := by + congr! + rw [aux2 hf hs hx] + _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • 0 := by + congr! with i _ j _ + exact h i j x hx + _ = 0 := by simp + +-- lemma the trivial connection on a normed space is torsion-free +-- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry + +-- lemma: tangent bundle of E is trivial -> there exists a single trivialisation with baseSet univ +-- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, +-- w.r.t. to this trivialisation +-- add lemmas: globalFrame is contMDiff globally + +-- proof of above lemma: write sections s and t in the global frame above +-- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) +-- compute: their Lie bracket is zero +-- compute: the other two terms cancel, done + +end CovariantDerivative From 8a1fa836bbfd11fe32cacf4c20c932d5d629f1a5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:04:36 +0000 Subject: [PATCH 463/601] chore: minimise imports in (Triv)Prelim --- .../VectorBundle/CovariantDerivative/Prelim.lean | 12 ++---------- .../VectorBundle/CovariantDerivative/TrivPrelim.lean | 11 ++--------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index f032d610c28a8d..bcb3a9d9367354 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -5,18 +5,10 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.Extend -public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -public import Mathlib.Geometry.Manifold.VectorBundle.Tangent -public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -public import Mathlib.Geometry.Manifold.BumpFunction -public import Mathlib.Geometry.Manifold.Notation -public import Mathlib.Geometry.Manifold.VectorBundle.Misc -public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim +public import Mathlib.Geometry.Manifold.MFDeriv.Atlas +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! # Supporting lemmas for CovariantDerivative.Basic diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index 7f9f4e3f373974..6643c3fc711fa3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -5,16 +5,9 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -public import Mathlib.Geometry.Manifold.VectorBundle.Tangent -public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -public import Mathlib.Geometry.Manifold.BumpFunction -public import Mathlib.Geometry.Manifold.Notation -public import Mathlib.Geometry.Manifold.VectorBundle.Misc -public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.MFDeriv.Atlas +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable /-! # Supporting lemmas for CovariantDerivative.Basic trivialization stuff From d22f9af5b42db0629c80846859f25e3e99ff0840 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:17:37 +0000 Subject: [PATCH 464/601] chore: split material about Ehresmann connections part into a new file --- Mathlib.lean | 1 + .../CovariantDerivative/Basic.lean | 427 +--------------- .../CovariantDerivative/Ehresmann.lean | 473 ++++++++++++++++++ .../CovariantDerivative/Lift.lean | 5 +- .../CovariantDerivative/Prelim.lean | 5 - 5 files changed, 478 insertions(+), 433 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2392df3075b333..e74fece974dbed 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4407,6 +4407,7 @@ public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 354855e22de640..baa3d36be1a4a3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -6,16 +6,11 @@ Authors: Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -public import Mathlib.Geometry.Manifold.VectorBundle.Tangent -public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -public import Mathlib.Geometry.Manifold.BumpFunction -public import Mathlib.Geometry.Manifold.Notation -public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim /-! # Covariant derivatives @@ -25,11 +20,8 @@ TODO: add a more complete doc-string -/ open Bundle Filter Module Topology Set - open scoped Bundle Manifold ContDiff - - variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! @@ -393,7 +385,6 @@ end trivial_bundle variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -- TODO: does it make sense to speak of analytic connections? if so, change the definition of -- regularity and use ∞ from `open scoped ContDiff` instead. @@ -610,420 +601,4 @@ lemma _root_.CovariantDerivative.exists_one_form end classification -section projection_trivial_bundle - -variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] - -local notation "TM" => TangentSpace I - -variable {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} - -noncomputable -def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) × F →L[ℝ] F := - .snd ℝ (TM x) F + (hcov.one_form x f ∘L .fst ℝ (TM x) F) - -@[simp] -lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : - hcov.projection x f (v, w) = w + hcov.one_form x f v := rfl - -lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (σ : M → F) - {x : M} (X₀ : TM x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - cov σ x X₀ = hcov.projection x (σ x) (X₀, mfderiv I 𝓘(ℝ, F) σ x X₀) := by - simpa using congr($(hcov.eq_one_form hσ) X₀) - -noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : - Submodule ℝ (TM x × F) := - (hcov.projection x f).ker - -lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : - IsCompl (hcov.horiz x f) (.prod ⊥ ⊤) := by - refine IsCompl.of_eq ?_ ?_ - · refine (Submodule.eq_bot_iff _).mpr ?_ - rintro ⟨u, w⟩ ⟨huw, hu, hw⟩ - simp_all [horiz] - · apply Submodule.sup_eq_top_iff _ _ |>.2 - intro u - use u - (0, hcov.projection x f u), ?_, (0, hcov.projection x f u), ?_, ?_ - all_goals simp [horiz] - -set_option backward.isDefEq.respectTransparency false in -lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : F} - {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ - ∃ σ : M → F, MDiffAt (T% σ) x ∧ - σ x = f ∧ - mfderiv I 𝓘(ℝ, F) σ x u = v ∧ - cov σ x u = 0 := by - constructor - · intro huv - simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv - let w : TangentSpace 𝓘(ℝ, F) f := v - by_cases hu : u = 0 - · subst hu - replace huv : v = 0 := by simpa using huv - subst huv - use fun x ↦ f - simp [mdifferentiableAt_section, mdifferentiableAt_const] - rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ - use map_of_one_jet u w, ?_, h, h'' - · rw [hcov.eq_one_form] - · simp only [w, h] - convert huv - convert ContinuousLinearMap.add_apply (M₁ := TangentSpace I x) (M₂ := F) _ - (hcov.one_form x f) u - exact h''.symm - · rwa [mdifferentiableAt_section] - · rwa [mdifferentiableAt_section] - · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ - simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covσ] - rw [hcov.eq_one_form σ_diff] - rfl - -end projection_trivial_bundle - end IsCovariantDerivativeOn - -namespace Bundle.Trivialization - -section to_trivialization - -variable (e : Trivialization F (π F V)) [VectorBundle ℝ F V] [MemTrivializationAtlas e] - [IsManifold I 1 M] - -noncomputable -def pushCovDer - (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : - (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := - fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (e.funToSec σ) x) - -set_option backward.isDefEq.respectTransparency false in -lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [ContMDiffVectorBundle 1 F V I] - {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - (hcov : IsCovariantDerivativeOn F cov e.baseSet) - {X₀ : TangentSpace I x} {σ : Π x : M, V x} {x : M} - (hσ : MDiffAt T%σ x) - (hx : x ∈ e.baseSet := by assumption) : - (e.pushCovDer cov) (fun x ↦ (e (σ x)).2) x X₀ = (e (cov σ x X₀)).2 := by - have : cov (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov σ x := by - apply hcov.congr_σ_of_eqOn _ hσ (e.baseSet_mem_nhds hx) - · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? - · stop - rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] - exact hσ - unfold pushCovDer - stop - rw [this] - simp [coe_linearMapAt, hx] - - -variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) - -lemma pushCovDer_isCovariantDerivativeOn - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [ContMDiffVectorBundle 1 F V I] - {u : Set M} (hu : u ⊆ e.baseSet) - (hcov : IsCovariantDerivativeOn F cov u) : - IsCovariantDerivativeOn F (e.pushCovDer cov) u where - addσ {σ σ' x} hσ hσ' hx := by - set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - set s' := (fun x' ↦ e.symm x' (σ' x')) - have hs' : MDiffAt (T% s') x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' - unfold Trivialization.pushCovDer - stop - rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] - congr - ext y - simp [e.symm_map_add ℝ, s, s'] - leibniz {σ g x} hσ hg hx := by - set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold Trivialization.pushCovDer - have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by - ext y - simp [s, e.symm_map_smul] - stop - rw [this, hcov.leibniz hs hg hx] - ext X₀ - simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, - ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', - continuousLinearMapAt_apply, Pi.smul_apply, Function.comp_apply, - ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply, _root_.map_smul, - add_right_inj, s] - congr! 1 - exact e.linearMapAt_symmₗ (R := ℝ) (hu hx) (σ x) - -variable {e} in -lemma coordChangeL_pushCovDer - [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) - {s : M → F} (hs : MDiffAt s x) : - e.coordChangeL ℝ e' x ∘L (e.pushCovDer cov s x) = - e'.pushCovDer cov (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by - ext1 X₀ - simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, Function.comp_apply] - unfold pushCovDer - let σ := (fun x' ↦ e.symm x' (s x')) - rw [coordChangeL_apply e e' hx] - simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, coe_linearMapAt, hx.1, - ↓reduceIte, Function.comp_apply, hx.2] - refold_let σ - have : e.symm x (e ⟨x, cov σ x X₀⟩).2 = cov σ x X₀ := by - -- TODO fix `simp [hx.1]` not working - exact symm_apply_apply_mk e hx.1 (cov σ x X₀) - stop - rw [this] - -- TODO: extract lemma? - have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = - e'.symm x' ((fun x ↦ (coordChangeL ℝ e e' x) (s x)) x') := by - rintro x' ⟨hx'e, hx'e'⟩ - simp only - rw [coordChangeL_apply e e' ⟨hx'e, hx'e'⟩] - -- simp [hx'e'] -- TODO doesn’t work - rw [symm_apply_apply_mk e' hx'e'] - have mem : e.baseSet ∩ e'.baseSet ∈ 𝓝 x := by - -- FIXME: make sure grind can do this proof - exact inter_mem (baseSet_mem_nhds e (mem_of_mem_inter_left hx)) - (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) - have hσ : MDiffAt (T% σ) x := - mdifferentiableAt_section_of_function e hx.1 hs - rw [hcov.congr_σ_of_eqOn hσ ?_ mem this] - -- TODO have automatation doing the next three lines… - apply mdifferentiableAt_section_of_function e' hx.2 - have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 - exact this.mdifferentiableAt (zero_ne_one.symm) |>.clm_apply hs - - -variable {e} in -lemma coordChangeL_mem_horiz - [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : - haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov - haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov - (u, w) ∈ hcove.horiz x v → - (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by - have hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov - have hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov - rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] - rintro ⟨s, sdiff, sxv, sxuw, covs⟩ - use fun x ↦ e.coordChangeL ℝ e' x (s x), ?_, ?_, ?_ - · let X := extend I E u - have hX : MDiffAt (T% X) x := by - -- TODO: extract as lemma? - exact (mdifferentiable_extend I E u).mdifferentiableAt - -- TODO: investigate whether the following line comes from inconsistent ways to - -- state assumptions - rw [mdifferentiableAt_section_trivial_iff] at sdiff - rw [← e.coordChangeL_pushCovDer hcov hx sdiff] - simp [covs] - · sorry - · congr - · rw [← sxuw] - sorry - --- This is PAIIIIINNNN -variable {e} in -lemma coordChangeL_coordChangeL - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : - e'.coordChangeL ℝ e x (e.coordChangeL ℝ e' x v) = v := by - have hx' := inter_comm _ _ ▸ hx - change ((coordChangeL ℝ e' e x) ∘ (coordChangeL ℝ e e' x)) v = v - rw [coe_coordChangeL _ _ hx] - rw [coe_coordChangeL _ _ hx'] - change - ((linearEquivAt ℝ e x hx'.2 ∘ (linearEquivAt ℝ e' x hx'.1).symm) ∘ - (linearEquivAt ℝ e' x hx'.1 ∘ (linearEquivAt ℝ e x hx'.2).symm)) - v = v - rw [Function.comp_assoc] - conv => - congr - congr - rfl - rw [← Function.comp_assoc] - change - ((linearEquivAt ℝ e x _) ∘ - (↑(linearEquivAt ℝ e' x hx'.1).symm ∘ₗ (linearEquivAt ℝ e' x hx'.1).toLinearMap) ∘ _) - v = v - rw [(linearEquivAt ℝ e' x hx'.1).symm_comp] - simp only [LinearMap.id_coe, CompTriple.comp_eq] - change (↑(linearEquivAt ℝ e x hx'.2) ∘ₗ (linearEquivAt ℝ e x _).symm.toLinearMap) v = v - rw [(linearEquivAt ℝ e x hx'.2).comp_symm] - simp - -variable {e} in -lemma coordChangeL_mem_horiz_iff - [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : - haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov - haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov - (u, w) ∈ hcove.horiz x v ↔ - (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by - refine ⟨e.coordChangeL_mem_horiz hcov hx, fun hu ↦ ?_⟩ - let v' := e.coordChangeL ℝ e' x v - let w' := e.coordChangeL ℝ e' x w - rw [inter_comm] at hx hcov - have hx' := inter_comm _ _ ▸ hx - have hvv' : v = e'.coordChangeL ℝ e x v' := (coordChangeL_coordChangeL hx' v).symm - have hww' : w = e'.coordChangeL ℝ e x w' := (coordChangeL_coordChangeL hx' w).symm - have key := e'.coordChangeL_mem_horiz hcov hx (w := w') (u := u) (v := v') ?_ - · rw [← hvv', ← hww'] at key - convert key using 2 - apply inter_comm - · convert hu using 2 - apply inter_comm - -end to_trivialization - -end Bundle.Trivialization - -section horiz -namespace CovariantDerivative - -variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - -local notation "TM" => TangentSpace I - --- FIXME the statement of CovariantDerivative.isCovariantDerivativeOn should work on any set - -noncomputable -def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := - letI t := trivializationAt F V v.proj - haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (u := t.baseSet) subset_rfl - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - letI tproj := d_covDerOn.projection v.proj (t v).2 - letI Tvt := t.deriv I v - t.symmL ℝ v.proj ∘L tproj ∘L Tvt - -omit [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] in -lemma isCovariantDerivativeOn_pushCovDer - (cov : CovariantDerivative I F V) (e : Trivialization F (π F V)) [MemTrivializationAtlas e] : - IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := - e.pushCovDer_isCovariantDerivativeOn subset_rfl - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - - - -lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod - 𝓘(ℝ, F)) v) : - letI t := trivializationAt F V v.proj - haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t - letI tproj := d_covDerOn.projection v.proj (t v).2 - letI Tvt := t.deriv I v - (t <| cov.proj v u).2 = tproj (Tvt u) := by - simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] - - -noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := - (cov.proj v).ker - -lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} - (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : - u ∈ cov.horiz v ↔ cov.proj v u = 0 := by - simp [horiz] - -lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - letI t := trivializationAt F V v.proj - haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t - horiz cov v = Submodule.comap (t.deriv I v).toLinearMap - (d_covDerOn.horiz v.proj (t v).2) := by - -- FIXME: needing all those lets and the change is awful - let t := trivializationAt F V v.proj - let Tvt := t.deriv I v - haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t - let tproj := hcov.projection v.proj (t v).2 - let t' := t.continuousLinearEquivAt ℝ v.proj (mem_baseSet_trivializationAt F V v.proj) - ext u - change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 - simp - - -omit [ContMDiffVectorBundle 1 F V I] in -lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] - (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - IsCompl (cov.horiz v) (vert v) := by - let t := trivializationAt F V v.proj - let Tvt := t.deriv I v - have hcov := cov.isCovariantDerivativeOn_pushCovDer t - rw [t.comap_vert (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] - apply LinearMap.comap_isCompl - · apply t.bijective_deriv - exact FiberBundle.mem_baseSet_trivializationAt' v.proj - · apply hcov.horiz_vert_direct_sum - -variable [IsManifold I 1 M] -variable {cov : CovariantDerivative I F V} - -set_option backward.isDefEq.respectTransparency false in -omit [ContMDiffVectorBundle 1 F V I] in -lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] - {σ : Π x : M, V x} (x : M) - (hσ : MDiffAt (T% σ) x) : - cov σ x = cov.proj (σ x) ∘L - (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x) := by - stop - let t := trivializationAt F V x - let s := fun x ↦ (t (σ x)).2 - let Tσx := mfderiv% (T% σ) x - -- FIXME `mfderiv%` fails in next line (fixed on master?) - let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) - ext1 X₀ - change cov σ x X₀ = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) X₀) - have hcov := cov.isCovariantDerivativeOn_pushCovDer t - have hx := mem_baseSet_trivializationAt F V x - have hs : MDiffAt (T% s) x := by - rw [t.mdifferentiableAt_section_iff I σ hx] at hσ - exact (mdifferentiableAt_section I s).mpr hσ - apply t.eq_of hx - erw [cov.snd_triv_proj (T% σ x), - ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hσ, - hcov.cov_eq_proj s X₀ hs, t.mfderiv_comp_section hσ _ hx] - -end CovariantDerivative -end horiz - -end real - --- variable (E E') in --- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ --- @[simps] --- noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' --- (Bundle.Trivial E E') where --- toFun X s := fun x ↦ fderiv 𝕜 s x (X x) --- isCovariantDerivativeOn := --- { addX X X' σ x _ := by simp --- smulX X σ c' x _ := by simp --- addσ X σ σ' x hσ hσ' hx := by --- rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' --- rw [fderiv_add hσ hσ'] --- rfl --- smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] --- leibniz X σ f x hσ hf hx := by --- have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := --- fderiv_smul (by simp_all) (by simp_all) --- simp [this, bar] --- rfl } diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean new file mode 100644 index 00000000000000..8c456d00e4311a --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -0,0 +1,473 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic + +/-! +# Covariant derivatives + +TODO: add a more complete doc-string + +-/ + +open Bundle Filter Module Topology Set +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section real + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + -- `V` vector bundle + +--- TODO FROM HERE! + +namespace IsCovariantDerivativeOn + +section projection_trivial_bundle + +variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + +local notation "TM" => TangentSpace I + +variable {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} + +noncomputable +def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) × F →L[ℝ] F := + .snd ℝ (TM x) F + (hcov.one_form x f ∘L .fst ℝ (TM x) F) + +@[simp] +lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : + hcov.projection x f (v, w) = w + hcov.one_form x f v := rfl + +lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (σ : M → F) + {x : M} (X₀ : TM x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + cov σ x X₀ = hcov.projection x (σ x) (X₀, mfderiv I 𝓘(ℝ, F) σ x X₀) := by + simpa using congr($(hcov.eq_one_form hσ) X₀) + +noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + Submodule ℝ (TM x × F) := + (hcov.projection x f).ker + +lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + IsCompl (hcov.horiz x f) (.prod ⊥ ⊤) := by + refine IsCompl.of_eq ?_ ?_ + · refine (Submodule.eq_bot_iff _).mpr ?_ + rintro ⟨u, w⟩ ⟨huw, hu, hw⟩ + simp_all [horiz] + · apply Submodule.sup_eq_top_iff _ _ |>.2 + intro u + use u - (0, hcov.projection x f u), ?_, (0, hcov.projection x f u), ?_, ?_ + all_goals simp [horiz] + +set_option backward.isDefEq.respectTransparency false in +lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : F} + {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ + ∃ σ : M → F, MDiffAt (T% σ) x ∧ + σ x = f ∧ + mfderiv I 𝓘(ℝ, F) σ x u = v ∧ + cov σ x u = 0 := by + constructor + · intro huv + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv + let w : TangentSpace 𝓘(ℝ, F) f := v + by_cases hu : u = 0 + · subst hu + replace huv : v = 0 := by simpa using huv + subst huv + use fun x ↦ f + simp [mdifferentiableAt_section, mdifferentiableAt_const] + rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ + use map_of_one_jet u w, ?_, h, h'' + · rw [hcov.eq_one_form] + · simp only [w, h] + convert huv + convert ContinuousLinearMap.add_apply (M₁ := TangentSpace I x) (M₂ := F) _ + (hcov.one_form x f) u + exact h''.symm + · rwa [mdifferentiableAt_section] + · rwa [mdifferentiableAt_section] + · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covσ] + rw [hcov.eq_one_form σ_diff] + rfl + +end projection_trivial_bundle + +end IsCovariantDerivativeOn + +--end real + +namespace Bundle.Trivialization + +section to_trivialization + +variable (e : Trivialization F (π F V)) [VectorBundle ℝ F V] [MemTrivializationAtlas e] + [IsManifold I 1 M] + +noncomputable +def pushCovDer + (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : + (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := + fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (e.funToSec σ) x) + +set_option backward.isDefEq.respectTransparency false in +lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} + (hcov : IsCovariantDerivativeOn F cov e.baseSet) + {X₀ : TangentSpace I x} {σ : Π x : M, V x} {x : M} + (hσ : MDiffAt T%σ x) + (hx : x ∈ e.baseSet := by assumption) : + (e.pushCovDer cov) (fun x ↦ (e (σ x)).2) x X₀ = (e (cov σ x X₀)).2 := by + have : cov (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov σ x := by + apply hcov.congr_σ_of_eqOn _ hσ (e.baseSet_mem_nhds hx) + · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? + · stop + rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] + exact hσ + unfold pushCovDer + stop + rw [this] + simp [coe_linearMapAt, hx] + + +variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} + -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + +lemma pushCovDer_isCovariantDerivativeOn + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] + {u : Set M} (hu : u ⊆ e.baseSet) + (hcov : IsCovariantDerivativeOn F cov u) : + IsCovariantDerivativeOn F (e.pushCovDer cov) u where + addσ {σ σ' x} hσ hσ' hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ + set s' := (fun x' ↦ e.symm x' (σ' x')) + have hs' : MDiffAt (T% s') x := + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' + unfold Trivialization.pushCovDer + stop + rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] + congr + ext y + simp [e.symm_map_add ℝ, s, s'] + leibniz {σ g x} hσ hg hx := by + set s := (fun x' ↦ e.symm x' (σ x')) + have hs : MDiffAt (T% s) x := + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ + unfold Trivialization.pushCovDer + have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by + ext y + simp [s, e.symm_map_smul] + stop + rw [this, hcov.leibniz hs hg hx] + ext X₀ + simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, + ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', + continuousLinearMapAt_apply, Pi.smul_apply, Function.comp_apply, + ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply, _root_.map_smul, + add_right_inj, s] + congr! 1 + exact e.linearMapAt_symmₗ (R := ℝ) (hu hx) (σ x) + +variable {e} in +lemma coordChangeL_pushCovDer + [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) + {s : M → F} (hs : MDiffAt s x) : + e.coordChangeL ℝ e' x ∘L (e.pushCovDer cov s x) = + e'.pushCovDer cov (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by + ext1 X₀ + simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, Function.comp_apply] + unfold pushCovDer + let σ := (fun x' ↦ e.symm x' (s x')) + rw [coordChangeL_apply e e' hx] + simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, coe_linearMapAt, hx.1, + ↓reduceIte, Function.comp_apply, hx.2] + refold_let σ + have : e.symm x (e ⟨x, cov σ x X₀⟩).2 = cov σ x X₀ := by + -- TODO fix `simp [hx.1]` not working + exact symm_apply_apply_mk e hx.1 (cov σ x X₀) + stop + rw [this] + -- TODO: extract lemma? + have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = + e'.symm x' ((fun x ↦ (coordChangeL ℝ e e' x) (s x)) x') := by + rintro x' ⟨hx'e, hx'e'⟩ + simp only + rw [coordChangeL_apply e e' ⟨hx'e, hx'e'⟩] + -- simp [hx'e'] -- TODO doesn’t work + rw [symm_apply_apply_mk e' hx'e'] + have mem : e.baseSet ∩ e'.baseSet ∈ 𝓝 x := by + -- FIXME: make sure grind can do this proof + exact inter_mem (baseSet_mem_nhds e (mem_of_mem_inter_left hx)) + (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) + have hσ : MDiffAt (T% σ) x := + mdifferentiableAt_section_of_function e hx.1 hs + rw [hcov.congr_σ_of_eqOn hσ ?_ mem this] + -- TODO have automatation doing the next three lines… + apply mdifferentiableAt_section_of_function e' hx.2 + have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 + exact this.mdifferentiableAt (zero_ne_one.symm) |>.clm_apply hs + + +variable {e} in +lemma coordChangeL_mem_horiz + [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : + haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + (u, w) ∈ hcove.horiz x v → + (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by + have hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + have hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] + rintro ⟨s, sdiff, sxv, sxuw, covs⟩ + use fun x ↦ e.coordChangeL ℝ e' x (s x), ?_, ?_, ?_ + · let X := extend I E u + have hX : MDiffAt (T% X) x := by + -- TODO: extract as lemma? + exact (mdifferentiable_extend I E u).mdifferentiableAt + -- TODO: investigate whether the following line comes from inconsistent ways to + -- state assumptions + rw [mdifferentiableAt_section_trivial_iff] at sdiff + rw [← e.coordChangeL_pushCovDer hcov hx sdiff] + simp [covs] + · sorry + · congr + · rw [← sxuw] + sorry + +-- This is PAIIIIINNNN +variable {e} in +lemma coordChangeL_coordChangeL + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : + e'.coordChangeL ℝ e x (e.coordChangeL ℝ e' x v) = v := by + have hx' := inter_comm _ _ ▸ hx + change ((coordChangeL ℝ e' e x) ∘ (coordChangeL ℝ e e' x)) v = v + rw [coe_coordChangeL _ _ hx] + rw [coe_coordChangeL _ _ hx'] + change + ((linearEquivAt ℝ e x hx'.2 ∘ (linearEquivAt ℝ e' x hx'.1).symm) ∘ + (linearEquivAt ℝ e' x hx'.1 ∘ (linearEquivAt ℝ e x hx'.2).symm)) + v = v + rw [Function.comp_assoc] + conv => + congr + congr + rfl + rw [← Function.comp_assoc] + change + ((linearEquivAt ℝ e x _) ∘ + (↑(linearEquivAt ℝ e' x hx'.1).symm ∘ₗ (linearEquivAt ℝ e' x hx'.1).toLinearMap) ∘ _) + v = v + rw [(linearEquivAt ℝ e' x hx'.1).symm_comp] + simp only [LinearMap.id_coe, CompTriple.comp_eq] + change (↑(linearEquivAt ℝ e x hx'.2) ∘ₗ (linearEquivAt ℝ e x _).symm.toLinearMap) v = v + rw [(linearEquivAt ℝ e x hx'.2).comp_symm] + simp + +variable {e} in +lemma coordChangeL_mem_horiz_iff + [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] + {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) + {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : + haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + (u, w) ∈ hcove.horiz x v ↔ + (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by + refine ⟨e.coordChangeL_mem_horiz hcov hx, fun hu ↦ ?_⟩ + let v' := e.coordChangeL ℝ e' x v + let w' := e.coordChangeL ℝ e' x w + rw [inter_comm] at hx hcov + have hx' := inter_comm _ _ ▸ hx + have hvv' : v = e'.coordChangeL ℝ e x v' := (coordChangeL_coordChangeL hx' v).symm + have hww' : w = e'.coordChangeL ℝ e x w' := (coordChangeL_coordChangeL hx' w).symm + have key := e'.coordChangeL_mem_horiz hcov hx (w := w') (u := u) (v := v') ?_ + · rw [← hvv', ← hww'] at key + convert key using 2 + apply inter_comm + · convert hu using 2 + apply inter_comm + +end to_trivialization + +end Bundle.Trivialization + +section horiz +namespace CovariantDerivative + +variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] + [T2Space M] [IsManifold I ∞ M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] + +local notation "TM" => TangentSpace I + +-- FIXME the statement of CovariantDerivative.isCovariantDerivativeOn should work on any set + +noncomputable +def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (u := t.baseSet) subset_rfl + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + letI tproj := d_covDerOn.projection v.proj (t v).2 + letI Tvt := t.deriv I v + t.symmL ℝ v.proj ∘L tproj ∘L Tvt + +omit [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] in +lemma isCovariantDerivativeOn_pushCovDer + (cov : CovariantDerivative I F V) (e : Trivialization F (π F V)) [MemTrivializationAtlas e] : + IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := + e.pushCovDer_isCovariantDerivativeOn subset_rfl + (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + + + +lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod + 𝓘(ℝ, F)) v) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t + letI tproj := d_covDerOn.projection v.proj (t v).2 + letI Tvt := t.deriv I v + (t <| cov.proj v u).2 = tproj (Tvt u) := by + simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] + + +noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := + (cov.proj v).ker + +lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} + (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + u ∈ cov.horiz v ↔ cov.proj v u = 0 := by + simp [horiz] + +lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t + horiz cov v = Submodule.comap (t.deriv I v).toLinearMap + (d_covDerOn.horiz v.proj (t v).2) := by + -- FIXME: needing all those lets and the change is awful + let t := trivializationAt F V v.proj + let Tvt := t.deriv I v + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t + let tproj := hcov.projection v.proj (t v).2 + let t' := t.continuousLinearEquivAt ℝ v.proj (mem_baseSet_trivializationAt F V v.proj) + ext u + change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 + simp + + +omit [ContMDiffVectorBundle 1 F V I] in +lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] + (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + IsCompl (cov.horiz v) (vert v) := by + let t := trivializationAt F V v.proj + let Tvt := t.deriv I v + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + rw [t.comap_vert (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] + apply LinearMap.comap_isCompl + · apply t.bijective_deriv + exact FiberBundle.mem_baseSet_trivializationAt' v.proj + · apply hcov.horiz_vert_direct_sum + +variable [IsManifold I 1 M] +variable {cov : CovariantDerivative I F V} + +set_option backward.isDefEq.respectTransparency false in +omit [ContMDiffVectorBundle 1 F V I] in +lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] + {σ : Π x : M, V x} (x : M) + (hσ : MDiffAt (T% σ) x) : + cov σ x = cov.proj (σ x) ∘L + (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x) := by + stop + let t := trivializationAt F V x + let s := fun x ↦ (t (σ x)).2 + let Tσx := mfderiv% (T% σ) x + -- FIXME `mfderiv%` fails in next line (fixed on master?) + let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) + ext1 X₀ + change cov σ x X₀ = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) X₀) + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + have hx := mem_baseSet_trivializationAt F V x + have hs : MDiffAt (T% s) x := by + rw [t.mdifferentiableAt_section_iff I σ hx] at hσ + exact (mdifferentiableAt_section I s).mpr hσ + apply t.eq_of hx + erw [cov.snd_triv_proj (T% σ x), + ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hσ, + hcov.cov_eq_proj s X₀ hs, t.mfderiv_comp_section hσ _ hx] + +end CovariantDerivative +end horiz + +end real + +-- variable (E E') in +-- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ +-- @[simps] +-- noncomputable def trivial : CovariantDerivative 𝓘(𝕜, E) E' +-- (Bundle.Trivial E E') where +-- toFun X s := fun x ↦ fderiv 𝕜 s x (X x) +-- isCovariantDerivativeOn := +-- { addX X X' σ x _ := by simp +-- smulX X σ c' x _ := by simp +-- addσ X σ σ' x hσ hσ' hx := by +-- rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' +-- rw [fderiv_add hσ hσ'] +-- rfl +-- smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] +-- leibniz X σ f x hσ hf hx := by +-- have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := +-- fderiv_smul (by simp_all) (by simp_all) +-- simp [this, bar] +-- rfl } + +end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 5fd1508b0baf90..b95742ad05b4e1 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -5,8 +5,9 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann public import Mathlib.Geometry.Manifold.IntegralCurve.Basic + /-! # Lifting vectors using covariant derivatives @@ -16,7 +17,7 @@ TODO: add a more complete doc-string @[expose] public section -@[expose] public section delaborators +section delaborators -- TODO: decide whether we want this and move -- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index bcb3a9d9367354..1ec9f3b87e8278 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -6,7 +6,6 @@ Authors: Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary -public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim public import Mathlib.Geometry.Manifold.MFDeriv.Atlas public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable @@ -18,10 +17,8 @@ TODO: PR all this to appropriate places. -/ open Bundle Filter Module Topology Set - open scoped Bundle Manifold ContDiff - @[expose] public section tangent_bundle_normedSpace variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] @@ -153,7 +150,6 @@ lemma map_of_spec (u : E) (u' : E') (h : u = 0 → u' = 0) : map_of 𝕜 u u' u (exists_map_of 𝕜 u u').choose_spec h end linear_algebra - section variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @@ -164,7 +160,6 @@ variable {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - variable (𝕜) in noncomputable def map_of_loc_one_jet (e u : E) (e' u' : E') : E → E' := fun x ↦ e' + map_of 𝕜 u u' (x - e) From 3c5af5bf67d6819ec59772aeeff824f8c5bde8b0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:30:14 +0000 Subject: [PATCH 465/601] chore: move material about trivial bundles to a separate file --- Mathlib.lean | 1 + .../CovariantDerivative/Basic.lean | 121 ------------ .../CovariantDerivative/Ehresmann.lean | 2 +- .../CovariantDerivative/Trivial.lean | 184 ++++++++++++++++++ 4 files changed, 186 insertions(+), 122 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean diff --git a/Mathlib.lean b/Mathlib.lean index e74fece974dbed..bfed718d84b91a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4414,6 +4414,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index baa3d36be1a4a3..6c06b86dfc11a8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -10,7 +10,6 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim -public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim /-! # Covariant derivatives @@ -232,30 +231,6 @@ lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] end operations -section trivial_bundle - -variable (I M F) in -@[simps] -noncomputable def trivial [IsManifold I 1 M] : - IsCovariantDerivativeOn F (V := Trivial M F) - (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where - addσ {σ σ' x} hσ hσ' hx := by - rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' - rw [mfderiv_add hσ hσ'] - leibniz {σ f x} hσ hf hx := by - rw [mdifferentiableAt_section] at hσ - ext1 X₀ - exact mfderiv_smul hσ hf X₀ - -lemma of_endomorphism (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F) : - IsCovariantDerivativeOn F - (fun (s : M → F) x ↦ - letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) s x - d + A x (s x)) univ := - trivial I M F |>.add_one_form A - -end trivial_bundle - end IsCovariantDerivativeOn /-! Bundled global covariant derivatives -/ @@ -366,60 +341,6 @@ lemma ContMDiffCovariantDerivative.affineCombination' [VectorBundle 𝕜 F V] end operations -section trivial_bundle - -variable (I M F) in -@[simps] -noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where - toFun s x := mfderiv I 𝓘(𝕜, F) s x - isCovariantDerivativeOn := -- TODO use previous work - { addσ {σ σ' x} hσ hσ' hx := by - rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' - rw [mfderiv_add hσ hσ'] - leibniz {σ f x} hσ hf hx := by - rw [mdifferentiableAt_section] at hσ - ext1 X₀ - exact mfderiv_smul hσ hf X₀ } - -end trivial_bundle - -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - --- TODO: does it make sense to speak of analytic connections? if so, change the definition of --- regularity and use ∞ from `open scoped ContDiff` instead. - -/-- The trivial connection on the trivial bundle is smooth -/ -lemma trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where - contMDiff := by -- {X σ} hX hσ - sorry /- - -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well - simp only [trivial] - -- use a local trivialisation - intro x - specialize hX x - -- TODO: use contMDiffOn instead, to get something like - -- have hX' : ContMDiffOn 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (∞ + 1) - -- (T% σ) (trivializationAt x).baseSet := hX.contMDiffOn - -- then want a version contMDiffOn_totalSpace - rw [contMDiffAt_totalSpace] at hX ⊢ - simp only [Trivial.fiberBundle_trivializationAt', Trivial.trivialization_apply] - refine ⟨contMDiff_id _, ?_⟩ - obtain ⟨h₁, h₂⟩ := hX - -- ... hopefully telling me - -- have h₂scifi : ContMDiffOn 𝓘(𝕜, E) 𝓘(𝕜, E') ∞ - -- (fun x ↦ σ x) (trivializationAt _).baseSet_ := sorry - simp at h₂ - -- now use ContMDiffOn.congr and contDiff_infty_iff_fderiv, - -- or perhaps a contMDiffOn version of this lemma? - sorry -/ - -noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : - CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where - toFun σ := fun x ↦ fderiv 𝕜 σ x + A x (σ x) - isCovariantDerivativeOn := by - convert IsCovariantDerivativeOn.of_endomorphism (I := 𝓘(𝕜, E)) A - ext f x v - rw [mfderiv_eq_fderiv] end CovariantDerivative end any_field @@ -559,46 +480,4 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x rw [mkTensorAt_apply _ _ _ _ hσ] rfl --- The classification of real connections over a trivial bundle -section classification - -variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - -/-- Classification of covariant derivatives over a trivial vector bundle: every connection -is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term --/ -lemma exists_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} - {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : - ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), - ∀ σ : M → F, ∀ x ∈ s, MDiffAt (T% σ) x → - letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x - cov σ x = d + A x (σ x) := by - use hcov.difference (trivial I M F |>.mono <| subset_univ s) - intro σ x hx hσ - rw [hcov.difference_apply _ (by trivial) hσ] - module - -noncomputable def one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} - {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : - Π x : M, F →L[ℝ] TangentSpace I x →L[ℝ] F := - hcov.exists_one_form.choose - -lemma eq_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} - {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) - {σ : M → F} - {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x - cov σ x = d + hcov.one_form x (σ x) := - hcov.exists_one_form.choose_spec σ x hx hσ - -lemma _root_.CovariantDerivative.exists_one_form - (cov : CovariantDerivative I F (Bundle.Trivial M F)) : - ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), - ∀ σ : M → F, ∀ x, MDiffAt (T% σ) x → - letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x - cov σ x = d + A x (σ x) := by - simpa using cov.isCovariantDerivativeOn.exists_one_form - -end classification - end IsCovariantDerivativeOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 8c456d00e4311a..680d33e33b4d6d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -15,7 +15,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary -public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial /-! # Covariant derivatives diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean new file mode 100644 index 00000000000000..996a463bde5185 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -0,0 +1,184 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim + +/-! +# Everything you always wanted to know about covariant derivatives on the trivial bundle + +Don't be afraid to ask. TODO! + +-/ + +open Bundle Filter Module Topology Set +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +@[expose] public section -- TODO: think if we want to expose all definitions! + +open Bundle Filter Module Topology Set + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] + [∀ x, Module 𝕜 (V x)] [∀ x, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] + [∀ x, ContinuousSMul 𝕜 (V x)] [FiberBundle F V] + [IsManifold I 1 M] + +namespace IsCovariantDerivativeOn + +section trivial_bundle + +variable (I M F) in +@[simps] +noncomputable def trivial [IsManifold I 1 M] : + IsCovariantDerivativeOn F (V := Trivial M F) + (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where + addσ {σ σ' x} hσ hσ' hx := by + rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' + rw [mfderiv_add hσ hσ'] + leibniz {σ f x} hσ hf hx := by + rw [mdifferentiableAt_section] at hσ + ext1 X₀ + exact mfderiv_smul hσ hf X₀ + +lemma of_endomorphism (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F) : + IsCovariantDerivativeOn F + (fun (s : M → F) x ↦ + letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) s x + d + A x (s x)) univ := + trivial I M F |>.add_one_form A + +end trivial_bundle + +end IsCovariantDerivativeOn + +namespace CovariantDerivative + +section trivial_bundle + +variable (I M F) in +@[simps] +noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where + toFun s x := mfderiv I 𝓘(𝕜, F) s x + isCovariantDerivativeOn := -- TODO use previous work + { addσ {σ σ' x} hσ hσ' hx := by + rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' + rw [mfderiv_add hσ hσ'] + leibniz {σ f x} hσ hf hx := by + rw [mdifferentiableAt_section] at hσ + ext1 X₀ + exact mfderiv_smul hσ hf X₀ } + +end trivial_bundle + + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +-- TODO: does it make sense to speak of analytic connections? if so, change the definition of +-- regularity and use ∞ from `open scoped ContDiff` instead. + +/-- The trivial connection on the trivial bundle is smooth -/ +lemma trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where + contMDiff := by -- {X σ} hX hσ + sorry /- + -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well + simp only [trivial] + -- use a local trivialisation + intro x + specialize hX x + -- TODO: use contMDiffOn instead, to get something like + -- have hX' : ContMDiffOn 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) (∞ + 1) + -- (T% σ) (trivializationAt x).baseSet := hX.contMDiffOn + -- then want a version contMDiffOn_totalSpace + rw [contMDiffAt_totalSpace] at hX ⊢ + simp only [Trivial.fiberBundle_trivializationAt', Trivial.trivialization_apply] + refine ⟨contMDiff_id _, ?_⟩ + obtain ⟨h₁, h₂⟩ := hX + -- ... hopefully telling me + -- have h₂scifi : ContMDiffOn 𝓘(𝕜, E) 𝓘(𝕜, E') ∞ + -- (fun x ↦ σ x) (trivializationAt _).baseSet_ := sorry + simp at h₂ + -- now use ContMDiffOn.congr and contDiff_infty_iff_fderiv, + -- or perhaps a contMDiffOn version of this lemma? + sorry -/ + +noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : + CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where + toFun σ := fun x ↦ fderiv 𝕜 σ x + A x (σ x) + isCovariantDerivativeOn := by + convert IsCovariantDerivativeOn.of_endomorphism (I := 𝓘(𝕜, E)) A + ext f x v + rw [mfderiv_eq_fderiv] + +end CovariantDerivative + +section real + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `F` model fiber + (n : WithTop ℕ∞) + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + -- `V` vector bundle + +namespace IsCovariantDerivativeOn + +-- The classification of real connections over a trivial bundle +section classification + +variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] + +/-- Classification of covariant derivatives over a trivial vector bundle: every connection +is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term +-/ +lemma exists_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), + ∀ σ : M → F, ∀ x ∈ s, MDiffAt (T% σ) x → + letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + cov σ x = d + A x (σ x) := by + use hcov.difference (trivial I M F |>.mono <| subset_univ s) + intro σ x hx hσ + rw [hcov.difference_apply _ (by trivial) hσ] + module + +noncomputable def one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + Π x : M, F →L[ℝ] TangentSpace I x →L[ℝ] F := + hcov.exists_one_form.choose + +lemma eq_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + {σ : M → F} + {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + cov σ x = d + hcov.one_form x (σ x) := + hcov.exists_one_form.choose_spec σ x hx hσ + +lemma _root_.CovariantDerivative.exists_one_form + (cov : CovariantDerivative I F (Bundle.Trivial M F)) : + ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), + ∀ σ : M → F, ∀ x, MDiffAt (T% σ) x → + letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + cov σ x = d + A x (σ x) := by + simpa using cov.isCovariantDerivativeOn.exists_one_form + +end classification + +end IsCovariantDerivativeOn From 1739941a205a43b4ee61b1deac08ed8056ea4d47 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:36:04 +0000 Subject: [PATCH 466/601] Fix and tweak imports more --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 2 -- .../Manifold/VectorBundle/CovariantDerivative/Torsion.lean | 1 + Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 6c06b86dfc11a8..624ee55f6c99ba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -7,8 +7,6 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -public import Mathlib.Geometry.Manifold.VectorField.LieBracket -public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim /-! diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 2e79073e37afbf..fa58a613f2175b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -6,6 +6,7 @@ Authors: Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorField.LieBracket /-! # Torsion of a covariant derivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 243d8a227f5d80..d8a8050ae39641 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module From f6079a3f054c9cfafda581ef4db60fa4ea7ea839 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 14:41:00 +0000 Subject: [PATCH 467/601] chore: move mfderiv lemmas we need to a separate file --- Mathlib.lean | 1 + Mathlib/Geometry/Manifold/MfDerivSMul.lean | 81 +++++++++++++++++++ .../CovariantDerivative/Basic.lean | 2 +- .../CovariantDerivative/Ehresmann.lean | 1 + .../CovariantDerivative/Prelim.lean | 54 ------------- 5 files changed, 84 insertions(+), 55 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/MfDerivSMul.lean diff --git a/Mathlib.lean b/Mathlib.lean index bfed718d84b91a..02cac988b1d922 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4393,6 +4393,7 @@ public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions public import Mathlib.Geometry.Manifold.MFDeriv.Tangent public import Mathlib.Geometry.Manifold.MFDeriv.UniqueDifferential public import Mathlib.Geometry.Manifold.Metrizable +public import Mathlib.Geometry.Manifold.MfDerivSMul public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.PartitionOfUnity public import Mathlib.Geometry.Manifold.PoincareConjecture diff --git a/Mathlib/Geometry/Manifold/MfDerivSMul.lean b/Mathlib/Geometry/Manifold/MfDerivSMul.lean new file mode 100644 index 00000000000000..5c21e2705c6d62 --- /dev/null +++ b/Mathlib/Geometry/Manifold/MfDerivSMul.lean @@ -0,0 +1,81 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.MFDeriv.Atlas +public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace +public import Mathlib.Geometry.Manifold.Notation + +/-! +# Auxiliary lemmas about mfderiv and scalar multiplication + +-/ + +open Bundle Filter Module Topology Set +open scoped Bundle Manifold ContDiff + +@[expose] public section mfderiv + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + +set_option backward.isDefEq.respectTransparency false in +-- cleaned up and PRed in #34262 +lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : + mfderiv% (a • s) x v = a • mfderiv% s x v := by + by_cases hs : MDiffAt s x + · have hs' := hs.const_smul a + suffices + (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = + a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) + (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] + change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ + rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] + rfl + · by_cases ha : a = 0 + · have : a • s = 0 := by ext; simp [ha] + rw [this, ha] + change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ + simp + have hs' : ¬ MDiffAt (a • s) x := + fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) + rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] + simp + rfl + +-- PRed and cleaned up in #34263 +set_option linter.flexible false in -- FIXME +lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) + (hs : MDiffAt s x) (v : TangentSpace I x) : + letI dsxv : 𝕜 := mfderiv% s x v + letI dfxv : F := mfderiv% f x v + mfderiv% (s • f) x v = (s x) • dfxv + dsxv • f x := by + set φ := chartAt H x + -- TODO: the next two have should be special cases of the same lemma + have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [← this] at hs + have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [← this] at hf + have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hsf : MDiffAt (s • f) x := hs.smul hf + simp [mfderiv, hsf, hs, hf] + have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := + ModelWithCorners.uniqueDiffWithinAt_image I + erw [fderivWithin_smul uniq hs' hf'] + simp [φ.left_inv (ChartedSpace.mem_chart_source x)] + rfl + +end mfderiv diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 624ee55f6c99ba..9a9586467e0b50 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -7,7 +7,7 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim +public import Mathlib.Geometry.Manifold.MfDerivSMul /-! # Covariant derivatives diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 680d33e33b4d6d..f6a348210beb90 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -10,6 +10,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Tangent public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 1ec9f3b87e8278..502b34ec1bc402 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -66,60 +66,6 @@ lemma surjective_mfderiv_of_eventually_rightInverse rw [← hxy] at this exact RightInverse.surjective this -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -set_option backward.isDefEq.respectTransparency false in --- cleaned up and PRed in #34262 -lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : - mfderiv% (a • s) x v = a • mfderiv% s x v := by - by_cases hs : MDiffAt s x - · have hs' := hs.const_smul a - suffices - (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = - a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) - (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] - change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ - rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] - rfl - · by_cases ha : a = 0 - · have : a • s = 0 := by ext; simp [ha] - rw [this, ha] - change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ - simp - have hs' : ¬ MDiffAt (a • s) x := - fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) - rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] - simp - rfl - --- PRed and cleaned up in #34263 -set_option linter.flexible false in -- FIXME -lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) - (hs : MDiffAt s x) (v : TangentSpace I x) : - letI dsxv : 𝕜 := mfderiv% s x v - letI dfxv : F := mfderiv% f x v - mfderiv% (s • f) x v = (s x) • dfxv + dsxv • f x := by - set φ := chartAt H x - -- TODO: the next two have should be special cases of the same lemma - have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x - rw [← this] at hs - have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this - have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x - rw [← this] at hf - have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this - have hsf : MDiffAt (s • f) x := hs.smul hf - simp [mfderiv, hsf, hs, hf] - have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := - ModelWithCorners.uniqueDiffWithinAt_image I - erw [fderivWithin_smul uniq hs' hf'] - simp [φ.left_inv (ChartedSpace.mem_chart_source x)] - rfl end mfderiv @[expose] public section -- TODO: think if we want to expose all definitions! From ebd0377693ad87b2b4ec8ed13a6872bfedd736ef Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 15:51:18 +0000 Subject: [PATCH 468/601] reorganise variables in tensoriality file --- .../Manifold/VectorBundle/Extend.lean | 1 + .../Manifold/VectorBundle/Tensoriality.lean | 218 +++--------------- 2 files changed, 39 insertions(+), 180 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean index 8be3307cbe1d65..d33695f3dbaf2d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -92,6 +92,7 @@ lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M exact ContMDiffOn.smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 (contMDiffOn_localExtensionOn _ hx _) +-- TODO weaken regularity condition on `IsManifold` and `ContMDiffVectorBundle` hypotheses lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : MDiff (T% (extend I F σ₀)) := diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index d8a8050ae39641..5975a33a75976f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -20,32 +20,25 @@ open scoped Bundle Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M] +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [T2Space M] [IsManifold I ∞ M] -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] +variable -- `F` model fiber - (n : WithTop ℕ∞) + (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + -- `V` vector bundle (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] - -- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] [VectorBundle ℝ F V] - -- `V` vector bundle + [ContMDiffVectorBundle 1 F V I] + -variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] - (m : WithTop ℕ∞) +variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] [FiniteDimensional ℝ F] (V' : M → Type*) [TopologicalSpace (TotalSpace F' V')] [∀ x, AddCommGroup (V' x)] [∀ x, Module ℝ (V' x)] - [∀ x : M, TopologicalSpace (V' x)] - -- [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] -omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in -lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] - [ContMDiffVectorBundle 1 F V I] [FiniteDimensional ℝ E] - [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] - [IsManifold I ∞ M] +lemma tensoriality_criterion {φ : (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : σ x = σ' x) @@ -113,81 +106,7 @@ lemma tensoriality_criterion [FiberBundle F V] [VectorBundle ℝ F V] · exact fun i ↦ (hc hσ i).smul_section (hs i) include I in -omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in -lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] - [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] - [ContMDiffVectorBundle 1 F V I] - {φ : (Π x : M, V x) → (Π x, V' x)} {x} - {σ σ' : Π x : M, V x} - (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by - have locality {σ σ'} (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : - φ σ x = φ σ' x := by - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' - have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by - by_cases h : σ x = σ' x - · rw [Pi.smul_apply', Pi.smul_apply', h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - calc φ σ x - _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul] - _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] - _ = φ σ' x := by simp [φ_smul] - let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F - classical - have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) : - φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by - induction s using Finset.induction_on with - | empty => - simp only [Finset.sum_empty] - rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl, φ_smul] - simp - | insert a s ha h => - change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp only [Finset.sum_insert ha, ← h] - erw [φ_add] - have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) - let b := Basis.ofVectorSpace ℝ F - let t := trivializationAt F V x - let s := t.localFrame b - let c := t.localFrame_coeff (I := I) b - rw [locality (t.eventually_eq_localFrame_sum_coeff_smul (I := I) b x_mem)] - nth_rw 2 [locality (t.eventually_eq_localFrame_sum_coeff_smul (I := I) b x_mem)] - rw [sum_phi, sum_phi] - -- FIXME: the `erw` below can be made an `rw` by uncommenting this `change` - --change ∑ i, φ (((LinearMap.piApply (c i)) σ) • (s i)) x = - -- ∑ i, φ (((LinearMap.piApply (c i)) σ') • (s i)) x - congr with i - -- `erw?` says this is because of smul with a constant vs. a function `M → ℝ` - erw [φ_smul, φ_smul] - congr - -include I in -omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle ℝ F V] in -lemma tensoriality_criterion₂' [FiberBundle F V] [VectorBundle ℝ F V] - [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [ContMDiffVectorBundle 1 F V I] - [FiberBundle F' V'] [VectorBundle ℝ F' V'] - {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - {σ σ' τ τ' : Π x : M, V x} - (hσσ' : σ x = σ' x) - (hττ' : τ x = τ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ τ, φ (f • σ) τ x = f x • φ σ τ x) - (φ_add : ∀ σ σ' τ, φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ σ τ, φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by - trans φ σ' τ x - · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ - change φ1 σ x = φ1 σ' x - exact tensoriality_criterion' I F V F' V' hσσ' (by simp [φ_smul, φ1]) (by simp [φ_add, φ1]) - · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X - change φ1 τ x = φ1 τ' x - exact tensoriality_criterion' I F V F' V' hττ' (by simp [τ_smul, φ1]) (by simp [τ_add, φ1]) - -include I in -omit [IsManifold I 1 M] in -lemma tensoriality_criterion₂ [ContMDiffVectorBundle 1 F V I] [IsManifold I ∞ M] - [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] - [FiberBundle F' V'] [VectorBundle ℝ F' V'] +lemma tensoriality_criterion₂ {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' τ τ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) @@ -205,90 +124,29 @@ lemma tensoriality_criterion₂ [ContMDiffVectorBundle 1 F V I] [IsManifold I trans φ σ' τ x · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ change φ1 σ x = φ1 σ' x - apply tensoriality_criterion I F V F' V' hσ hσ' hσσ' + apply tensoriality_criterion I F V V' hσ hσ' hσσ' exacts [fun f σ hf hσ ↦ φ_smul hf hσ, fun σ σ' hσ hσ' ↦ φ_add hσ hσ'] · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X change φ1 τ x = φ1 τ' x - apply tensoriality_criterion I F V F' V' hτ hτ' hττ' + apply tensoriality_criterion I F V V' hτ hτ' hττ' exacts [fun f τ hf hτ ↦ τ_smul hf hτ, fun τ τ' hτ hτ' ↦ τ_add hτ hτ'] -/- include I in -lemma tensoriality_criterion'' [FiberBundle F V] [VectorBundle ℝ F V] [FiniteDimensional ℝ E] - [FiniteDimensional ℝ F] [FiberBundle F' V'] [VectorBundle ℝ F' V'] [T2Space M] - {φ : (Π x : M, V x) → (Π x, V' x)} {x} - {σ σ' : Π x : M, V x} - {Pσ : (Π x : M, V x) → Prop} - {Pσ_loc : ∀ σ σ', (∀ᶠ x' in 𝓝 x, σ x' = σ' x') → Pσ σ → Pσ σ'} - (hσ : Pσ σ) - (hσ' : Pσ σ') - {Pf : (M → ℝ) → Prop} - {Pf_loc : ∀ f f', (∀ᶠ x' in 𝓝 x, f x' = f' x') → Pf f → Pf f'} - (Pf_smooth : ∀ f, MDifferentiableAt I 𝓘(ℝ) f x → Pf f) - (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, Pf f → Pσ σ → φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', Pσ σ → Pσ σ → φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by - have locality {σ σ'} (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : - φ σ x = φ σ' x := by - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' - have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by - by_cases h : σ x = σ' x - · rw [Pi.smul_apply', Pi.smul_apply', h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - calc φ σ x - _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul] - _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] - _ = φ σ' x := by simp [φ_smul] - let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F - classical - have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) : - φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by - induction s using Finset.induction_on with - | empty => - simp only [Finset.sum_empty] - rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl, φ_smul] - simp - | insert a s ha h => - change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp [Finset.sum_insert ha, Finset.sum_insert ha, ← h] - erw [φ_add] - have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) - let b := Basis.ofVectorSpace ℝ F - let t := trivializationAt F V x - let s := b.localFrame (trivializationAt F V x) - let c := Basis.localFrame_coeff t b - rw [locality (b.localFrame_eventually_eq_sum_coeff_smul x_mem σ), - locality (b.localFrame_eventually_eq_sum_coeff_smul x_mem σ'), sum_phi, sum_phi] - change ∑ i, φ ((c i σ) • (s i)) x = ∑ i, φ ((c i σ') • (s i)) x - congr - ext i - rw [φ_smul, φ_smul] - congr - apply b.localFrame_coeff_congr - assumption - -/ - - section tensoriality -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] - (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [T2Space M] [ChartedSpace H M] [IsManifold I ∞ M] - variable - (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] [FiniteDimensional ℝ F] - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] [(x : M) → TopologicalSpace (V x)] + {V} -- TODO can probably remove the next two hypotheses, by transport [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] + -- TODO needed until `mdifferentiable_extend` is fixed to require the correct regularity + -- hypotheses + [ContMDiffVectorBundle ∞ F V I] variable - (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] - {V' : M → Type*} [TopologicalSpace (TotalSpace F' V')] [(x : M) → AddCommGroup (V' x)] - [(x : M) → Module ℝ (V' x)] [(x : M) → TopologicalSpace (V' x)] - -- TODO can probably remove the next two hypotheses, by transport - [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] + {V'} + -- TODO can probably remove the next three hypotheses, by transport + [∀ x : M, TopologicalSpace (V' x)] + [∀ x, IsTopologicalAddGroup (V' x)] + [∀ x, ContinuousSMul ℝ (V' x)] [FiberBundle F' V'] [VectorBundle ℝ F' V'] noncomputable def mkTensorAt @@ -307,7 +165,7 @@ noncomputable def mkTensorAt toFun v := φ (_root_.extend I F v) x map_add' v₁ v₂ := by rw [← φ_add] - · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add + · apply tensoriality_criterion I F _ _ _ _ _ φ_smul φ_add · exact mdifferentiable_extend .. · apply mdifferentiableAt_add_section · exact mdifferentiable_extend .. @@ -318,7 +176,7 @@ noncomputable def mkTensorAt map_smul' c v := by dsimp rw [← φ_smul (fun _ ↦ c)] - · apply tensoriality_criterion I F _ F' _ _ _ _ φ_smul φ_add + · apply tensoriality_criterion I F _ _ _ _ _ φ_smul φ_add · exact mdifferentiable_extend .. · apply MDifferentiableAt.smul_section · exact mdifferentiableAt_const @@ -335,8 +193,8 @@ theorem mkTensorAt_apply φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : - mkTensorAt I F F' φ x φ_smul φ_add (σ x) = φ σ x := by - apply tensoriality_criterion I F _ F' _ _ hσ _ φ_smul φ_add + mkTensorAt I F φ x φ_smul φ_add (σ x) = φ σ x := by + apply tensoriality_criterion I F _ _ _ hσ _ φ_smul φ_add · exact mdifferentiable_extend .. · simp @@ -348,7 +206,7 @@ noncomputable def mkTensor (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) (x : M) : V x →L[ℝ] V' x := - mkTensorAt I F F' φ x (φ_smul x) (φ_add x) + mkTensorAt I F φ x (φ_smul x) (φ_add x) theorem contMDiff_mkTensor (φ : (Π x : M, V x) → (Π x, V' x)) @@ -358,7 +216,7 @@ theorem contMDiff_mkTensor {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : -- elaborators not working here let T (x : M) : TotalSpace (F →L[ℝ] F') (fun x ↦ V x →L[ℝ] V' x) := - ⟨x, mkTensor I F F' φ φ_smul φ_add x⟩ + ⟨x, mkTensor I F φ φ_smul φ_add x⟩ ContMDiff I (I.prod 𝓘(ℝ, F →L[ℝ] F')) k T := by sorry @@ -383,7 +241,7 @@ noncomputable def mk2TensorAt (fun (v w : V x) ↦ φ (_root_.extend I F v) (_root_.extend I F w) x) := { add_left v₁ v₂ w := by rw [← σ_add] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add · exact mdifferentiable_extend .. · apply mdifferentiableAt_add_section · exact mdifferentiable_extend .. @@ -395,7 +253,7 @@ noncomputable def mk2TensorAt · exact mdifferentiable_extend .. smul_left c v w := by rw [← σ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add · exact mdifferentiable_extend .. · apply MDifferentiableAt.smul_section · exact mdifferentiableAt_const @@ -407,7 +265,7 @@ noncomputable def mk2TensorAt · exact mdifferentiable_extend .. add_right v w₁ w₂ := by rw [← τ_add] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. @@ -419,7 +277,7 @@ noncomputable def mk2TensorAt · exact mdifferentiable_extend .. smul_right c v w := by rw [← τ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. @@ -444,8 +302,8 @@ theorem mk2TensorAt_apply (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : - mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by - apply tensoriality_criterion₂ I F _ F' _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add + mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by + apply tensoriality_criterion₂ I F _ _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. · simp @@ -470,7 +328,7 @@ theorem mk2TensorAt_add ψ σ (f • τ) x = f x • ψ σ τ x) (ψ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : - mk2TensorAt I F F' (φ + ψ) + mk2TensorAt I F (φ + ψ) (fun {_ _ τ} hf hσ ↦ (congr($(φ_σ_smul hf hσ (τ := τ)) + $(ψ_σ_smul hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) (fun {σ₁ σ₂} τ hσ₁ hσ₂ ↦ @@ -483,8 +341,8 @@ theorem mk2TensorAt_add (congr($(φ_τ_add hτ₁ hτ₂ (σ := σ)) + $(ψ_τ_add hτ₁ hτ₂ (σ := σ)))).trans <| by dsimp abel) - = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add - + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by + = mk2TensorAt I F φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add + + mk2TensorAt I F ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by ext simp [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap] From fc9d99bc1b88fc6c117ad66bf5d722f07dc337b0 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 15:55:41 +0000 Subject: [PATCH 469/601] mkTensor_eq_extend --- .../Manifold/VectorBundle/Tensoriality.lean | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 5975a33a75976f..25dfee3af9a7d9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -198,6 +198,17 @@ theorem mkTensorAt_apply · exact mdifferentiable_extend .. · simp +variable {I} in +theorem mkTensorAt_apply_eq_extend + -- `φ` explicit to make it easier to generate the side conditions at point of use + {φ : (Π x : M, V x) → (Π x, V' x)} {x} + (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) x = f x • φ σ x) + (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') x = φ σ x + φ σ' x) (σ : V x) : + mkTensorAt I F φ x φ_smul φ_add σ = φ (_root_.extend I F σ) x := + rfl + noncomputable def mkTensor -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x, V' x)) @@ -309,6 +320,23 @@ theorem mk2TensorAt_apply · simp · simp +variable {I} in +theorem mk2TensorAt_apply_eq_extend + -- `φ` explicit to make it easier to generate the side conditions at point of use + {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + φ (f • σ) τ x = f x • φ σ τ x) + (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) + (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + φ σ (f • τ) x = f x • φ σ τ x) + (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + (σ τ : V x) : + mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add σ τ + = φ (_root_.extend I F σ) (_root_.extend I F τ) x := + rfl + theorem mk2TensorAt_add (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} (φ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → From ff07cbabb99429ca677b105edf43b8e93a1af012 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:06:31 +0000 Subject: [PATCH 470/601] fixes --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 4 ++-- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 4 ++-- .../Manifold/VectorBundle/CovariantDerivative/Torsion.lean | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 9a9586467e0b50..e26347c1ff197c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -442,7 +442,7 @@ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Spac (hcov' : IsCovariantDerivativeOn F cov' s) (x : M) : V x →L[ℝ] TangentSpace I x →L[ℝ] V x := if hxs : x ∈ s then - mkTensorAt I F (E →L[ℝ] F) (differenceAux cov cov') x + mkTensorAt I F (differenceAux cov cov') x (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.addσ hσ hσ', hcov'.addσ hσ hσ']; abel) else @@ -475,7 +475,7 @@ lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by simp only [difference, hx, reduceDIte] - rw [mkTensorAt_apply _ _ _ _ hσ] + rw [mkTensorAt_apply _ _ _ hσ] rfl end IsCovariantDerivativeOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 4ccbd183ca742d..081e7c1d8983b0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -710,7 +710,7 @@ open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] ℝ := - mk2TensorAt I E ℝ (fun (X Z : Π x : M, TangentSpace I x) ↦ + mk2TensorAt I E (fun (X Z : Π x : M, TangentSpace I x) ↦ if hX : MDiffAt (T% X) x then if hZ : MDiffAt (T% Z) x then leviCivitaRhs I X Y Z else 0 else 0) (x := x) @@ -751,7 +751,7 @@ theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : lcAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by unfold lcAux₀ - rw [mk2TensorAt_apply _ _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] + rw [mk2TensorAt_apply _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] noncomputable def lcAux₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index fa58a613f2175b..ff7138cda84d08 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -109,7 +109,7 @@ variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] noncomputable def torsionTensor (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := - mk2TensorAt I E E (Bundle.torsion cov) + mk2TensorAt I E (Bundle.torsion cov) (fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ) (fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ) (hcov.torsion_smul_right_apply) @@ -120,7 +120,7 @@ theorem torsionTensor_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : torsionTensor hcov x (X x) (Y x) = Bundle.torsion cov X Y x := by rw [torsionTensor] - refine mk2TensorAt_apply _ _ ?_ ?_ ?_ ?_ hX hY + refine mk2TensorAt_apply _ ?_ ?_ ?_ ?_ hX hY · exact fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ · exact fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ · exact hcov.torsion_smul_right_apply @@ -222,7 +222,7 @@ def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] (hY : MDiffAt (T% Y) x₀) (hY' : MDiffAt (T% Y') x₀) (hXX' : X x₀ = X' x₀) (hYY' : Y x₀ = Y' x₀) : (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by - apply tensoriality_criterion₂ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' + apply tensoriality_criterion₂ I E (TangentSpace I) (TangentSpace I) hX hX' hY hY' hXX' hYY' · intro f σ τ hf hσ exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ hf hσ · intro σ σ' τ hσ hσ' From bcc29b39ee67a72a452b20be4a357e5f12af5625 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:52:18 +0000 Subject: [PATCH 471/601] adjust implicit/explicit arguments in tensoriality for better inference --- .../CovariantDerivative/Torsion.lean | 10 +-- .../Manifold/VectorBundle/Tensoriality.lean | 67 ++++++++++--------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index ff7138cda84d08..2508cb203ebc25 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -112,19 +112,15 @@ noncomputable def torsionTensor (hcov : IsCovariantDerivativeOn E cov univ) (x : mk2TensorAt I E (Bundle.torsion cov) (fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ) (fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ) - (hcov.torsion_smul_right_apply) - (hcov.torsion_add_right_apply) + (fun {_ _} ↦ hcov.torsion_smul_right_apply) + (fun {_ _ _} ↦ hcov.torsion_add_right_apply) theorem torsionTensor_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : torsionTensor hcov x (X x) (Y x) = Bundle.torsion cov X Y x := by rw [torsionTensor] - refine mk2TensorAt_apply _ ?_ ?_ ?_ ?_ hX hY - · exact fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ - · exact fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ - · exact hcov.torsion_smul_right_apply - · exact hcov.torsion_add_right_apply + exact mk2TensorAt_apply _ ?_ ?_ ?_ ?_ hX hY end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 25dfee3af9a7d9..0a1083a689e9ba 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -35,7 +35,7 @@ variable variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] [FiniteDimensional ℝ F] - (V' : M → Type*) [TopologicalSpace (TotalSpace F' V')] + (V' : M → Type*) [∀ x, AddCommGroup (V' x)] [∀ x, Module ℝ (V' x)] lemma tensoriality_criterion @@ -113,23 +113,23 @@ lemma tensoriality_criterion₂ (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) - (φ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (φ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by trans φ σ' τ x · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ change φ1 σ x = φ1 σ' x apply tensoriality_criterion I F V V' hσ hσ' hσσ' - exacts [fun f σ hf hσ ↦ φ_smul hf hσ, fun σ σ' hσ hσ' ↦ φ_add hσ hσ'] + exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ'] · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X change φ1 τ x = φ1 τ' x apply tensoriality_criterion I F V V' hτ hτ' hττ' - exacts [fun f τ hf hτ ↦ τ_smul hf hτ, fun τ τ' hτ hτ' ↦ τ_add hτ hτ'] + exacts [fun f τ hf hτ ↦ τ_smul _ hf hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hτ hτ'] section tensoriality @@ -147,6 +147,7 @@ variable [∀ x : M, TopologicalSpace (V' x)] [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul ℝ (V' x)] + [TopologicalSpace (TotalSpace F' V')] [FiberBundle F' V'] [VectorBundle ℝ F' V'] noncomputable def mkTensorAt @@ -235,13 +236,13 @@ theorem contMDiff_mkTensor noncomputable def mk2TensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : V x →L[ℝ] V x →L[ℝ] V' x := let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x @@ -304,13 +305,13 @@ variable {I} in theorem mk2TensorAt_apply -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by @@ -324,13 +325,13 @@ variable {I} in theorem mk2TensorAt_apply_eq_extend -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (σ τ : V x) : mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add σ τ @@ -339,34 +340,36 @@ theorem mk2TensorAt_apply_eq_extend theorem mk2TensorAt_add (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (φ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (φ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (φ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (φ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (φ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (φ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) - (ψ_σ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (ψ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → ψ (f • σ) τ x = f x • ψ σ τ x) - (ψ_σ_add : ∀ {σ σ' τ}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) - (ψ_τ_smul : ∀ {f : M → ℝ}, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (ψ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → ψ σ (f • τ) x = f x • ψ σ τ x) - (ψ_τ_add : ∀ {σ τ τ'}, MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% τ) x → MDiffAt (T% τ') x → ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : mk2TensorAt I F (φ + ψ) (fun {_ _ τ} hf hσ ↦ - (congr($(φ_σ_smul hf hσ (τ := τ)) + $(ψ_σ_smul hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) - (fun {σ₁ σ₂} τ hσ₁ hσ₂ ↦ - (congr($(φ_σ_add hσ₁ hσ₂ (τ := τ)) + $(ψ_σ_add hσ₁ hσ₂ (τ := τ)))).trans <| by + (congr($(φ_σ_smul _ hf hσ (τ := τ)) + $(ψ_σ_smul _ hf hσ (τ := τ)))).trans + (smul_add _ _ _).symm) + (fun σ₁ σ₂ τ hσ₁ hσ₂ ↦ + (congr($(φ_σ_add _ _ _ hσ₁ hσ₂) + $(ψ_σ_add _ _ _ hσ₁ hσ₂))).trans <| by dsimp abel) (fun {_ σ _} hf hτ ↦ - (congr($(φ_τ_smul hf hτ (σ := σ)) + $(ψ_τ_smul hf hτ (σ := σ)))).trans (smul_add _ _ _).symm) + (congr($(φ_τ_smul _ hf hτ (σ := σ)) + $(ψ_τ_smul _ hf hτ (σ := σ)))).trans + (smul_add _ _ _).symm) (fun σ {τ₁ τ₂} hτ₁ hτ₂ ↦ - (congr($(φ_τ_add hτ₁ hτ₂ (σ := σ)) + $(ψ_τ_add hτ₁ hτ₂ (σ := σ)))).trans <| by + (congr($(φ_τ_add _ _ _ hτ₁ hτ₂) + $(ψ_τ_add _ _ _ hτ₁ hτ₂))).trans <| by dsimp abel) = mk2TensorAt I F φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add From 8d987f6d7275060a711a9f3e051b0a0def1fe4b9 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Wed, 4 Mar 2026 18:40:34 +0100 Subject: [PATCH 472/601] Refactor Torsion --- .../CovariantDerivative/LeviCivita.lean | 52 ++-- .../CovariantDerivative/Torsion.lean | 239 ++++++------------ .../CovariantDerivative/Torsion2.lean | 114 ++++----- .../Manifold/VectorBundle/Extend.lean | 5 + 4 files changed, 173 insertions(+), 237 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 081e7c1d8983b0..0684b3c5958615 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -35,7 +35,7 @@ set_option backward.isDefEq.respectTransparency false -- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. variable {n : WithTop ℕ∞} - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I ∞ M] [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] @@ -646,26 +646,27 @@ lemma leviCivitaRhs_smulZ_apply [CompleteSpace E] {f : M → ℝ} end leviCivitaRhs -variable (X Y Z) in -lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = - ⟪∇ X, Y, Z⟫ + ⟪Y, ∇ Z, X⟫ + ⟪Y, VectorField.mlieBracket I X Z⟫ := by - trans ⟪∇ X, Y, Z⟫ + ⟪Y, ∇ X, Z⟫ - · ext x - exact h.1 X Y Z x - · ext x - simp [← isTorsionFree_iff.mp h.2 X Z, product, inner_sub_right] - -variable (X Y Z) {cov} in +variable (Y) in +lemma aux (h : cov.IsLeviCivitaConnection) {x : M} + (hX : MDiffAt (T% X) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = + ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ Z, X⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by + trans ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + · exact h.1 X Y Z x + · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, + product, inner_sub_right] + +variable {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ -lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : - ⟪∇ X, Y, Z⟫ = leviCivitaRhs I X Y Z := by +lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) + {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + ⟪∇ X, Y, Z⟫ x = leviCivitaRhs I X Y Z x := by unfold leviCivitaRhs leviCivitaRhs' - have eq1 := aux I X Y Z cov h - have eq2 := aux I Y Z X cov h - have eq3 := aux I Z X Y cov h - simp [product_swap] at * - linear_combination (norm := module) -(2:ℝ)⁻¹ • (eq1 + eq2 - eq3) + have eq1 := aux I Y cov h hX hZ + have eq2 := aux I Z cov h hY hX + have eq3 := aux I X cov h hZ hY + rw [product_swap] at eq1 eq2 eq3 ⊢ + sorry -- linear_combination (norm := module) -(2:ℝ)⁻¹ • (eq1 + eq2 - eq3) section @@ -688,21 +689,22 @@ at least on differentiable vector fields. -/ -- (probably not everywhere, as addition rules apply only for differentiable vector fields?) theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] {cov cov' : CovariantDerivative I E (TangentSpace I : M → Type _)} - (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) : + (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) + {X Y : Π x : M, TangentSpace I x} {x : M} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : -- almost, only agree on smooth functions - cov = cov' := by - ext X x Y₀ + cov X x (Y x) = cov' X x (Y x) := by have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) apply Φ.injective ext Z₀ - let Y := _root_.extend I E Y₀ let Z := _root_.extend I E Z₀ - suffices inner ℝ (cov X x (Y x)) (Z x) = inner ℝ (cov' X x (Y x)) (Z x) by simpa [Φ, Y, Z] + have hZ := mdifferentiableAt_extend I E Z₀ x + suffices inner ℝ (cov X x (Y x)) (Z x) = inner ℝ (cov' X x (Y x)) (Z x) by simpa [Φ, Z] trans leviCivitaRhs I X Y Z x - · exact congr($(hcov.eq_leviCivitaRhs I X Y Z) x) - · exact congr($((hcov'.eq_leviCivitaRhs I X Y Z).symm) x) + · rw [← hcov.eq_leviCivitaRhs I hX hY hZ] + · rw [← hcov'.eq_leviCivitaRhs I hX hY hZ] variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 2508cb203ebc25..90a1d73bf57668 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -34,7 +34,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -- TODO: where is a good namespace for this? /-- The torsion of a covariant derivative on the tangent bundle `TM` -/ -noncomputable def Bundle.torsion +noncomputable def Bundle.torsionFun (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := fun X Y x ↦ cov X x (Y x) - cov Y x (X x) - VectorField.mlieBracket I X Y x @@ -44,14 +44,14 @@ variable {X X' Y : Π x : M, TangentSpace I x} variable (f X) in -lemma torsion_self : torsion cov X X = 0 := by +lemma torsionFun_self : torsionFun cov X X = 0 := by ext - simp [torsion] + simp [torsionFun] variable (X Y) in -lemma torsion_antisymm : torsion cov X Y = - torsion cov Y X := by +lemma torsionFun_antisymm : torsionFun cov X Y = - torsionFun cov Y X := by ext x - unfold torsion + unfold torsionFun rw [VectorField.mlieBracket_swap] dsimp module @@ -61,24 +61,24 @@ namespace IsCovariantDerivativeOn variable [IsManifold I ∞ M] {U : Set M} variable (Y) in -lemma torsion_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) +lemma torsionFun_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : - torsion cov (X + X') Y x = torsion cov X Y x + torsion cov X' Y x := by - simp [torsion, hcov.addσ hX hX', VectorField.mlieBracket_add_left hX hX'] + torsionFun cov (X + X') Y x = torsionFun cov X Y x + torsionFun cov X' Y x := by + simp [torsionFun, hcov.addσ hX hX', VectorField.mlieBracket_add_left hX hX'] module -lemma torsion_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) +lemma torsionFun_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : - torsion cov Y (X + X') x = torsion cov Y X x + torsion cov Y X' x := by - rw [torsion_antisymm, Pi.neg_apply, - hcov.torsion_add_left_apply _ hX hX', torsion_antisymm Y, torsion_antisymm Y] + torsionFun cov Y (X + X') x = torsionFun cov Y X x + torsionFun cov Y X' x := by + rw [torsionFun_antisymm, Pi.neg_apply, + hcov.torsionFun_add_left_apply _ hX hX', torsionFun_antisymm Y, torsionFun_antisymm Y] simp; abel variable (Y) in -lemma torsion_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) +lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : - torsion cov (f • X) Y x = f x • torsion cov X Y x := by - simp only [torsion] + torsionFun cov (f • X) Y x = f x • torsionFun cov X Y x := by + simp only [torsionFun] rw [hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] simp? [bar, smul_sub] says simp only [bar, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, @@ -88,177 +88,106 @@ lemma torsion_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn set A := f x • (cov X x) (Y x) set B := f x • (cov Y x) (X x) set C := f x • VectorField.mlieBracket I X Y x - sorry /-simp only [torsion, Pi.sub_apply, hF.smulX (X := X) (σ := Y) (f := f)] + sorry /-simp only [torsionFun, Pi.sub_apply, hF.smulX (X := X) (σ := Y) (f := f)] rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] simp [bar, smul_sub] abel -/ -lemma torsion_smul_right_apply [CompleteSpace E] +lemma torsionFun_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) (hx : x ∈ U := by trivial) : - torsion F X (f • Y) x = f x • torsion F X Y x := by - rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hf hX, torsion_antisymm X] + torsionFun F X (f • Y) x = f x • torsionFun F X Y x := by + rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply X hf hX, torsionFun_antisymm X] simp -end IsCovariantDerivativeOn section variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] -noncomputable def torsionTensor (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : +noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := - mk2TensorAt I E (Bundle.torsion cov) - (fun {_ _ τ} ↦ hcov.torsion_smul_left_apply τ) - (fun {_ _ τ} ↦ hcov.torsion_add_left_apply τ) - (fun {_ _} ↦ hcov.torsion_smul_right_apply) - (fun {_ _ _} ↦ hcov.torsion_add_right_apply) + mk2TensorAt I E (Bundle.torsionFun cov) + (fun {_ _ τ} ↦ hcov.torsionFun_smul_left_apply τ) + (fun {_ _ τ} ↦ hcov.torsionFun_add_left_apply τ) + (fun {_ _} ↦ hcov.torsionFun_smul_right_apply) + (fun {_ _ _} ↦ hcov.torsionFun_add_right_apply) -theorem torsionTensor_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} +theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : - torsionTensor hcov x (X x) (Y x) = Bundle.torsion cov X Y x := by - rw [torsionTensor] - exact mk2TensorAt_apply _ ?_ ?_ ?_ ?_ hX hY - -end - -/-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ -noncomputable def IsTorsionFreeOn - (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) - (U : Set M) : Prop := - ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsion cov X Y x = 0 - -namespace IsTorsionFreeOn - -section changing_set - -/-! Changing set -In this changing we change `s` in `IsTorsionFreeOn F f s`. --/ - -lemma mono {s t : Set M} (hf : IsTorsionFreeOn cov t) (hst : s ⊆ t) : IsTorsionFreeOn cov s := - fun _ hx _ _ ↦ hf _ (hst hx) .. - -lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn cov (s i)) : - IsTorsionFreeOn cov (⋃ i, s i) := by - rintro x ⟨si, ⟨i, hi⟩, hxsi⟩ X Y - exact hf i x (by simp [hi, hxsi]) X Y - -end changing_set - -/- Congruence properties -/ -section - --- unused? -lemma congr {s : Set M} (h : IsTorsionFreeOn cov s) - (hfg : ∀ {X Y : Π x : M, TangentSpace I x}, ∀ {x}, x ∈ s → cov X x (Y x) = cov' X x (Y x)) : - IsTorsionFreeOn cov' s := by - intro x hx X Y - specialize h x hx X Y - -- now, use torsion congruence lemma, i.e. tensoriality of sorts! - -- TODO: generalise tensoriality to the local setting! - sorry + torsion hcov x (X x) (Y x) = Bundle.torsionFun cov X Y x := + mk2TensorAt_apply _ _ _ _ _ hX hY end -end IsTorsionFreeOn +end IsCovariantDerivativeOn +-- /-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ +-- noncomputable def IsTorsionFreeOn +-- (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) +-- (U : Set M) : Prop := +-- ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsionFun cov X Y x = 0 +-- +-- namespace IsTorsionFreeOn +-- +-- section changing_set +-- +-- /-! Changing set +-- In this changing we change `s` in `IsTorsionFreeOn F f s`. +-- -/ +-- +-- lemma mono {s t : Set M} (hf : IsTorsionFreeOn cov t) (hst : s ⊆ t) : IsTorsionFreeOn cov s := +-- fun _ hx _ _ ↦ hf _ (hst hx) .. +-- +-- lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn cov (s i)) : +-- IsTorsionFreeOn cov (⋃ i, s i) := by +-- rintro x ⟨si, ⟨i, hi⟩, hxsi⟩ X Y +-- exact hf i x (by simp [hi, hxsi]) X Y +-- +-- end changing_set +-- +-- end IsTorsionFreeOn namespace CovariantDerivative +open VectorField -variable [IsManifold I ∞ M] --- The torsion tensor of a covariant derivative on the tangent bundle `TM`. -variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} - -variable {U : Set M} (hf : IsCovariantDerivativeOn E cov U) - --- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! -variable (f) in -@[simp] -lemma torsion_zero : torsion cov 0 X = 0 := by - ext x - simp [torsion] +variable [IsManifold I ∞ M] [FiniteDimensional ℝ E] [T2Space M] +variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) +/-- The torsion tensor of a covariant derivative on the tangent bundle of a manifold. -/ +noncomputable def torsion := cov.isCovariantDerivativeOn.torsion -@[simp] -lemma torsion_zero' : torsion cov X 0 = 0 := by - rw [torsion_antisymm, torsion_zero]; simp - -variable (Y) in -lemma torsion_add_left [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : - torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (hX x) (hX' x) - -lemma torsion_add_right [CompleteSpace E] - (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : - torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by - rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module +lemma torsion_vector_field_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : + cov.torsion x (X x) (Y x) = cov X x (Y x) - cov Y x (X x) - mlieBracket I X Y x := by + unfold torsion IsCovariantDerivativeOn.torsion + apply mk2TensorAt_apply + exacts [hX, hY] -variable (Y) in -lemma torsion_smul_left [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hX : MDiff (T% X)) : - torsion cov (f • X) Y = f • torsion cov X Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (hf x) (hX x) +lemma torsion_apply (u v : TangentSpace I x) : + cov.torsion x u v = cov (extend I E u) x (extend I E v x) + - cov (extend I E v) x (extend I E u x) + - mlieBracket I (extend I E u) (extend I E v) x := by + unfold torsion IsCovariantDerivativeOn.torsion + apply mk2TensorAt_apply_eq_extend -variable (X) in -lemma torsion_smul_right [CompleteSpace E] {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) : - torsion cov X (f • Y) = f • torsion cov X Y := by - ext x - exact cov.isCovariantDerivativeOn.torsion_smul_right_apply (hf x) (hY x) - -/-- The torsion of a covariant derivative is tensorial: -the value of `torsion cov X Y` at `x₀` depends only on `X x₀` and `Y x₀`. -/ -def torsion_tensorial [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] - [FiniteDimensional ℝ F] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] - {X X' Y Y' : Π x : M, TangentSpace I x} {x₀ : M} - (hX : MDiffAt (T% X) x₀) (hX' : MDiffAt (T% X') x₀) - (hY : MDiffAt (T% Y) x₀) (hY' : MDiffAt (T% Y') x₀) - (hXX' : X x₀ = X' x₀) (hYY' : Y x₀ = Y' x₀) : - (torsion cov X Y) x₀ = (torsion cov X' Y') x₀ := by - apply tensoriality_criterion₂ I E (TangentSpace I) (TangentSpace I) hX hX' hY hY' hXX' hYY' - · intro f σ τ hf hσ - exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ hf hσ - · intro σ σ' τ hσ hσ' - exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ hσ hσ' - · intros f σ σ' hf hσ' - exact cov.isCovariantDerivativeOn.torsion_smul_right_apply hf hσ' - · intro σ τ τ' hτ hτ' - exact cov.isCovariantDerivativeOn.torsion_add_right_apply hτ hτ' - --- TODO: relate torsion-freeness to torsion tensor --- (That will not work for torsion-freeness on a set, though.) - --- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, --- so it would apply here as well - -variable (cov) in /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ def IsTorsionFree : Prop := torsion cov = 0 -@[simp] -lemma isTorsionFreeOn_univ : IsTorsionFreeOn cov univ ↔ IsTorsionFree cov := by - simp only [IsTorsionFree, IsTorsionFreeOn] - refine ⟨fun h ↦ ?_, fun h ↦ by simp [h]⟩ - ext X Y x - simp [h x] - -/-- If a covariant derivative `cov` is torsion-free on each set in an open cover, -it is torsion-free. -/ -def of_isTorsionFreeOn_of_open_cover {ι : Type*} {s : ι → Set M} - (hf : ∀ i, IsTorsionFreeOn cov (s i)) (hs : ⋃ i, s i = Set.univ) : - IsTorsionFree cov := by - rw [← isTorsionFreeOn_univ, ← hs] - exact IsTorsionFreeOn.iUnion hf - -lemma isTorsionFree_def : IsTorsionFree cov ↔ torsion cov = 0 := by simp [IsTorsionFree] - --- This should be obvious; am I doing something wrong? lemma isTorsionFree_iff : IsTorsionFree cov ↔ - ∀ X Y x, cov X x (Y x) - cov Y x (X x) = VectorField.mlieBracket I X Y x := by - unfold IsTorsionFree torsion - simp [funext_iff, sub_eq_iff_eq_add'] + ∀ {X Y x}, MDiffAt (T% X) x → MDiffAt (T% Y) x → + cov X x (Y x) - cov Y x (X x) = mlieBracket I X Y x := by + unfold IsTorsionFree + constructor + · intro h X Y x hX hY + replace h := congr($h x (X x) (Y x)) + rw [cov.torsion_vector_field_apply hX hY] at h + simpa [sub_eq_iff_eq_add'] using h + · intro h + ext x u v + rw [torsion_apply, h] + · simp + · apply mdifferentiableAt_extend + · apply mdifferentiableAt_extend end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean index aa6e6a1e6cac8e..b61b44f08240f8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean @@ -42,63 +42,63 @@ variable [IsManifold I ∞ M] variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} {U : Set M} (hf : IsCovariantDerivativeOn E cov U) -variable {n} in -lemma aux1 {ι : Type*} [Fintype ι] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) - (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.coeff i) x (X x) • torsion f (s i) Y x := - have hU : U ∈ 𝓝 x := sorry - have aux := hs.eventually_eq_sum_coeff_smul X hU - have hX : X x = ∑ i, (hs.coeff i) x (X x) • s i x := sorry - calc torsion f X Y x - _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) x (X x) • s i x) Y x := by - sorry -- tensoriality and [hX] - _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) x (X x) • s i x) Y x) := sorry - _ = ∑ i, (hs.coeff i) x (X x) • (torsion f (s i) Y x) := sorry - --- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x -variable {n} in -lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} - (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) - (X Y : (x : M) → TangentSpace I x) : - torsion f X Y x = ∑ i, (hs.coeff i) x (Y x) • torsion f X (s i) x := - have hU : U ∈ 𝓝 x := sorry - have aux := hs.eventually_eq_sum_coeff_smul Y hU - have hY : Y x = ∑ i, (hs.coeff i) x (Y x) • s i x := hs.coeff_sum_eq Y hx - calc torsion f X Y x - _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) x (Y x) • s i x) x := by - sorry -- tensoriality and [hY] - _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) x (Y x) • s i x) x) := sorry - _ = ∑ i, (hs.coeff i) x (Y x) • (torsion f X (s i) x) := by - congr with i - have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry - have hsi' : MDiffAt (T% (s i)) x := sorry - have := hf.torsion_smul_right_apply (X := X) (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' - erw [← this] - congr - -/-- We can test torsion-freeness on a set using a local frame. -/ -lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame - {ι : Type*} [Fintype ι] [CompleteSpace E] - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {U : Set M} {s : ι → (x : M) → TangentSpace I x} - (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : - IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by - rw [IsTorsionFreeOn] - refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ - intro x hx X Y - rw [aux1 hs hx] - calc - _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • torsion f (s i) (s j) x := by - congr! - rw [aux2 hf hs hx] - _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • 0 := by - congr! with i _ j _ - exact h i j x hx - _ = 0 := by simp +-- variable {n} in +-- lemma aux1 {ι : Type*} [Fintype ι] +-- {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} +-- {U : Set M} {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) +-- (X Y : (x : M) → TangentSpace I x) : +-- torsion f X Y x = ∑ i, (hs.coeff i) x (X x) • torsion f (s i) Y x := +-- have hU : U ∈ 𝓝 x := sorry +-- have aux := hs.eventually_eq_sum_coeff_smul X hU +-- have hX : X x = ∑ i, (hs.coeff i) x (X x) • s i x := sorry +-- calc torsion f X Y x +-- _ = torsion f (fun x ↦ ∑ i, (hs.coeff i) x (X x) • s i x) Y x := by +-- sorry -- tensoriality and [hX] +-- _ = ∑ i, (torsion f (fun x ↦ (hs.coeff i) x (X x) • s i x) Y x) := sorry +-- _ = ∑ i, (hs.coeff i) x (X x) • (torsion f (s i) Y x) := sorry +-- +-- -- Weaker hypotheses possible, e.g. local frame on U ∈ 𝓝 x, while a cov. derivative on s ∋ x +-- variable {n} in +-- lemma aux2 {ι : Type*} [Fintype ι] [CompleteSpace E] +-- {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} +-- {U : Set M} {s : ι → (x : M) → TangentSpace I x} +-- (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x ∈ U) +-- (X Y : (x : M) → TangentSpace I x) : +-- torsion f X Y x = ∑ i, (hs.coeff i) x (Y x) • torsion f X (s i) x := +-- have hU : U ∈ 𝓝 x := sorry +-- have aux := hs.eventually_eq_sum_coeff_smul Y hU +-- have hY : Y x = ∑ i, (hs.coeff i) x (Y x) • s i x := hs.coeff_sum_eq Y hx +-- calc torsion f X Y x +-- _ = torsion f X (fun x ↦ ∑ i, (hs.coeff i) x (Y x) • s i x) x := by +-- sorry -- tensoriality and [hY] +-- _ = ∑ i, (torsion f X (fun x ↦ (hs.coeff i) x (Y x) • s i x) x) := sorry +-- _ = ∑ i, (hs.coeff i) x (Y x) • (torsion f X (s i) x) := by +-- congr with i +-- have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry +-- have hsi' : MDiffAt (T% (s i)) x := sorry +-- have := hf.torsion_smul_right_apply (X := X) (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' +-- erw [← this] +-- congr +-- +-- /-- We can test torsion-freeness on a set using a local frame. -/ +-- lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame +-- {ι : Type*} [Fintype ι] [CompleteSpace E] +-- {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} +-- {U : Set M} {s : ι → (x : M) → TangentSpace I x} +-- (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : +-- IsTorsionFreeOn f U ↔ ∀ i j, ∀ x ∈ U, torsion f (s i) (s j) x = 0 := by +-- rw [IsTorsionFreeOn] +-- refine ⟨fun h i j x hx ↦ h x hx (s i) (s j), fun h ↦ ?_⟩ +-- intro x hx X Y +-- rw [aux1 hs hx] +-- calc +-- _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • torsion f (s i) (s j) x := by +-- congr! +-- rw [aux2 hf hs hx] +-- _ = ∑ i, (hs.coeff i) x (X x) • ∑ j, (hs.coeff j) x (Y x) • 0 := by +-- congr! with i _ j _ +-- exact h i j x hx +-- _ = 0 := by simp -- lemma the trivial connection on a normed space is torsion-free -- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle 𝓘(ℝ, E) E) := sorry diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean index d33695f3dbaf2d..79047fd29836eb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -98,6 +98,11 @@ lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2S MDiff (T% (extend I F σ₀)) := contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) +lemma mdifferentiableAt_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] + [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) (x' : M) : + MDiffAt (T% (extend I F σ₀)) x' := + mdifferentiable_extend I F σ₀ |>.mdifferentiableAt + theorem contDiff_extend {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] From 998297c848936f46bda0686851af9d1166068b9c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 20:31:50 +0000 Subject: [PATCH 473/601] Tiny fixes --- .../CovariantDerivative/Ehresmann.lean | 18 ++++++++---------- .../VectorBundle/CovariantDerivative/Lift.lean | 1 - .../CovariantDerivative/Torsion.lean | 6 +++--- .../CovariantDerivative/Trivial.lean | 3 ++- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index f6a348210beb90..47cb384585a1c6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -173,11 +173,13 @@ lemma pushCovDer_isCovariantDerivativeOn IsCovariantDerivativeOn F (e.pushCovDer cov) u where addσ {σ σ' x} hσ hσ' hx := by set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ + have hs : MDiffAt (T% s) x := by + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| + --mdifferentiableAt_section_trivial_iff.1 hσ set s' := (fun x' ↦ e.symm x' (σ' x')) have hs' : MDiffAt (T% s') x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ' + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| + --mdifferentiableAt_section_trivial_iff.1 hσ' unfold Trivialization.pushCovDer stop rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] @@ -187,7 +189,8 @@ lemma pushCovDer_isCovariantDerivativeOn leibniz {σ g x} hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ + sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| + --mdifferentiableAt_section_trivial_iff.1 hσ unfold Trivialization.pushCovDer have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by ext y @@ -223,8 +226,7 @@ lemma coordChangeL_pushCovDer ↓reduceIte, Function.comp_apply, hx.2] refold_let σ have : e.symm x (e ⟨x, cov σ x X₀⟩).2 = cov σ x X₀ := by - -- TODO fix `simp [hx.1]` not working - exact symm_apply_apply_mk e hx.1 (cov σ x X₀) + simp [hx.1] stop rw [this] -- TODO: extract lemma? @@ -368,8 +370,6 @@ lemma isCovariantDerivativeOn_pushCovDer e.pushCovDer_isCovariantDerivativeOn subset_rfl (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) - - lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : letI t := trivializationAt F V v.proj @@ -379,7 +379,6 @@ lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : (t <| cov.proj v u).2 = tproj (Tvt u) := by simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] - noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := (cov.proj v).ker @@ -404,7 +403,6 @@ lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalS change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 simp - omit [ContMDiffVectorBundle 1 F V I] in lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] (cov : CovariantDerivative I F V) (v : TotalSpace F V) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index b95742ad05b4e1..39943001be6d7c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -178,7 +178,6 @@ lemma CovariantDerivative.mfderiv_proj_lift_vec {v : TotalSpace F V} (u : Tangen unfold CovariantDerivative.lift_vec simp [FiberBundle.mem_baseSet_trivializationAt' v.proj] - lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace I v.proj) (w : TangentSpace (I.prod 𝓘(ℝ, F)) v) : cov.lift_vec v u = w ↔ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 90a1d73bf57668..bac5fc0d1bd3c4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -84,7 +84,7 @@ lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative simp only [bar, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk, Function.comp_apply, - ContinuousLinearMap.toSpanSingleton_apply, Pi.smul_apply', map_smul, neg_smul, smul_sub] + ContinuousLinearMap.toSpanSingleton_apply, Pi.smul_apply', map_smul, smul_sub] set A := f x • (cov X x) (Y x) set B := f x • (cov Y x) (X x) set C := f x • VectorField.mlieBracket I X Y x @@ -98,10 +98,10 @@ lemma torsionFun_smul_right_apply [CompleteSpace E] (hF : IsCovariantDerivativeOn E F U) {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) (hx : x ∈ U := by trivial) : torsionFun F X (f • Y) x = f x • torsionFun F X Y x := by - rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply X hf hX, torsionFun_antisymm X] + rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply X hf hX, + torsionFun_antisymm X] simp - section variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index 996a463bde5185..30f2f6d7e23215 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -88,7 +88,8 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] -- regularity and use ∞ from `open scoped ContDiff` instead. /-- The trivial connection on the trivial bundle is smooth -/ -lemma trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where +lemma trivial_isSmooth : + ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where contMDiff := by -- {X σ} hX hσ sorry /- -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well From 3a342e2f1816b3349ec6c2a34460856f7c282ae3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 20:47:40 +0000 Subject: [PATCH 474/601] chore: fix some unused variable warnings --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0684b3c5958615..e30fe1bb44e77d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -35,7 +35,7 @@ set_option backward.isDefEq.respectTransparency false -- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. variable {n : WithTop ℕ∞} - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I ∞ M] [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] @@ -196,7 +196,7 @@ iff it is torsion-free and compatible with `g`. Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a version depending on a choice of Riemannian metric on `M`. -/ -def IsLeviCivitaConnection : Prop := cov.IsCompatible ∧ cov.IsTorsionFree +def IsLeviCivitaConnection [FiniteDimensional ℝ E] : Prop := cov.IsCompatible ∧ cov.IsTorsionFree variable (X Y Z) in /-- The first term in the definition of the candidate Levi-Civita connection: @@ -646,6 +646,7 @@ lemma leviCivitaRhs_smulZ_apply [CompleteSpace E] {f : M → ℝ} end leviCivitaRhs +variable [FiniteDimensional ℝ E] in variable (Y) in lemma aux (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = @@ -658,7 +659,8 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} variable {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term ⟨∇ X Y, Z⟩ for all differentiable vector fields X, Y and Z, without reference to ∇. -/ -lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) +lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional ℝ E] + (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : ⟪∇ X, Y, Z⟫ x = leviCivitaRhs I X Y Z x := by unfold leviCivitaRhs leviCivitaRhs' From 6020d16236f532978fcb9171ef0e43907958f816 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 20:50:47 +0000 Subject: [PATCH 475/601] Checkpoint: refacoring compatibility of a connection to use a tensor --- .../CovariantDerivative/LeviCivita.lean | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e30fe1bb44e77d..b1fe2caa3808b0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -183,6 +183,97 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) local notation "∇" X "," Y => fun (x:M) ↦ cov X x (Y x) +/- +-- kept for archival purposes +noncomputable example [FiniteDimensional ℝ E] (Y Z : Π x : M, TangentSpace I x) (x : M) : + TangentSpace I x →L[ℝ] ℝ := + have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ + let Zflat : TangentSpace I x →L[ℝ] ℝ := + (InnerProductSpace.toDual ℝ (TangentSpace I x)) (Z x) + let A : TangentSpace I x →L[ℝ] TangentSpace I x := cov Y x + Zflat ∘L A + +-- Given two vector fields `Y` and `Z`, compute the 1-form `g(∇. Y, Z)`. +noncomputable def foo [FiniteDimensional ℝ E] (Y Z : Π x : M, TangentSpace I x) (x : M) : + TangentSpace I x →L[ℝ] ℝ := + (innerSL ℝ (Z x)) ∘L (cov Y x) -/ + +noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : + Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ + letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x + b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +noncomputable example {x : M} [FiniteDimensional ℝ E] : + TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := by + apply mk2TensorAt I E (myfun I cov) + · intro f σ τ hf hσ + unfold myfun + rw [product_smul_left] + --simp only [smul_eq_mul] + --erw [mfderiv_smul] + rw [cov.isCovariantDerivativeOn.leibniz hσ hf] + ext X + simp + sorry + · intro σ σ' τ hσ hσ' + have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? + simp only [myfun] + ext X + simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, + Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] + rw [product_add_left, + mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), + cov.isCovariantDerivativeOn.addσ hσ hσ', + ContinuousLinearMap.comp_add, ContinuousLinearMap.coe_sub', Pi.sub_apply, + ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] + -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x + -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) + -- set B' := ((innerSL ℝ) (τ x)).comp (cov σ' x) + -- set C := inner ℝ (σ x) ((cov τ x) X) + -- set C' := inner ℝ (σ' x) ((cov τ x) X) + erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, + ContinuousLinearMap.sub_apply] + -- bug: abel fails, but module works + module + · intro f σ τ hf hτ + simp only [myfun] + ext X + dsimp + rw [map_smul (innerSL ℝ) (f x) (τ x), product_smul_right] + have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis? + have aux := mfderiv_smul (s := f) (f := ⟪σ, τ⟫) (I := I) (x := x) (hσ.inner_bundle' hτ) hf + set A := (f x • (innerSL ℝ) (τ x)).comp (cov σ x) + set B := mfderiv I 𝓘(ℝ, ℝ) (f • ⟪σ, τ⟫) x + -- issue: A and B live in different tangent spaces, so cannot simply expand and apply aux... + -- next steps: apply the Leibniz rule, collect the other terms and suffer some more + sorry + · intro σ τ τ' hτ hτ' + have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis! + unfold myfun + ext X + simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', + ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, + ContinuousLinearMap.add_apply] + rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), + cov.isCovariantDerivativeOn.addσ hτ hτ'] + dsimp + rw [inner_add_right] + set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x + set B := ((innerSL ℝ) (τ x)).comp (cov σ x) + set B' := ((innerSL ℝ) (τ' x)).comp (cov σ x) + set C := inner ℝ (σ x) ((cov τ x) X) + set C' := inner ℝ (σ x) ((cov τ' x) X) + set D := (cov σ x) X + erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, + ContinuousLinearMap.sub_apply] + -- The goal is false now, what? + sorry -- module + +-- old version of the definition. TODO: replace by the tensor ∇ g being zero! /-- Predicate saying for a connection `∇` on a Riemannian manifold `M` to be compatible with the ambient metric, i.e. for all smooth vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ From 4d611254bfa95e542c26d1e4d439c465128e7819 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 21:44:02 +0000 Subject: [PATCH 476/601] Remove one superfluous backwards option --- .../Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean | 1 - .../Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean | 1 - 2 files changed, 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 47cb384585a1c6..c4795570a00c50 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -139,7 +139,6 @@ def pushCovDer (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (e.funToSec σ) x) -set_option backward.isDefEq.respectTransparency false in lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index 6643c3fc711fa3..e93353d0713114 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -378,7 +378,6 @@ def derivInv (v : TotalSpace F V) : TangentSpace I v.proj × F →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) v := mfderiv (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e.invFun (e v) - set_option backward.isDefEq.respectTransparency false in @[simp] lemma derivInv_deriv From 64f4d84094f5f601c9849691d5e966a29d443e5f Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 21:15:36 +0000 Subject: [PATCH 477/601] fix broken linear_combination proof --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index b1fe2caa3808b0..ee6d2c4c834286 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -758,8 +758,8 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional ℝ E] have eq1 := aux I Y cov h hX hZ have eq2 := aux I Z cov h hY hX have eq3 := aux I X cov h hZ hY - rw [product_swap] at eq1 eq2 eq3 ⊢ - sorry -- linear_combination (norm := module) -(2:ℝ)⁻¹ • (eq1 + eq2 - eq3) + simp [real_inner_comm, smul_eq_mul] at * + linear_combination - (eq1 + eq2 - eq3) / 2 section From 68c4d6629515eb753b52213ff7838c420211270d Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 23:02:52 +0000 Subject: [PATCH 478/601] fix broken proof in compatibility tensor --- .../CovariantDerivative/LeviCivita.lean | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ee6d2c4c834286..4349cd626bbe6b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -204,6 +204,7 @@ noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) +set_option maxHeartbeats 400000 in variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in noncomputable example {x : M} [FiniteDimensional ℝ E] : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := by @@ -261,17 +262,23 @@ noncomputable example {x : M} [FiniteDimensional ℝ E] : cov.isCovariantDerivativeOn.addσ hτ hτ'] dsimp rw [inner_add_right] - set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x - set B := ((innerSL ℝ) (τ x)).comp (cov σ x) - set B' := ((innerSL ℝ) (τ' x)).comp (cov σ x) - set C := inner ℝ (σ x) ((cov τ x) X) - set C' := inner ℝ (σ x) ((cov τ' x) X) - set D := (cov σ x) X - erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, - ContinuousLinearMap.sub_apply] - -- The goal is false now, what? - sorry -- module + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.add_apply] + erw [ContinuousLinearMap.comp_apply] + conv => + enter [2, 2, 1, 2] + erw [ContinuousLinearMap.comp_apply] + erw [innerSL_apply_apply] + conv => + enter [2, 2, 1, 2] + erw [innerSL_apply_apply] + -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x + -- set C := inner ℝ (σ x) ((cov τ x) X) + -- set C' := inner ℝ (σ x) ((cov τ' x) X) + -- set D := (cov σ x) X + module -- old version of the definition. TODO: replace by the tensor ∇ g being zero! /-- Predicate saying for a connection `∇` on a Riemannian manifold `M` to be compatible with the From 1f4db0d83ef77fb297b17faacb08e7f0a2af095c Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Wed, 4 Mar 2026 23:41:53 +0000 Subject: [PATCH 479/601] scalar multiplication proof --- .../CovariantDerivative/LeviCivita.lean | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 4349cd626bbe6b..8f655ff0982679 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -204,7 +204,7 @@ noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) -set_option maxHeartbeats 400000 in +set_option maxHeartbeats 800000 in variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in noncomputable example {x : M} [FiniteDimensional ℝ E] : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := by @@ -216,8 +216,37 @@ noncomputable example {x : M} [FiniteDimensional ℝ E] : --erw [mfderiv_smul] rw [cov.isCovariantDerivativeOn.leibniz hσ hf] ext X - simp - sorry + simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, + RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, + ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', + coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.comp_apply] + conv => + enter [1, 1, 2] + erw [ContinuousLinearMap.add_apply] + conv => + enter [1, 1, 2, 1] + erw [ContinuousLinearMap.smul_apply] + rw [ContinuousLinearMap.comp_apply] + rw [ContinuousLinearMap.comp_apply] + rw [ContinuousLinearMap.comp_apply] + rw [ContinuousLinearMap.comp_apply] + rw [innerSL_apply_apply] + rw [innerSL_apply_apply] + rw [ContinuousLinearMap.toSpanSingleton_apply] + rw [inner_smul_right] + rw [mfderiv_smul _ hf] + · simp only [smul_eq_mul, Pi.mul_apply, bar, ContinuousLinearEquiv.coe_coe, + ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] + conv => + enter [1, 1, 1, 2, 2] + dsimp [product] + rw [real_inner_comm] + rw [← sub_eq_zero] + ring + sorry -- missing hypothesis needed for this differentiability goal? · intro σ σ' τ hσ hσ' have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? simp only [myfun] From bc94c874b0946f86070c47fda0c86474681ae730 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 09:49:15 +0000 Subject: [PATCH 480/601] Small polish --- .../CovariantDerivative/LeviCivita.lean | 244 +++++++++--------- 1 file changed, 126 insertions(+), 118 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 8f655ff0982679..cee3c74b9e8178 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -183,133 +183,141 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) local notation "∇" X "," Y => fun (x:M) ↦ cov X x (Y x) -/- --- kept for archival purposes -noncomputable example [FiniteDimensional ℝ E] (Y Z : Π x : M, TangentSpace I x) (x : M) : - TangentSpace I x →L[ℝ] ℝ := - have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) - have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ - let Zflat : TangentSpace I x →L[ℝ] ℝ := - (InnerProductSpace.toDual ℝ (TangentSpace I x)) (Z x) - let A : TangentSpace I x →L[ℝ] TangentSpace I x := cov Y x - Zflat ∘L A - --- Given two vector fields `Y` and `Z`, compute the 1-form `g(∇. Y, Z)`. -noncomputable def foo [FiniteDimensional ℝ E] (Y Z : Π x : M, TangentSpace I x) (x : M) : - TangentSpace I x →L[ℝ] ℝ := - (innerSL ℝ (Z x)) ∘L (cov Y x) -/ - noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) -set_option maxHeartbeats 800000 in variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in -noncomputable example {x : M} [FiniteDimensional ℝ E] : - TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := by - apply mk2TensorAt I E (myfun I cov) - · intro f σ τ hf hσ - unfold myfun - rw [product_smul_left] - --simp only [smul_eq_mul] - --erw [mfderiv_smul] - rw [cov.isCovariantDerivativeOn.leibniz hσ hf] - ext X - simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, - RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, - ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', - coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.comp_apply] - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.add_apply] - conv => - enter [1, 1, 2, 1] - erw [ContinuousLinearMap.smul_apply] - rw [ContinuousLinearMap.comp_apply] - rw [ContinuousLinearMap.comp_apply] - rw [ContinuousLinearMap.comp_apply] - rw [ContinuousLinearMap.comp_apply] - rw [innerSL_apply_apply] - rw [innerSL_apply_apply] - rw [ContinuousLinearMap.toSpanSingleton_apply] - rw [inner_smul_right] - rw [mfderiv_smul _ hf] - · simp only [smul_eq_mul, Pi.mul_apply, bar, ContinuousLinearEquiv.coe_coe, - ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] - conv => - enter [1, 1, 1, 2, 2] - dsimp [product] - rw [real_inner_comm] - rw [← sub_eq_zero] - ring - sorry -- missing hypothesis needed for this differentiability goal? - · intro σ σ' τ hσ hσ' - have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? - simp only [myfun] - ext X - simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, - Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] - rw [product_add_left, - mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), - cov.isCovariantDerivativeOn.addσ hσ hσ', - ContinuousLinearMap.comp_add, ContinuousLinearMap.coe_sub', Pi.sub_apply, - ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] - -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x - -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) - -- set B' := ((innerSL ℝ) (τ x)).comp (cov σ' x) - -- set C := inner ℝ (σ x) ((cov τ x) X) - -- set C' := inner ℝ (σ' x) ((cov τ x) X) - erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, - ContinuousLinearMap.sub_apply] - -- bug: abel fails, but module works - module - · intro f σ τ hf hτ - simp only [myfun] - ext X - dsimp - rw [map_smul (innerSL ℝ) (f x) (τ x), product_smul_right] - have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis? - have aux := mfderiv_smul (s := f) (f := ⟪σ, τ⟫) (I := I) (x := x) (hσ.inner_bundle' hτ) hf - set A := (f x • (innerSL ℝ) (τ x)).comp (cov σ x) - set B := mfderiv I 𝓘(ℝ, ℝ) (f • ⟪σ, τ⟫) x - -- issue: A and B live in different tangent spaces, so cannot simply expand and apply aux... - -- next steps: apply the Leibniz rule, collect the other terms and suffer some more - sorry - · intro σ τ τ' hτ hτ' - have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis! - unfold myfun - ext X - simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', - ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, - ContinuousLinearMap.add_apply] - rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), - cov.isCovariantDerivativeOn.addσ hτ hτ'] - dsimp - rw [inner_add_right] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.sub_apply] +private lemma aux1 {x : M} (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x} + (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) : + myfun I cov (f • σ) τ x = f x • myfun I cov σ τ x := by + have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? + unfold myfun + rw [product_smul_left] + rw [cov.isCovariantDerivativeOn.leibniz hσ hf] + ext X + simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, + RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, + ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', + coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.comp_apply] + conv => + enter [1, 1, 2] erw [ContinuousLinearMap.add_apply] + conv => + enter [1, 1, 2, 1] + erw [ContinuousLinearMap.smul_apply] + rw [ContinuousLinearMap.comp_apply] + rw [ContinuousLinearMap.comp_apply] + rw [ContinuousLinearMap.comp_apply] + rw [ContinuousLinearMap.comp_apply] + rw [innerSL_apply_apply] + rw [innerSL_apply_apply] + rw [ContinuousLinearMap.toSpanSingleton_apply] + rw [inner_smul_right] + rw [mfderiv_smul (hσ.inner_bundle' hτ) hf] + simp only [smul_eq_mul, Pi.mul_apply, bar, ContinuousLinearEquiv.coe_coe, + ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] + conv => + enter [1, 1, 1, 2, 2] + dsimp [product] + rw [real_inner_comm] + rw [← sub_eq_zero] + ring + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) + (hσ : MDiffAt (T% σ) x) + (hσ' : MDiffAt (T% σ') x) : + myfun I cov (σ + σ') τ x = myfun I cov σ τ x + myfun I cov σ' τ x := by + have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? + simp only [myfun] + ext X + simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, + Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] + rw [product_add_left, + mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), + cov.isCovariantDerivativeOn.addσ hσ hσ', + ContinuousLinearMap.comp_add, ContinuousLinearMap.coe_sub', Pi.sub_apply, + ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] + -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x + -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) + -- set B' := ((innerSL ℝ) (τ x)).comp (cov σ' x) + -- set C := inner ℝ (σ x) ((cov τ x) X) + -- set C' := inner ℝ (σ' x) ((cov τ x) X) + erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, + ContinuousLinearMap.sub_apply] + -- bug: abel fails, but module works + module + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +private lemma aux3 {x : M } (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x} + (hf : MDiffAt f x) + (hτ : MDiffAt (T% τ) x) : + myfun I cov σ (f • τ) x = f x • myfun I cov σ τ x := by + -- TODO: should be similar to aux1! + simp only [myfun] + ext X + dsimp + rw [map_smul (innerSL ℝ) (f x) (τ x), product_smul_right] + have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis? + have aux := mfderiv_smul (s := f) (f := ⟪σ, τ⟫) (I := I) (x := x) (hσ.inner_bundle' hτ) hf + set A := (f x • (innerSL ℝ) (τ x)).comp (cov σ x) + set B := mfderiv I 𝓘(ℝ, ℝ) (f • ⟪σ, τ⟫) x + -- issue: A and B live in different tangent spaces, so cannot simply expand and apply aux... + -- next steps: apply the Leibniz rule, collect the other terms and suffer some more + sorry + +-- TODO: investigate why this takes so long! +set_option maxHeartbeats 400000 in +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) + (hτ : MDiffAt (T% τ) x) + (hτ' : MDiffAt (T% τ') x) : + myfun I cov σ (τ + τ') x = myfun I cov σ τ x + myfun I cov σ τ' x := by + have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis! + unfold myfun + ext X + simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', + ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, + ContinuousLinearMap.add_apply] + rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), + cov.isCovariantDerivativeOn.addσ hτ hτ'] + dsimp + rw [inner_add_right] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.sub_apply] + erw [ContinuousLinearMap.add_apply] + erw [ContinuousLinearMap.comp_apply] + conv => + enter [2, 2, 1, 2] erw [ContinuousLinearMap.comp_apply] - conv => - enter [2, 2, 1, 2] - erw [ContinuousLinearMap.comp_apply] + erw [innerSL_apply_apply] + conv => + enter [2, 2, 1, 2] erw [innerSL_apply_apply] - conv => - enter [2, 2, 1, 2] - erw [innerSL_apply_apply] - -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x - -- set C := inner ℝ (σ x) ((cov τ x) X) - -- set C' := inner ℝ (σ x) ((cov τ' x) X) - -- set D := (cov σ x) X - module - --- old version of the definition. TODO: replace by the tensor ∇ g being zero! + -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x + -- set C := inner ℝ (σ x) ((cov τ x) X) + -- set C' := inner ℝ (σ x) ((cov τ' x) X) + -- set D := (cov σ x) X + module + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +/-- Given a connecion `∇` on `(M, g)`, the tensor `∇ g`. -/ +@[no_expose] noncomputable def MetricTensor {x : M} [FiniteDimensional ℝ E] : + TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := + mk2TensorAt I E (myfun I cov) + (fun f _σ _τ hf hσ ↦ aux1 cov f hf hσ) + (fun σ σ' τ hσ hσ' ↦ aux2 cov σ σ' τ hσ hσ') + (fun f _σ _τ hf hτ ↦ aux3 cov f hf hτ) + (fun σ τ τ' hτ hτ' ↦ aux4 cov σ τ τ' hτ hτ') + +-- TODO: redefine this in terms of MetricTensor! /-- Predicate saying for a connection `∇` on a Riemannian manifold `M` to be compatible with the ambient metric, i.e. for all smooth vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ From 9d22180246de7bc581d477d402af294343cb57af Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 10:24:20 +0000 Subject: [PATCH 481/601] chore: redefine compatibility using the tensor --- .../CovariantDerivative/LeviCivita.lean | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index cee3c74b9e8178..196cc049597d3e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -188,7 +188,9 @@ noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] + +variable {I} in private lemma aux1 {x : M} (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) : myfun I cov (f • σ) τ x = f x • myfun I cov σ τ x := by @@ -228,7 +230,7 @@ private lemma aux1 {x : M} (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x rw [← sub_eq_zero] ring -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable {I} in private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) : @@ -254,7 +256,7 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) -- bug: abel fails, but module works module -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable {I} in private lemma aux3 {x : M } (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hτ : MDiffAt (T% τ) x) : @@ -274,7 +276,7 @@ private lemma aux3 {x : M } (f : M → ℝ) {σ τ : (x : M) → TangentSpace I -- TODO: investigate why this takes so long! set_option maxHeartbeats 400000 in -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable {I} in private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : @@ -307,9 +309,9 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) -- set D := (cov σ x) X module -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable {I} in /-- Given a connecion `∇` on `(M, g)`, the tensor `∇ g`. -/ -@[no_expose] noncomputable def MetricTensor {x : M} [FiniteDimensional ℝ E] : +@[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := mk2TensorAt I E (myfun I cov) (fun f _σ _τ hf hσ ↦ aux1 cov f hf hσ) @@ -317,14 +319,13 @@ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] (fun f _σ _τ hf hτ ↦ aux3 cov f hf hτ) (fun σ τ τ' hτ hτ' ↦ aux4 cov σ τ τ' hτ hτ') --- TODO: redefine this in terms of MetricTensor! -/-- Predicate saying for a connection `∇` on a Riemannian manifold `M` to be compatible with the -ambient metric, i.e. for all smooth vector fields `X`, `Y` and `Z` on `M`, we have +/-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with +the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ -def IsCompatible : Prop := - ∀ X Y Z : Π x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! - ∀ x : M, - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x +def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 + +lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} : + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x := sorry /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. @@ -361,7 +362,7 @@ lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z ext x simp [rhs_aux] -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x} +variable {x : M} variable (X) in @[simp] @@ -484,8 +485,6 @@ lemma leviCivitaRhs_apply : leviCivitaRhs I X Y Z x = (1 / 2 : ℝ) • leviCivi section leviCivitaRhs -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] - @[simp] lemma leviCivitaRhs'_addX_apply [CompleteSpace E] (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) @@ -787,9 +786,8 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ Z, X⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by trans ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x - · exact h.1 X Y Z x - · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, - product, inner_sub_right] + · apply cov.IsCompatible_apply I h.1 + · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term From a8d6bb41de40d00e2e74b2e4a8c5c0db0f8cfa35 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 10:41:32 +0000 Subject: [PATCH 482/601] More Heather --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 2 +- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index e26347c1ff197c..98e080763dafbf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 196cc049597d3e..63897bcbc36b13 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module From c1773894fca146ba0be44081bf106349d6909d41 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 5 Mar 2026 12:09:12 +0100 Subject: [PATCH 483/601] Move around prerequisites --- Mathlib.lean | 2 + .../CovariantDerivative/TrivPrelim.lean | 8 ++ .../VectorBundle/IsBilinearPrelim.lean | 77 ++++++++++++ .../Geometry/Manifold/VectorBundle/Misc.lean | 113 ------------------ .../Manifold/VectorBundle/Tensoriality.lean | 1 + .../Manifold/VectorBundle/Unused.lean | 60 ++++++++++ 6 files changed, 148 insertions(+), 113 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Unused.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9d8ec57322895f..9bba9b77694019 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4426,6 +4426,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho public import Mathlib.Geometry.Manifold.VectorBundle.Hom +public import Mathlib.Geometry.Manifold.VectorBundle.IsBilinearPrelim public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable public import Mathlib.Geometry.Manifold.VectorBundle.Misc @@ -4435,6 +4436,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tangent public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorBundle.Unused public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.VectorField.Pullback public import Mathlib.Geometry.Manifold.WhitneyEmbedding diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index e93353d0713114..248d04d52fffaf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -566,6 +566,14 @@ lemma _root_.mdifferentiableAt_section_trivial_iff {σ : (x : M) → Trivial M F rw [mdifferentiableAt_section I] simp +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + +@[simp] +theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : + MDiffAt (T% σ) e ↔ DifferentiableAt 𝕜 σ e := by + simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] + end to_trivialization end Bundle.Trivialization diff --git a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean new file mode 100644 index 00000000000000..ec3b18e6970e50 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean @@ -0,0 +1,77 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Topology.Algebra.Module.FiniteDimension +public import Mathlib.Topology.Algebra.Module.StrongTopology + +/-! +# Miscellaneous pre-requisites for covariant derivatives + +TODO: this file should not exist; move everything in here to a proper place +(and PR it accordingly) + +-/ + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section -- Building continuous bilinear maps + +structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] (f : E → F → G) : Prop where + add_left : ∀ (x₁ x₂ : E) (y : F), f (x₁ + x₂) y = f x₁ y + f x₂ y + smul_left : ∀ (c : R) (x : E) (y : F), f (c • x) y = c • f x y + add_right : ∀ (x : E) (y₁ y₂ : F), f x (y₁ + y₂) = f x y₁ + f x y₂ + smul_right : ∀ (c : R) (x : E) (y : F), f x (c • y) = c • f x y + +def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] {f : E → F → G} (hf : IsBilinearMap R f) : + E →ₗ[R] F →ₗ[R] G := + LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right + +lemma isBilinearMap_eval (R : Type*) (E F : Type*) [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [Module R E] [Module R F] : + IsBilinearMap R (fun (e : E) (φ : E →ₗ[R] F) ↦ φ e) := by + constructor <;> simp + +def IsBilinearMap.toContinuousLinearMap + {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + {F : Type*} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] + {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] + [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] + {f : E → F → G} (h : IsBilinearMap 𝕜 f) : E →L[𝕜] F →L[𝕜] G := + IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) + (by constructor <;> (intros;simp)) |>.toContinuousLinearMap + +def isBilinearMap_evalL + (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] : + IsBilinearMap 𝕜 (fun (e : E) (φ : E →L[𝕜] F) ↦ φ e) := by + constructor <;> simp + +def evalL + (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] + [T2Space E] + (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] + [T2Space F] : E →L[𝕜] (E →L[𝕜] F) →L[𝕜] F := + (isBilinearMap_evalL 𝕜 E F).toContinuousLinearMap +end + diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean index f751f402d1a17a..a54026aa3d9ab0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -18,63 +18,6 @@ TODO: this file should not exist; move everything in here to a proper place @[expose] public section -- TODO: think if we want to expose all definitions! -section -- Building continuous bilinear maps - -structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] - [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] - [Module R E] [Module R F] [Module R G] (f : E → F → G) : Prop where - add_left : ∀ (x₁ x₂ : E) (y : F), f (x₁ + x₂) y = f x₁ y + f x₂ y - smul_left : ∀ (c : R) (x : E) (y : F), f (c • x) y = c • f x y - add_right : ∀ (x : E) (y₁ y₂ : F), f x (y₁ + y₂) = f x y₁ + f x y₂ - smul_right : ∀ (c : R) (x : E) (y : F), f x (c • y) = c • f x y - -def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] - [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] - [Module R E] [Module R F] [Module R G] {f : E → F → G} (hf : IsBilinearMap R f) : - E →ₗ[R] F →ₗ[R] G := - LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right - -lemma isBilinearMap_eval (R : Type*) (E F : Type*) [CommSemiring R] - [AddCommMonoid E] [AddCommMonoid F] [Module R E] [Module R F] : - IsBilinearMap R (fun (e : E) (φ : E →ₗ[R] F) ↦ φ e) := by - constructor <;> simp - -def IsBilinearMap.toContinuousLinearMap - {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - {F : Type*} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] - {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] - [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] - {f : E → F → G} (h : IsBilinearMap 𝕜 f) : E →L[𝕜] F →L[𝕜] G := - IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) - (by constructor <;> (intros;simp)) |>.toContinuousLinearMap - -def isBilinearMap_evalL - (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] : - IsBilinearMap 𝕜 (fun (e : E) (φ : E →L[𝕜] F) ↦ φ e) := by - constructor <;> simp - -def evalL - (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] : E →L[𝕜] (E →L[𝕜] F) →L[𝕜] F := - (isBilinearMap_evalL 𝕜 E F).toContinuousLinearMap -end - section prerequisites open Bundle Filter Function Topology Set @@ -83,21 +26,6 @@ open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 0 M] - -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -- `F` model fiber - (n : WithTop ℕ∞) - (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] - [∀ x, ContinuousSMul 𝕜 (V x)] - [FiberBundle F V] [VectorBundle 𝕜 F V] - -- `V` vector bundle set_option backward.isDefEq.respectTransparency false in def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where @@ -106,47 +34,6 @@ def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where map_add' := by simp map_smul' := by simp -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] - -@[simp] -theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) (e : E) : - MDiffAt (T% σ) e ↔ DifferentiableAt 𝕜 σ e := by - simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] - -attribute [simp] mdifferentiableAt_iff_differentiableAt - -lemma FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) - [TopologicalSpace B] [TopologicalSpace F] - (E : B → Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] - [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) ∈ 𝓝 b := - (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) - -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] - [(x : M) → AddCommGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] in -variable {I F V x} in -/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -if one is differentiable at `x` then so is the other. -Issue: EventuallyEq does not work for dependent functions. -/ -lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ₁ : MDiffAt (T% σ) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : - MDiffAt (T% σ') x := by - apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ - -- TODO: split off a lemma? - apply Set.EqOn.eventuallyEq_of_mem _ hs - intro x hx - simp [hσ₂, hx] -omit [IsManifold I 0 M] [∀ (x : M), IsTopologicalAddGroup (V x)] [(x : M) → Module 𝕜 (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [(x : M) → AddCommGroup (V x)] in -variable {I F V x} in -/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, -one is differentiable at `x` iff the other is. -/ -lemma mdifferentiable_dependent_congr_iff {σ σ' : Π x : M, V x} {s : Set M} (hs : s ∈ nhds x) - (hσ : ∀ x ∈ s, σ x = σ' x) : - MDiffAt (T% σ) x ↔ MDiffAt (T% σ') x := - ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, - fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ end prerequisites diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 0a1083a689e9ba..a0329f0392007d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -9,6 +9,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Extend import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +public import Mathlib.Geometry.Manifold.VectorBundle.IsBilinearPrelim /-! # The tensoriality criterion diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Unused.lean b/Mathlib/Geometry/Manifold/VectorBundle/Unused.lean new file mode 100644 index 00000000000000..38cb8f2b526a18 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Unused.lean @@ -0,0 +1,60 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable + +/-! +# Miscellaneous pre-requisites for covariant derivatives + +TODO: this file should not exist; move everything in here to a proper place +(and PR it accordingly) + +-/ + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section prerequisites + +open Bundle Filter Function Topology Set + +open scoped Bundle Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + + + +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +if one is differentiable at `x` then so is the other. +Issue: EventuallyEq does not work for dependent functions. -/ +lemma mdifferentiableAt_dependent_congr {σ σ' : Π x : M, V x} {x : M} {s : Set M} (hs : s ∈ nhds x) + (hσ₁ : MDiffAt (T% σ) x) (hσ₂ : ∀ x ∈ s, σ x = σ' x) : + MDiffAt (T% σ') x := by + apply MDifferentiableAt.congr_of_eventuallyEq hσ₁ + -- TODO: split off a lemma? + apply Set.EqOn.eventuallyEq_of_mem _ hs + intro x hx + simp [hσ₂, hx] + +/-- If two sections `σ` and `σ'` are equal on a neighbourhood `s` of `x`, +one is differentiable at `x` iff the other is. -/ +lemma mdifferentiable_dependent_congr_iff {σ σ' : Π x : M, V x} {x : M} {s : Set M} + (hs : s ∈ nhds x) (hσ : ∀ x ∈ s, σ x = σ' x) : + MDiffAt (T% σ) x ↔ MDiffAt (T% σ') x := + ⟨fun h ↦ mdifferentiableAt_dependent_congr hs h hσ, + fun h ↦ mdifferentiableAt_dependent_congr hs h (fun x hx ↦ (hσ x hx).symm)⟩ + +end prerequisites From cd08afc6c9261f8a72e050d92923eaa4b8210b53 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 11:10:15 +0000 Subject: [PATCH 484/601] [pre-commit.ci lite] apply automatic fixes --- Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean index ec3b18e6970e50..9a0fb4fad3b9aa 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean @@ -74,4 +74,3 @@ def evalL [T2Space F] : E →L[𝕜] (E →L[𝕜] F) →L[𝕜] F := (isBilinearMap_evalL 𝕜 E F).toContinuousLinearMap end - From fc51f83b8988da1ff028c39b944c1e51d8b179f1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 10:48:07 +0000 Subject: [PATCH 485/601] Compactify code --- .../CovariantDerivative/LeviCivita.lean | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 63897bcbc36b13..9dea11e51bd424 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -196,31 +196,23 @@ private lemma aux1 {x : M} (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x myfun I cov (f • σ) τ x = f x • myfun I cov σ τ x := by have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? unfold myfun - rw [product_smul_left] - rw [cov.isCovariantDerivativeOn.leibniz hσ hf] + rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] ext X simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.comp_apply] + erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] conv => enter [1, 1, 2] erw [ContinuousLinearMap.add_apply] conv => enter [1, 1, 2, 1] erw [ContinuousLinearMap.smul_apply] - rw [ContinuousLinearMap.comp_apply] - rw [ContinuousLinearMap.comp_apply] - rw [ContinuousLinearMap.comp_apply] - rw [ContinuousLinearMap.comp_apply] - rw [innerSL_apply_apply] - rw [innerSL_apply_apply] - rw [ContinuousLinearMap.toSpanSingleton_apply] - rw [inner_smul_right] - rw [mfderiv_smul (hσ.inner_bundle' hτ) hf] + rw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, + ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, + innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, + inner_smul_right, mfderiv_smul (hσ.inner_bundle' hτ) hf] simp only [smul_eq_mul, Pi.mul_apply, bar, ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] conv => @@ -291,10 +283,8 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) cov.isCovariantDerivativeOn.addσ hτ hτ'] dsimp rw [inner_add_right] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.sub_apply] - erw [ContinuousLinearMap.add_apply] - erw [ContinuousLinearMap.comp_apply] + erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, + ContinuousLinearMap.add_apply, ContinuousLinearMap.comp_apply] conv => enter [2, 2, 1, 2] erw [ContinuousLinearMap.comp_apply] From 277a94d1656d13ecc3b7e23baf7dca4d3ba1849e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 10:48:14 +0000 Subject: [PATCH 486/601] Speed up! --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 9dea11e51bd424..bf331dc5b1e08e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -266,8 +266,6 @@ private lemma aux3 {x : M } (f : M → ℝ) {σ τ : (x : M) → TangentSpace I -- next steps: apply the Leibniz rule, collect the other terms and suffer some more sorry --- TODO: investigate why this takes so long! -set_option maxHeartbeats 400000 in variable {I} in private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) (hτ : MDiffAt (T% τ) x) @@ -288,7 +286,7 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) conv => enter [2, 2, 1, 2] erw [ContinuousLinearMap.comp_apply] - erw [innerSL_apply_apply] + rw [innerSL_apply_apply] conv => enter [2, 2, 1, 2] erw [innerSL_apply_apply] From f4b0c31f2de5728aca97d93f694c25083f6db1b6 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 11:36:22 +0000 Subject: [PATCH 487/601] Make f implicit --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index bf331dc5b1e08e..6d351b820df523 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -191,7 +191,7 @@ noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] variable {I} in -private lemma aux1 {x : M} (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x} +private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) : myfun I cov (f • σ) τ x = f x • myfun I cov σ τ x := by have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? @@ -249,7 +249,7 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) module variable {I} in -private lemma aux3 {x : M } (f : M → ℝ) {σ τ : (x : M) → TangentSpace I x} +private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hτ : MDiffAt (T% τ) x) : myfun I cov σ (f • τ) x = f x • myfun I cov σ τ x := by @@ -302,9 +302,9 @@ variable {I} in @[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := mk2TensorAt I E (myfun I cov) - (fun f _σ _τ hf hσ ↦ aux1 cov f hf hσ) + (fun _f _σ _τ hf hσ ↦ aux1 cov hf hσ) (fun σ σ' τ hσ hσ' ↦ aux2 cov σ σ' τ hσ hσ') - (fun f _σ _τ hf hτ ↦ aux3 cov f hf hτ) + (fun _f _σ _τ hf hτ ↦ aux3 cov hf hτ) (fun σ τ τ' hτ hτ' ↦ aux4 cov σ τ τ' hτ hτ') /-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with From 9ad18e1b1a7d9e63270475222ed0849ab131f105 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 11:46:11 +0000 Subject: [PATCH 488/601] Last sorry virtually proven --- .../CovariantDerivative/LeviCivita.lean | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 6d351b820df523..e3a6086f5280f0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -253,18 +253,34 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x (hf : MDiffAt f x) (hτ : MDiffAt (T% τ) x) : myfun I cov σ (f • τ) x = f x • myfun I cov σ τ x := by - -- TODO: should be similar to aux1! - simp only [myfun] + have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis? + unfold myfun + rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] ext X + simp only [smul_eq_mul, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, + ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, + ContinuousLinearMap.coe_sub', Pi.sub_apply, ContinuousLinearMap.add_apply, + ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.smul_apply, + comp_apply, ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply] + erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] + set A := inner ℝ (σ x) ((cov τ x) X) + conv => + enter [1, 1, 2] + erw [ContinuousLinearMap.smul_apply] + conv => + enter [1, 1, 2, 2] + erw [ContinuousLinearMap.comp_apply] dsimp - rw [map_smul (innerSL ℝ) (f x) (τ x), product_smul_right] - have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis? - have aux := mfderiv_smul (s := f) (f := ⟪σ, τ⟫) (I := I) (x := x) (hσ.inner_bundle' hτ) hf - set A := (f x • (innerSL ℝ) (τ x)).comp (cov σ x) - set B := mfderiv I 𝓘(ℝ, ℝ) (f • ⟪σ, τ⟫) x - -- issue: A and B live in different tangent spaces, so cannot simply expand and apply aux... - -- next steps: apply the Leibniz rule, collect the other terms and suffer some more - sorry + --set B := inner ℝ (τ x) ((cov σ x) X) + erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] + --set C := (mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) X + --set D := (mfderiv I 𝓘(ℝ, ℝ) f x) X + simp only [smul_eq_mul, bar, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, + AddHom.coe_mk, inner_smul_right] + -- might be superfluous + have : inner ℝ (σ x) (τ x) = ⟪σ, τ⟫ x := by rfl + rw [this] + sorry -- morally true now! variable {I} in private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) From c6cfc8abdfe04a7ff2bbbdbbd0f5b903868bd426 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Thu, 5 Mar 2026 12:08:02 +0000 Subject: [PATCH 489/601] apply lemma --- .../CovariantDerivative/LeviCivita.lean | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e3a6086f5280f0..d406cb17fe2422 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -323,6 +323,22 @@ variable {I} in (fun _f _σ _τ hf hτ ↦ aux3 cov hf hτ) (fun σ τ τ' hτ hτ' ↦ aux4 cov σ τ τ' hτ hτ') +theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + MetricTensor cov x (Y x) (Z x) (X x) = + bar _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by + unfold MetricTensor + rw [mk2TensorAt_apply _ _ _ _ _ hY hZ] + simp only [myfun, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, + Pi.sub_apply, comp_apply] + conv => + enter [1, 1] + erw [ContinuousLinearMap.sub_apply] + conv => + enter [1, 1, 2] + erw [ContinuousLinearMap.comp_apply] + simp [product, real_inner_comm, bar] + /-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ From dab702cf53fccaf1f7a5d2725f594b0fcf9fb38d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 12:01:59 +0000 Subject: [PATCH 490/601] chore: smuggle in two more differentiability hypotheses --- .../CovariantDerivative/LeviCivita.lean | 16 ++++---- .../CovariantDerivative/Torsion.lean | 4 +- .../Manifold/VectorBundle/Tensoriality.lean | 38 ++++++++++--------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index d406cb17fe2422..cd888681119102 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -224,10 +224,8 @@ private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x variable {I} in private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) - (hσ : MDiffAt (T% σ) x) - (hσ' : MDiffAt (T% σ') x) : + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : myfun I cov (σ + σ') τ x = myfun I cov σ τ x + myfun I cov σ' τ x := by - have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? simp only [myfun] ext X simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, @@ -284,10 +282,8 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x variable {I} in private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) - (hτ : MDiffAt (T% τ) x) - (hτ' : MDiffAt (T% τ') x) : + (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : myfun I cov σ (τ + τ') x = myfun I cov σ τ x + myfun I cov σ τ' x := by - have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis! unfold myfun ext X simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', @@ -314,14 +310,14 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) module variable {I} in -/-- Given a connecion `∇` on `(M, g)`, the tensor `∇ g`. -/ +/-- The tensor `∇ g` defined by a connection `∇` on a Riemannian manifold `(M, g)`. -/ @[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := mk2TensorAt I E (myfun I cov) (fun _f _σ _τ hf hσ ↦ aux1 cov hf hσ) - (fun σ σ' τ hσ hσ' ↦ aux2 cov σ σ' τ hσ hσ') + (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) (fun _f _σ _τ hf hτ ↦ aux3 cov hf hτ) - (fun σ τ τ' hτ hτ' ↦ aux4 cov σ τ τ' hτ hτ') + (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : @@ -347,6 +343,8 @@ def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} : mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x := sorry +#exit + /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index bac5fc0d1bd3c4..ed93d9ab562e6a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -110,9 +110,9 @@ noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := mk2TensorAt I E (Bundle.torsionFun cov) (fun {_ _ τ} ↦ hcov.torsionFun_smul_left_apply τ) - (fun {_ _ τ} ↦ hcov.torsionFun_add_left_apply τ) + (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionFun_add_left_apply τ hσ hσ') (fun {_ _} ↦ hcov.torsionFun_smul_right_apply) - (fun {_ _ _} ↦ hcov.torsionFun_add_right_apply) + (fun {_ _ _ _} ↦ hcov.torsionFun_add_right_apply) theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index a0329f0392007d..548b2b088793c2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -116,21 +116,21 @@ lemma tensoriality_criterion₂ (hττ' : τ x = τ' x) (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by trans φ σ' τ x · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ change φ1 σ x = φ1 σ' x apply tensoriality_criterion I F V V' hσ hσ' hσσ' - exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ'] + exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ' hτ] · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X change φ1 τ x = φ1 τ' x apply tensoriality_criterion I F V V' hτ hτ' hττ' - exacts [fun f τ hf hτ ↦ τ_smul _ hf hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hτ hτ'] + exacts [fun f τ hf hτ ↦ τ_smul _ hf hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hσ' hτ hτ'] section tensoriality @@ -239,11 +239,11 @@ noncomputable def mk2TensorAt (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : V x →L[ℝ] V x →L[ℝ] V' x := let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x @@ -264,6 +264,7 @@ noncomputable def mk2TensorAt · simp · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. smul_left c v w := by rw [← σ_smul (f := fun _ ↦ c)] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add @@ -288,6 +289,7 @@ noncomputable def mk2TensorAt · simp · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. smul_right c v w := by rw [← τ_smul (f := fun _ ↦ c)] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add @@ -308,11 +310,11 @@ theorem mk2TensorAt_apply {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by @@ -328,11 +330,11 @@ theorem mk2TensorAt_apply_eq_extend {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (σ τ : V x) : mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add σ τ @@ -343,34 +345,34 @@ theorem mk2TensorAt_add (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} (φ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) τ x = f x • φ σ τ x) - (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) (φ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) - (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) (ψ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → ψ (f • σ) τ x = f x • ψ σ τ x) - (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → + (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) (ψ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → ψ σ (f • τ) x = f x • ψ σ τ x) - (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% τ) x → MDiffAt (T% τ') x → + (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : mk2TensorAt I F (φ + ψ) (fun {_ _ τ} hf hσ ↦ (congr($(φ_σ_smul _ hf hσ (τ := τ)) + $(ψ_σ_smul _ hf hσ (τ := τ)))).trans (smul_add _ _ _).symm) - (fun σ₁ σ₂ τ hσ₁ hσ₂ ↦ - (congr($(φ_σ_add _ _ _ hσ₁ hσ₂) + $(ψ_σ_add _ _ _ hσ₁ hσ₂))).trans <| by + (fun σ₁ σ₂ τ hσ₁ hσ₂ hτ ↦ + (congr($(φ_σ_add _ _ _ hσ₁ hσ₂ hτ) + $(ψ_σ_add _ _ _ hσ₁ hσ₂ hτ))).trans <| by dsimp abel) (fun {_ σ _} hf hτ ↦ (congr($(φ_τ_smul _ hf hτ (σ := σ)) + $(ψ_τ_smul _ hf hτ (σ := σ)))).trans (smul_add _ _ _).symm) - (fun σ {τ₁ τ₂} hτ₁ hτ₂ ↦ - (congr($(φ_τ_add _ _ _ hτ₁ hτ₂) + $(ψ_τ_add _ _ _ hτ₁ hτ₂))).trans <| by + (fun σ {τ₁ τ₂} hσ hτ₁ hτ₂ ↦ + (congr($(φ_τ_add _ _ _ hσ hτ₁ hτ₂) + $(ψ_τ_add _ _ _ hσ hτ₁ hτ₂))).trans <| by dsimp abel) = mk2TensorAt I F φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add From 2d36cc9544ea1447e73ba053a1000a867c35ee4f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 12:10:16 +0000 Subject: [PATCH 491/601] I'm getting tensor every day --- .../CovariantDerivative/LeviCivita.lean | 13 ++----- .../CovariantDerivative/Torsion.lean | 4 +- .../Manifold/VectorBundle/Tensoriality.lean | 38 ++++++++++--------- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index cd888681119102..bd715c0d9d36fd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -192,9 +192,8 @@ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] variable {I} in private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} - (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) : + (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : myfun I cov (f • σ) τ x = f x • myfun I cov σ τ x := by - have hτ : MDiffAt (T% τ) x := sorry -- missing hypothesis? unfold myfun rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] ext X @@ -248,10 +247,8 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) variable {I} in private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} - (hf : MDiffAt f x) - (hτ : MDiffAt (T% τ) x) : + (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : myfun I cov σ (f • τ) x = f x • myfun I cov σ τ x := by - have hσ : MDiffAt (T% σ) x := sorry -- missing hypothesis? unfold myfun rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] ext X @@ -314,9 +311,9 @@ variable {I} in @[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := mk2TensorAt I E (myfun I cov) - (fun _f _σ _τ hf hσ ↦ aux1 cov hf hσ) + (fun _f _σ _τ hf hσ hτ ↦ aux1 cov hf hσ hτ) (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) - (fun _f _σ _τ hf hτ ↦ aux3 cov hf hτ) + (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) @@ -343,8 +340,6 @@ def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} : mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x := sorry -#exit - /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index ed93d9ab562e6a..d936e069b3aa0a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -109,9 +109,9 @@ variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := mk2TensorAt I E (Bundle.torsionFun cov) - (fun {_ _ τ} ↦ hcov.torsionFun_smul_left_apply τ) + (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_left_apply τ hf hσ) (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionFun_add_left_apply τ hσ hσ') - (fun {_ _} ↦ hcov.torsionFun_smul_right_apply) + (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_right_apply hf hτ) (fun {_ _ _ _} ↦ hcov.torsionFun_add_right_apply) theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 548b2b088793c2..37c8eb4f8134f0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -114,11 +114,11 @@ lemma tensoriality_criterion₂ (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by @@ -126,11 +126,11 @@ lemma tensoriality_criterion₂ · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ change φ1 σ x = φ1 σ' x apply tensoriality_criterion I F V V' hσ hσ' hσσ' - exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ' hτ] + exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ hτ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ' hτ] · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X change φ1 τ x = φ1 τ' x apply tensoriality_criterion I F V V' hτ hτ' hττ' - exacts [fun f τ hf hτ ↦ τ_smul _ hf hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hσ' hτ hτ'] + exacts [fun f τ hf hτ ↦ τ_smul _ hf hσ' hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hσ' hτ hτ'] section tensoriality @@ -237,11 +237,11 @@ theorem contMDiff_mkTensor noncomputable def mk2TensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : @@ -277,6 +277,7 @@ noncomputable def mk2TensorAt · simp · exact mdifferentiable_const .. · exact mdifferentiable_extend .. + · exact mdifferentiable_extend .. add_right v w₁ w₂ := by rw [← τ_add] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add @@ -301,6 +302,7 @@ noncomputable def mk2TensorAt · exact mdifferentiable_extend .. · simp · exact mdifferentiable_const .. + · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. } H.toContinuousLinearMap @@ -308,11 +310,11 @@ variable {I} in theorem mk2TensorAt_apply -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) @@ -328,11 +330,11 @@ variable {I} in theorem mk2TensorAt_apply_eq_extend -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) @@ -343,33 +345,33 @@ theorem mk2TensorAt_apply_eq_extend theorem mk2TensorAt_add (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (φ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (φ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (φ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (φ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) - (ψ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → + (ψ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → ψ (f • σ) τ x = f x • ψ σ τ x) (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) - (ψ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% τ) x → + (ψ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → ψ σ (f • τ) x = f x • ψ σ τ x) (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : mk2TensorAt I F (φ + ψ) - (fun {_ _ τ} hf hσ ↦ - (congr($(φ_σ_smul _ hf hσ (τ := τ)) + $(ψ_σ_smul _ hf hσ (τ := τ)))).trans + (fun {_ _ τ} hf hσ hτ ↦ + (congr($(φ_σ_smul _ hf hσ hτ) + $(ψ_σ_smul _ hf hσ hτ))).trans (smul_add _ _ _).symm) (fun σ₁ σ₂ τ hσ₁ hσ₂ hτ ↦ (congr($(φ_σ_add _ _ _ hσ₁ hσ₂ hτ) + $(ψ_σ_add _ _ _ hσ₁ hσ₂ hτ))).trans <| by dsimp abel) - (fun {_ σ _} hf hτ ↦ - (congr($(φ_τ_smul _ hf hτ (σ := σ)) + $(ψ_τ_smul _ hf hτ (σ := σ)))).trans + (fun {_ σ _} hf hσ hτ ↦ + (congr($(φ_τ_smul _ hf hσ hτ) + $(ψ_τ_smul _ hf hσ hτ))).trans (smul_add _ _ _).symm) (fun σ {τ₁ τ₂} hσ hτ₁ hτ₂ ↦ (congr($(φ_τ_add _ _ _ hσ hτ₁ hτ₂) + $(ψ_τ_add _ _ _ hσ hτ₁ hτ₂))).trans <| by From 9e3f139fc8be95e036bb58226656a6cc411632a3 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 5 Mar 2026 13:27:39 +0100 Subject: [PATCH 492/601] Document PR --- Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean index 9a0fb4fad3b9aa..44589a9386ecfc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean @@ -9,10 +9,9 @@ public import Mathlib.Topology.Algebra.Module.FiniteDimension public import Mathlib.Topology.Algebra.Module.StrongTopology /-! -# Miscellaneous pre-requisites for covariant derivatives +# Bilinear map pre-requisites for covariant derivatives -TODO: this file should not exist; move everything in here to a proper place -(and PR it accordingly) +PRed as #36193 -/ From 1d61f51258f4d0cf713c0d6141cc6780b4e9e6c3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 12:39:57 +0000 Subject: [PATCH 493/601] chore: fix the build in LeviCivita --- .../CovariantDerivative/LeviCivita.lean | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index bd715c0d9d36fd..1feaddd9236b18 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -868,32 +868,27 @@ noncomputable def lcAux₀ [FiniteDimensional ℝ E] dsimp rw [if_pos hX, if_pos] · split_ifs with hZ - · exact leviCivitaRhs_smulX_apply hf hX hY hZ + · exact leviCivitaRhs_smulX_apply hf hX hY · simp · exact hf.smul_section hX) (fun {X₁ X₂ Z} hX₁ hX₂ ↦ by dsimp rw [if_pos hX₁, if_pos hX₂, if_pos] · split_ifs with hZ - · exact leviCivitaRhs_addX_apply I hX₁ hX₂ hY hZ + · exact leviCivitaRhs_addX_apply I hX₁ hX₂ hY · simp · exact mdifferentiableAt_add_section hX₁ hX₂) - (fun {f X Z} hf hZ ↦ by + (fun {f X Z} hf hX hZ ↦ by dsimp - rw [if_pos hZ] - nth_rw 2 [if_pos] - · split_ifs with hX - · exact leviCivitaRhs_smulZ_apply I hf hX hY hZ - · simp + rw [if_pos hX, if_pos hZ, if_pos, if_pos hX] + · exact leviCivitaRhs_smulZ_apply I hf hX hY hZ · exact hf.smul_section hZ) - (fun {X Z₁ Z₂} hZ₁ hZ₂ ↦ by + (fun {X Z₁ Z₂} hX hZ₁ hZ₂ ↦ by dsimp - rw [if_pos hZ₁, if_pos hZ₂] - nth_rw 2 [if_pos] - · split_ifs with hX - · exact leviCivitaRhs_addZ_apply I hX hY hZ₁ hZ₂ - · simp - · exact mdifferentiableAt_add_section hZ₁ hZ₂) + rw [if_pos hZ₁, if_pos hZ₂, if_pos hX, if_pos, if_pos hX, if_pos hX] + · exact leviCivitaRhs_addZ_apply I hX hY hZ₁ hZ₂ + · exact mdifferentiableAt_add_section hZ₁ hZ₂ + ) theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) @@ -950,11 +945,8 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : dite_eq_ite, LinearMap.coe_toContinuousLinearMap', IsLinearMap.mk'_apply, LinearMap.mk₂_apply, ContinuousLinearMap.add_apply] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] - · apply leviCivitaRhs_addY_apply - · exact mdifferentiable_extend .. - · exact hY - · exact hY' - · exact mdifferentiable_extend .. + · apply leviCivitaRhs_addY_apply _ (mdifferentiable_extend ..) hY hY' + exact mdifferentiable_extend .. · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. · exact mdifferentiable_extend .. From 86cb3256ac501a1b525fc9d84474b9528169376c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 14:09:12 +0000 Subject: [PATCH 494/601] Fixed the last sorry, by bashing through --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 1feaddd9236b18..b1f9a30ccb73bf 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -258,7 +258,7 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.smul_apply, comp_apply, ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply] erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] - set A := inner ℝ (σ x) ((cov τ x) X) + --set A := inner ℝ (σ x) ((cov τ x) X) conv => enter [1, 1, 2] erw [ContinuousLinearMap.smul_apply] @@ -272,10 +272,11 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x --set D := (mfderiv I 𝓘(ℝ, ℝ) f x) X simp only [smul_eq_mul, bar, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk, inner_smul_right] - -- might be superfluous - have : inner ℝ (σ x) (τ x) = ⟪σ, τ⟫ x := by rfl - rw [this] - sorry -- morally true now! + -- would be nice to finish by a tactic now! + erw [mul_add, mul_add] + rw [Pi.mul_apply, mul_neg, mul_neg, + ← sub_eq_add_neg, ← sub_eq_add_neg, sub_add_eq_sub_sub] + match_scalars <;> all_goals simp variable {I} in private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) From bf4e330a059b300dc75be99a5e2a79fc47eb86b1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 14:29:32 +0000 Subject: [PATCH 495/601] Did we switch some variables in the metric tensor? --- .../CovariantDerivative/LeviCivita.lean | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index b1f9a30ccb73bf..f8f3447ac55c41 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -317,6 +317,8 @@ variable {I} in (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') +-- TODO: should we have ∇ X Y and ∇ X Z instead? +variable {I} in theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : MetricTensor cov x (Y x) (Z x) (X x) = @@ -338,8 +340,21 @@ the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 -lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} : - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x := sorry +lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x := by + rw [IsCompatible] at hcov + have : MetricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] + rw [metricTensor_apply cov x hY hZ] at this + simp [bar] at this + set A := (mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x) + have : A = ⟪fun x ↦ (cov Y x) (X x), Z⟫ x + ⟪Y, fun x ↦ (cov Z x) (X x)⟫ x := sorry -- use this + rw [this] + + -- TODO: was there a mix-up in the definition of metric tensor above? + -- set B := ⟪fun x ↦ (cov X x) (Y x), Z⟫ x + -- set C := ⟪Y, fun x ↦ (cov X x) (Z x)⟫ x + sorry /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. @@ -800,7 +815,9 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ Z, X⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by trans ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x - · apply cov.IsCompatible_apply I h.1 + · -- TODO: is something wrong, + -- or do we just need to thread through more differentiability assumptions? + apply cov.IsCompatible_apply I h.1 sorry hZ · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in From 4e5b2645248cee48d101154f2e6e1834152f6d08 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 15:31:58 +0000 Subject: [PATCH 496/601] Checkpoint towards torsion --- .../CovariantDerivative/LeviCivita.lean | 79 +++++++++++++++++-- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index f8f3447ac55c41..5bb1e0b8a07969 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -836,6 +836,16 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional ℝ E] section +variable {I} in +lemma congr_of_forall_product_apply [FiniteDimensional ℝ E] {Y Y' : TangentSpace I x} + (h : ∀ Z : TangentSpace I x, inner ℝ Y Z = inner ℝ Y' Z) : Y = Y' := by + have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ + set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) + apply Φ.injective + ext Z₀ + simpa [Φ, product] using h Z₀ + variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ @@ -843,12 +853,9 @@ vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ lemma congr_of_forall_product [FiniteDimensional ℝ E] (h : ∀ Z : Π x : M, TangentSpace I x, ⟪X, Z⟫ = ⟪X', Z⟫) : X = X' := by ext1 x - have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) - have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ - set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) - apply Φ.injective - ext Z₀ - simpa [Φ, product] using congr($(h (_root_.extend I E Z₀)) x) + apply congr_of_forall_product_apply + intro Z₀ + simpa [product] using congr($(h (_root_.extend I E Z₀)) x) /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ @@ -1028,7 +1035,67 @@ theorem leviCivitaConnection_apply [FiniteDimensional ℝ E] {x : M} inner ℝ (LeviCivitaConnection I M Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := lcAux_apply _ hX hY hZ +lemma leviCivitaConnection_isCompatible [FiniteDimensional ℝ E] : + (LeviCivitaConnection I M).IsCompatible := by + sorry + +lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : + (LeviCivitaConnection I M).IsTorsionFree := by + have a := (LeviCivitaConnection I M).isCovariantDerivativeOn + rw [CovariantDerivative.isTorsionFree_iff] + intro X Y x hX hY + apply congr_of_forall_product_apply + intro Z + trans (inner ℝ (((LeviCivitaConnection I M) X x) (Y x)) Z) - + (inner ℝ (((LeviCivitaConnection I M) Y x) (X x)) Z) + · apply inner_sub_left + have hZ' : _root_.extend I E Z x = Z := extend_apply_self Z + rw [← hZ'] + rw [leviCivitaConnection_apply I hY hX (mdifferentiable_extend ..)] + rw [leviCivitaConnection_apply I hX hY (mdifferentiable_extend ..)] + simp only [leviCivitaRhs_apply] + -- XXX: should there be leviCivitaRhs'_apply? + simp only [leviCivitaRhs', Pi.add_apply, Pi.sub_apply, product_apply] + simp only [VectorField.mlieBracket_swap (V := Y) (W := X)] + simp only [Pi.neg_apply, inner_neg_right, sub_neg_eq_add] + set C := inner ℝ Z (VectorField.mlieBracket I X Y x) + set Z' := _root_.extend I E Z + simp only [VectorField.mlieBracket_swap (V := Z') (W := X)] + simp only [VectorField.mlieBracket_swap (V := Z') (W := Y)] + simp only [Pi.neg_apply, inner_neg_right] + rw [rhs_aux_swap (Y := Z'), rhs_aux_swap (Y := Z'), rhs_aux_swap (X := Z')] + rw [real_inner_comm (Z' x) (VectorField.mlieBracket I X Y x)] + set A := inner ℝ (Z' x) (VectorField.mlieBracket I X Y x) + set B := inner ℝ (Y x) (VectorField.mlieBracket I X Z' x) + set C := inner ℝ (X x) (VectorField.mlieBracket I Y Z' x) + set D := rhs_aux I X Y Z' x + set E := rhs_aux I Y X Z' x + set F := rhs_aux I Z' X Y x + have aux : (E + D - F - C - A + -B) - (D + E - F - B + A + -C) = - A - A := by abel + rw [smul_eq_mul] + erw [← mul_sub] + abel_nf + simp -- just a sign error remaining... + -- trans (1 / 2) • (E + D - F - C - A + -B) - (1 / 2) • (D + E - F - B + A + -C) + -- · match_scalars + -- all_goals simp + stop + sorry + match_scalars + all_goals simp + trans A + B + · match_scalars + all_goals simp + sorry -- should be obvious! + --simp only [A, B, C]--set D := inner ℝ (VectorField.mlieBracket I X Y x) (Z' x) + -- is A = B? + sorry + #exit + +lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := + ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_isTorsionFree I⟩ + -- TODO: move this section to `Torsion.lean` section From e0265b33f1d3821166dca98cb456db146c5214d3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 15:52:09 +0000 Subject: [PATCH 497/601] Gotcha: the argument order in Torsion.lean was flipped; with that fixed, LC is actually torsion-free! --- .../CovariantDerivative/Basic.lean | 1 + .../CovariantDerivative/LeviCivita.lean | 39 ++++++------------- .../CovariantDerivative/Torsion.lean | 10 ++--- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 98e080763dafbf..170962ef6e7180 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -234,6 +234,7 @@ end IsCovariantDerivativeOn /-! Bundled global covariant derivatives -/ variable (I F V) in +/-- Caution: `cov Y x (X x)` corresponds to `∇ X Y` in textbooks! -/ @[ext] structure CovariantDerivative [IsManifold I 1 M] where toFun : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 5bb1e0b8a07969..4800dc560d6012 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -818,7 +818,7 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} · -- TODO: is something wrong, -- or do we just need to thread through more differentiability assumptions? apply cov.IsCompatible_apply I h.1 sorry hZ - · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] + · sorry -- simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term @@ -1046,8 +1046,8 @@ lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : intro X Y x hX hY apply congr_of_forall_product_apply intro Z - trans (inner ℝ (((LeviCivitaConnection I M) X x) (Y x)) Z) - - (inner ℝ (((LeviCivitaConnection I M) Y x) (X x)) Z) + trans (inner ℝ (((LeviCivitaConnection I M) Y x) (X x)) Z) - + (inner ℝ (((LeviCivitaConnection I M) X x) (Y x)) Z) · apply inner_sub_left have hZ' : _root_.extend I E Z x = Z := extend_apply_self Z rw [← hZ'] @@ -1065,31 +1065,14 @@ lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : simp only [Pi.neg_apply, inner_neg_right] rw [rhs_aux_swap (Y := Z'), rhs_aux_swap (Y := Z'), rhs_aux_swap (X := Z')] rw [real_inner_comm (Z' x) (VectorField.mlieBracket I X Y x)] - set A := inner ℝ (Z' x) (VectorField.mlieBracket I X Y x) - set B := inner ℝ (Y x) (VectorField.mlieBracket I X Z' x) - set C := inner ℝ (X x) (VectorField.mlieBracket I Y Z' x) - set D := rhs_aux I X Y Z' x - set E := rhs_aux I Y X Z' x - set F := rhs_aux I Z' X Y x - have aux : (E + D - F - C - A + -B) - (D + E - F - B + A + -C) = - A - A := by abel - rw [smul_eq_mul] - erw [← mul_sub] - abel_nf - simp -- just a sign error remaining... - -- trans (1 / 2) • (E + D - F - C - A + -B) - (1 / 2) • (D + E - F - B + A + -C) - -- · match_scalars - -- all_goals simp - stop - sorry - match_scalars - all_goals simp - trans A + B - · match_scalars - all_goals simp - sorry -- should be obvious! - --simp only [A, B, C]--set D := inner ℝ (VectorField.mlieBracket I X Y x) (Z' x) - -- is A = B? - sorry + -- set A := inner ℝ (Z' x) (VectorField.mlieBracket I X Y x) + -- set B := inner ℝ (Y x) (VectorField.mlieBracket I X Z' x) + -- set C := inner ℝ (X x) (VectorField.mlieBracket I Y Z' x) + -- set D := rhs_aux I X Y Z' x + -- set E := rhs_aux I Y X Z' x + -- set F := rhs_aux I Z' X Y x + match_scalars <;> simp + norm_num #exit diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index d936e069b3aa0a..34c81339c24808 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -37,7 +37,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] noncomputable def Bundle.torsionFun (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := - fun X Y x ↦ cov X x (Y x) - cov Y x (X x) - VectorField.mlieBracket I X Y x + fun X Y x ↦ cov Y x (X x) - cov X x (Y x) - VectorField.mlieBracket I X Y x variable {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} @@ -159,14 +159,14 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) noncomputable def torsion := cov.isCovariantDerivativeOn.torsion lemma torsion_vector_field_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : - cov.torsion x (X x) (Y x) = cov X x (Y x) - cov Y x (X x) - mlieBracket I X Y x := by + cov.torsion x (X x) (Y x) = cov Y x (X x) - cov X x (Y x) - mlieBracket I X Y x := by unfold torsion IsCovariantDerivativeOn.torsion apply mk2TensorAt_apply exacts [hX, hY] lemma torsion_apply (u v : TangentSpace I x) : - cov.torsion x u v = cov (extend I E u) x (extend I E v x) - - cov (extend I E v) x (extend I E u x) + cov.torsion x u v = cov (extend I E v) x (extend I E u x) + - cov (extend I E u) x (extend I E v x) - mlieBracket I (extend I E u) (extend I E v) x := by unfold torsion IsCovariantDerivativeOn.torsion apply mk2TensorAt_apply_eq_extend @@ -176,7 +176,7 @@ def IsTorsionFree : Prop := torsion cov = 0 lemma isTorsionFree_iff : IsTorsionFree cov ↔ ∀ {X Y x}, MDiffAt (T% X) x → MDiffAt (T% Y) x → - cov X x (Y x) - cov Y x (X x) = mlieBracket I X Y x := by + cov Y x (X x) - cov X x (Y x) = mlieBracket I X Y x := by unfold IsTorsionFree constructor · intro h X Y x hX hY From 1f3bc997686deccfb9eeca606366688b7546a106 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 15:52:09 +0000 Subject: [PATCH 498/601] Gotcha: the argument order in Torsion.lean was flipped; with that fixed, LC is actually torsion-free! --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 4800dc560d6012..f6f0349f09bd27 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -181,7 +181,8 @@ namespace CovariantDerivative -- TODO: include in cheat sheet! variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) -local notation "∇" X "," Y => fun (x:M) ↦ cov X x (Y x) +/-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ +local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ From 29266bc408c6532d9db89cde33ea7f8af0383279 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 16:06:13 +0000 Subject: [PATCH 499/601] fix: make all code using torsion-freeness work again This involved correcting *some* old code that did the wrong thing! --- .../CovariantDerivative/LeviCivita.lean | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index f6f0349f09bd27..985b3b79bf704e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -814,12 +814,12 @@ variable [FiniteDimensional ℝ E] in variable (Y) in lemma aux (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = - ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ Z, X⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by - trans ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by + trans ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x · -- TODO: is something wrong, -- or do we just need to thread through more differentiability assumptions? - apply cov.IsCompatible_apply I h.1 sorry hZ - · sorry -- simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] + sorry--apply cov.IsCompatible_apply I h.1 sorry hZ + · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term @@ -827,7 +827,7 @@ variable {cov} in lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional ℝ E] (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - ⟪∇ X, Y, Z⟫ x = leviCivitaRhs I X Y Z x := by + ⟪∇ Y, X, Z⟫ x = leviCivitaRhs I X Y Z x := by unfold leviCivitaRhs leviCivitaRhs' have eq1 := aux I Y cov h hX hZ have eq2 := aux I Z cov h hY hX @@ -866,8 +866,7 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) {X Y : Π x : M, TangentSpace I x} {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : - -- almost, only agree on smooth functions - cov X x (Y x) = cov' X x (Y x) := by + cov Y x (X x) = cov' Y x (X x) := by have : FiniteDimensional ℝ (TangentSpace I x) := inferInstanceAs (FiniteDimensional ℝ E) have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete ℝ _ set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) @@ -875,7 +874,7 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] ext Z₀ let Z := _root_.extend I E Z₀ have hZ := mdifferentiableAt_extend I E Z₀ x - suffices inner ℝ (cov X x (Y x)) (Z x) = inner ℝ (cov' X x (Y x)) (Z x) by simpa [Φ, Z] + suffices inner ℝ (cov Y x (X x)) (Z x) = inner ℝ (cov' Y x (X x)) (Z x) by simpa [Φ, Z] trans leviCivitaRhs I X Y Z x · rw [← hcov.eq_leviCivitaRhs I hX hY hZ] · rw [← hcov'.eq_leviCivitaRhs I hX hY hZ] From 1ee1a318beff0aa4672ef843a96a897254119169 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 16:28:37 +0000 Subject: [PATCH 500/601] Fix compatibility lemma; fix torsion lemma, fix application in aux. --- .../CovariantDerivative/LeviCivita.lean | 30 ++++++++----------- .../CovariantDerivative/Torsion.lean | 17 +++++------ 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 985b3b79bf704e..7661a2ac2ccda6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -341,21 +341,18 @@ the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 +-- Auxiliary computation for `IsCompatible_apply`. +-- TODO: inlining this lemma does not work +private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + C := by grind + lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ X, Y, Z⟫ x + ⟪Y, ∇ X, Z⟫ x := by + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by rw [IsCompatible] at hcov have : MetricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] rw [metricTensor_apply cov x hY hZ] at this - simp [bar] at this - set A := (mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x) - have : A = ⟪fun x ↦ (cov Y x) (X x), Z⟫ x + ⟪Y, fun x ↦ (cov Z x) (X x)⟫ x := sorry -- use this - rw [this] - - -- TODO: was there a mix-up in the definition of metric tensor above? - -- set B := ⟪fun x ↦ (cov X x) (Y x), Z⟫ x - -- set C := ⟪Y, fun x ↦ (cov X x) (Z x)⟫ x - sorry + change (bar _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ + exact isCompatible_apply_aux this /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. @@ -811,14 +808,11 @@ lemma leviCivitaRhs_smulZ_apply [CompleteSpace E] {f : M → ℝ} end leviCivitaRhs variable [FiniteDimensional ℝ E] in -variable (Y) in lemma aux (h : cov.IsLeviCivitaConnection) {x : M} - (hX : MDiffAt (T% X) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by trans ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x - · -- TODO: is something wrong, - -- or do we just need to thread through more differentiability assumptions? - sorry--apply cov.IsCompatible_apply I h.1 sorry hZ + · exact cov.IsCompatible_apply I h.1 hY hZ · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in @@ -829,9 +823,9 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional ℝ E] {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : ⟪∇ Y, X, Z⟫ x = leviCivitaRhs I X Y Z x := by unfold leviCivitaRhs leviCivitaRhs' - have eq1 := aux I Y cov h hX hZ - have eq2 := aux I Z cov h hY hX - have eq3 := aux I X cov h hZ hY + have eq1 := aux I cov h hX hY hZ + have eq2 := aux I cov h hY hZ hX + have eq3 := aux I cov h hZ hX hY simp [real_inner_comm, smul_eq_mul] at * linear_combination - (eq1 + eq2 - eq3) / 2 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 34c81339c24808..36487db067fde6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -80,18 +80,17 @@ lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative torsionFun cov (f • X) Y x = f x • torsionFun cov X Y x := by simp only [torsionFun] rw [hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] - simp? [bar, smul_sub] says - simp only [bar, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, - ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.coe_mk, - LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk, Function.comp_apply, - ContinuousLinearMap.toSpanSingleton_apply, Pi.smul_apply', map_smul, smul_sub] + simp? [smul_sub] says + simp only [Pi.smul_apply', map_smul, ContinuousLinearMap.add_apply, + ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.coe_comp', + ContinuousLinearEquiv.coe_coe, Function.comp_apply, ContinuousLinearMap.toSpanSingleton_apply, + smul_sub] set A := f x • (cov X x) (Y x) set B := f x • (cov Y x) (X x) set C := f x • VectorField.mlieBracket I X Y x - sorry /-simp only [torsionFun, Pi.sub_apply, hF.smulX (X := X) (σ := Y) (f := f)] - rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] - simp [bar, smul_sub] - abel -/ + set D := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + change B - (A + (bar _ D) • X x) - (-(bar _ D) • X x + C) = B - A - C + module lemma torsionFun_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} From 9e77a0b1ba11d49dcdd6a222959411ffca50fef2 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 5 Mar 2026 17:47:17 +0100 Subject: [PATCH 501/601] Move delaborators --- Mathlib.lean | 1 + .../CovariantDerivative/Basic.lean | 1 + .../CovariantDerivative/Lift.lean | 35 ------ .../CovariantDerivative/TrivPrelim.lean | 38 +----- .../Manifold/VectorBundle/Delaborators.lean | 113 ++++++++++++++++++ 5 files changed, 118 insertions(+), 70 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9bba9b77694019..7120c49fb7e39f 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4422,6 +4422,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial +public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 170962ef6e7180..9c0fcc74976eee 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -8,6 +8,7 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.MfDerivSMul +public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators /-! # Covariant derivatives diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 39943001be6d7c..e107d6457741c6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -17,41 +17,6 @@ TODO: add a more complete doc-string @[expose] public section -section delaborators - --- TODO: decide whether we want this and move --- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` -open Lean PrettyPrinter Delaborator SubExpr - -@[app_delab mfderiv] meta def delab_mfderiv : Delab := do - whenPPOption getPPNotation do - let args := (← getExpr).getAppArgs - if args.size < 22 then failure - let pt : Term ← withNaryArg 21 <| delab - let f := args[20]! - let m := mkIdent (.mkSimple "mfderiv%") - let T := mkIdent (.mkSimple "T%") - try - if let .lam _ _ b _ := f then - if b.isAppOf ``Bundle.TotalSpace.mk' then - let s := b.getAppArgs[4]!.getAppFn - if s matches .fvar .. then - let ss ← PrettyPrinter.delab s - return ← `($m ($T $ss) $pt) - throwError "nope" - catch _ => - let x : Term ← withNaryArg 20 <| delab - return ← `($m $x $pt) - -@[app_delab Bundle.TotalSpace.mk'] meta def delabTotalSpace_mk' : Delab := do - whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - -end delaborators - open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index 248d04d52fffaf..f20955bf0df987 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -8,6 +8,7 @@ module public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.MFDeriv.Atlas public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators /-! # Supporting lemmas for CovariantDerivative.Basic trivialization stuff @@ -16,45 +17,12 @@ TODO: PR all this to appropriate places. -/ +@[expose] public section + open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff -@[expose] public section - -section delaborators - --- TODO: decide whether we want this and move --- This delaborates `TotalSpace.mk x v` to `⟨x, v⟩` -open Lean PrettyPrinter Delaborator SubExpr - -@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do - whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - -@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do - whenPPOption getPPNotation do - let args := (← getExpr).getAppArgs - if args.size < 22 then failure - let pt : Term ← withNaryArg 21 <| delab - let f := args[20]! - try - if let .lam _ _ b _ := f then - if b.isAppOf ``Bundle.TotalSpace.mk' then - let s := b.getAppArgs[4]!.getAppFn - if s matches .fvar .. then - let ss ← PrettyPrinter.delab s - return ← `(MDiffAt (T% $ss) $pt) - throwError "nope" - catch _ => - let x : Term ← withNaryArg 20 <| delab - return ← `(MDiffAt $x $pt) - -end delaborators - namespace Bundle.Trivialization section trivilization_topology diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean b/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean new file mode 100644 index 00000000000000..72252e54a3a5d3 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean @@ -0,0 +1,113 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.MFDeriv.Atlas +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +@[expose] public section + +section delaborators + +open Lean PrettyPrinter Delaborator SubExpr + +open scoped Bundle Manifold ContDiff + +@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +@[app_delab Bundle.TotalSpace.mk'] meta def delabTotalSpace_mk' : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure + let bd : Term ← withNaryArg 3 <| delab + let vd : Term ← withNaryArg 4 <| delab + `(⟨$bd, $vd⟩) + +@[app_delab mfderiv] meta def delab_mfderiv : Delab := do + whenPPOption getPPNotation do + withOverApp 21 do + try + let f := (← getExpr).appArg! + let .lam n _ b _ := f | failure + guard <| b.isAppOf ``Bundle.TotalSpace.mk' + let s := b.getAppArgs[4]!.getAppFn + guard <| s.isFVar + let ss ← withAppArg do + let ss ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + annotateGoToSyntaxDef (← `(T% $ss)) + let stx ← `(mfderiv% ($ss)) + annotateGoToSyntaxDef stx + catch _ => + let f ← withAppArg delab + annotateGoToSyntaxDef (← `(mfderiv% $f)) + +@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do + whenPPOption getPPNotation do + withOverApp 21 do + try + let f := (← getExpr).appArg! + let .lam n _ b _ := f | failure + guard <| b.isAppOf ``Bundle.TotalSpace.mk' + let s := b.getAppArgs[4]!.getAppFn + guard <| s.isFVar + let ss ← withAppArg do + let ss ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + annotateGoToSyntaxDef (← `(T% $ss)) + let stx ← `(MDiffAt $ss) + annotateGoToSyntaxDef stx + catch _ => + let f ← withAppArg delab + annotateGoToSyntaxDef (← `(MDiffAt $f)) + +-- @[app_delab MDifferentiableWithinAt] meta def delabMDifferentiableWithinAt : Delab := do +-- whenPPOption getPPNotation do +-- withOverApp 22 do +-- try +-- let f := (← getExpr).getAppArgs[20]! +-- let .lam n _ b _ := f | failure +-- guard <| b.isAppOf ``Bundle.TotalSpace.mk' +-- let s := b.getAppArgs[4]!.getAppFn +-- guard <| s.isFVar +-- let fs ← withNaryArg 20 <| delab +-- let ss ← withAppArg do +-- let ss ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab +-- annotateGoToSyntaxDef (← `(T% $ss)) +-- let stx ← `(MDiffAt $ss) +-- annotateGoToSyntaxDef stx +-- catch _ => +-- let ss ← withAppArg delab +-- let fs ← withNaryArg 20 <| delab +-- annotateGoToSyntaxDef (← `(MDiffAt[$ss] $fs)) + +section + +open Bundle +open scoped Bundle Manifold ContDiff + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] [IsManifold I ∞ M] + (f : M → M) (x : M) (s : Set M) + (v : (x : M) → TangentSpace I x) + +-- #check MDiffAt f x +-- #check MDiffAt[s] f x +-- #check mfderiv% f x +-- #check mfderiv I I.tangent (fun x ↦ Bundle.TotalSpace.mk' E x (v x)) x +-- #check mfderiv% (T% v) x +-- #check TotalSpace.mk' E x (v x) + +end +end delaborators From 50be730c3f3910ecc8680fa3a2dab6d1a31cbdbc Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 16:49:00 +0000 Subject: [PATCH 502/601] Towards showing compatibility of LC --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 7661a2ac2ccda6..6b595c41a2d27b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -345,7 +345,8 @@ def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 -- TODO: inlining this lemma does not work private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + C := by grind -lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} +variable {I} in +lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by rw [IsCompatible] at hcov @@ -354,6 +355,13 @@ lemma IsCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x change (bar _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ exact isCompatible_apply_aux this +lemma isCompatible_iff [FiniteDimensional ℝ E] : + cov.IsCompatible ↔ ∀ {x : M} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x), + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by + refine ⟨fun hcov x hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ + unfold IsCompatible + sorry + /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a @@ -812,7 +820,7 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by trans ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x - · exact cov.IsCompatible_apply I h.1 hY hZ + · exact cov.isCompatible_apply h.1 hY hZ · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in From 9430c13d1bc619f18842845672b687cff7a2448a Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 5 Mar 2026 18:08:17 +0100 Subject: [PATCH 503/601] More delaborators --- .../Manifold/VectorBundle/Delaborators.lean | 127 +++++++++++------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean b/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean index 72252e54a3a5d3..1187c35fa8f95b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean @@ -8,6 +8,11 @@ module public import Mathlib.Geometry.Manifold.MFDeriv.Atlas public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +/-! +# Delaborators for the custom elaborators + +-/ + open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff @@ -22,73 +27,69 @@ open scoped Bundle Manifold ContDiff @[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab + withOverApp 5 do + let bd ← withNaryArg 3 <| delab + let vd ← withNaryArg 4 <| delab `(⟨$bd, $vd⟩) @[app_delab Bundle.TotalSpace.mk'] meta def delabTotalSpace_mk' : Delab := do whenPPOption getPPNotation do - let #[_B, _F, _E, _b, _v] := (← getExpr).getAppArgs | failure - let bd : Term ← withNaryArg 3 <| delab - let vd : Term ← withNaryArg 4 <| delab + withOverApp 5 do + let bd ← withNaryArg 3 <| delab + let vd ← withNaryArg 4 <| delab `(⟨$bd, $vd⟩) @[app_delab mfderiv] meta def delab_mfderiv : Delab := do whenPPOption getPPNotation do withOverApp 21 do try - let f := (← getExpr).appArg! - let .lam n _ b _ := f | failure + let fe := (← getExpr).appArg! + let .lam n _ b _ := fe | failure guard <| b.isAppOf ``Bundle.TotalSpace.mk' - let s := b.getAppArgs[4]!.getAppFn - guard <| s.isFVar - let ss ← withAppArg do - let ss ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab - annotateGoToSyntaxDef (← `(T% $ss)) - let stx ← `(mfderiv% ($ss)) - annotateGoToSyntaxDef stx + let σe := b.getAppArgs[4]!.getAppFn + guard <| σe.isFVar + let Tσs ← withAppArg do + let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + `(T% $σs) >>= annotateGoToSyntaxDef + `(mfderiv% ($Tσs)) >>= annotateGoToSyntaxDef catch _ => - let f ← withAppArg delab - annotateGoToSyntaxDef (← `(mfderiv% $f)) + let fs ← withAppArg delab + `(mfderiv% $fs) >>= annotateGoToSyntaxDef @[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do whenPPOption getPPNotation do withOverApp 21 do try - let f := (← getExpr).appArg! + let fe := (← getExpr).appArg! + let .lam n _ b _ := fe | failure + guard <| b.isAppOf ``Bundle.TotalSpace.mk' + let σe := b.getAppArgs[4]!.getAppFn + guard <| σe.isFVar + let Tσs ← withAppArg do + let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + `((T% $σs)) >>= annotateGoToSyntaxDef + `(MDiffAt $Tσs) >>= annotateGoToSyntaxDef + catch _ => + let fs ← withAppArg delab + `(MDiffAt $fs) >>= annotateGoToSyntaxDef + +@[app_delab MDifferentiableWithinAt] meta def delabMDifferentiableWithinAt : Delab := do + whenPPOption getPPNotation do + withOverApp 22 do + let ss ← withAppArg delab + try + let f := (← getExpr).getAppArgs[20]! let .lam n _ b _ := f | failure guard <| b.isAppOf ``Bundle.TotalSpace.mk' let s := b.getAppArgs[4]!.getAppFn guard <| s.isFVar - let ss ← withAppArg do - let ss ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab - annotateGoToSyntaxDef (← `(T% $ss)) - let stx ← `(MDiffAt $ss) - annotateGoToSyntaxDef stx + let fs ← withNaryArg 20 do + let fs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab + `((T% $fs)) >>= annotateGoToSyntaxDef + `(MDiffAt[$ss] $fs) >>= annotateGoToSyntaxDef catch _ => - let f ← withAppArg delab - annotateGoToSyntaxDef (← `(MDiffAt $f)) - --- @[app_delab MDifferentiableWithinAt] meta def delabMDifferentiableWithinAt : Delab := do --- whenPPOption getPPNotation do --- withOverApp 22 do --- try --- let f := (← getExpr).getAppArgs[20]! --- let .lam n _ b _ := f | failure --- guard <| b.isAppOf ``Bundle.TotalSpace.mk' --- let s := b.getAppArgs[4]!.getAppFn --- guard <| s.isFVar --- let fs ← withNaryArg 20 <| delab --- let ss ← withAppArg do --- let ss ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab --- annotateGoToSyntaxDef (← `(T% $ss)) --- let stx ← `(MDiffAt $ss) --- annotateGoToSyntaxDef stx --- catch _ => --- let ss ← withAppArg delab --- let fs ← withNaryArg 20 <| delab --- annotateGoToSyntaxDef (← `(MDiffAt[$ss] $fs)) + let fs ← withNaryArg 20 <| delab + `(MDiffAt[$ss] $fs) >>= annotateGoToSyntaxDef section @@ -102,12 +103,36 @@ variable (f : M → M) (x : M) (s : Set M) (v : (x : M) → TangentSpace I x) --- #check MDiffAt f x --- #check MDiffAt[s] f x --- #check mfderiv% f x --- #check mfderiv I I.tangent (fun x ↦ Bundle.TotalSpace.mk' E x (v x)) x --- #check mfderiv% (T% v) x --- #check TotalSpace.mk' E x (v x) +/-- info: MDiffAt f x : Prop -/ +#guard_msgs in +#check MDiffAt f x + +/-- info: MDiffAt[s] f x : Prop -/ +#guard_msgs in +#check MDiffAt[s] f x + +/-- info: MDiffAt (T% v) x : Prop -/ +#guard_msgs in +#check MDiffAt (T% v) x + +/-- info: MDiffAt[s] (T% v) x : Prop -/ +#guard_msgs in +#check MDiffAt[s] (T% v) x + +/-- info: mfderiv% f x : TangentSpace I x →L[ℝ] TangentSpace I (f x) -/ +#guard_msgs in +#check mfderiv% f x + +/-- info: mfderiv% (T% v) x : TangentSpace I x →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, E)) ⟨x, v x⟩ -/ +#guard_msgs in +#check mfderiv% (T% v) x + +/-- info: ⟨x, v x⟩ : TotalSpace E (TangentSpace I) -/ +#guard_msgs in +#check TotalSpace.mk' E x (v x) +/-- info: ⟨x, v x⟩ : TotalSpace E (TangentSpace I) -/ +#guard_msgs in +#check TotalSpace.mk (F := E) x (v x) end end delaborators From d8cf6e70ebcd43b6d80b957e17d3145ddbb5d132 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 17:29:38 +0000 Subject: [PATCH 504/601] Some fixes --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 6 ++++-- .../VectorBundle/CovariantDerivative/TrivPrelim.lean | 4 ---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 6b595c41a2d27b..09ca5817f8fc98 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -233,8 +233,10 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) rw [product_add_left, mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), cov.isCovariantDerivativeOn.addσ hσ hσ', - ContinuousLinearMap.comp_add, ContinuousLinearMap.coe_sub', Pi.sub_apply, - ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] + ContinuousLinearMap.comp_add] + erw [ContinuousLinearMap.coe_sub'] + rw [Pi.sub_apply] + erw [ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index f20955bf0df987..e173dc7a7fd39c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -101,10 +101,6 @@ lemma funToSec_congr {s s' : B → F} {b : B} (h : s b = s' b) : e.funToSec s b = e.funToSec s' b := by simp [funToSec, h] -lemma totalSpace_mk'_funToSec {v : TotalSpace F E} (s : B → F) : - (T% (e.funToSec s) v.proj) = e.symm v.proj (s v.proj) := - rfl - @[simp] lemma secToFun_funToSec_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (s : B → F) : e.secToFun (e.funToSec s) =ᶠ[𝓝 x] s := by From e6e514a88711865b3fb02f781626be52d4dc74b5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 17:31:03 +0000 Subject: [PATCH 505/601] Sorry one broken proof --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 09ca5817f8fc98..536340ac81008b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -296,6 +296,7 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) rw [inner_add_right] erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.add_apply, ContinuousLinearMap.comp_apply] + /- TODO: proof used to be done before merging rc4; was: conv => enter [2, 2, 1, 2] erw [ContinuousLinearMap.comp_apply] @@ -303,12 +304,13 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) conv => enter [2, 2, 1, 2] erw [innerSL_apply_apply] + module -/ + sorry -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x -- set C := inner ℝ (σ x) ((cov τ x) X) -- set C' := inner ℝ (σ x) ((cov τ' x) X) -- set D := (cov σ x) X - module variable {I} in /-- The tensor `∇ g` defined by a connection `∇` on a Riemannian manifold `(M, g)`. -/ From eaf2185bdc118a84a1f30500d3253d4ecc866040 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 5 Mar 2026 18:41:13 +0100 Subject: [PATCH 506/601] Fix build --- .../Manifold/VectorBundle/CovariantDerivative/Trivial.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index 30f2f6d7e23215..7c9c2d1a4328f9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -38,6 +38,7 @@ namespace IsCovariantDerivativeOn section trivial_bundle +set_option backward.isDefEq.respectTransparency false in variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : @@ -66,6 +67,7 @@ namespace CovariantDerivative section trivial_bundle +set_option backward.isDefEq.respectTransparency false in variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where From 0f1fc6ccbe78d8cbf04027cad91d2612f0ad77de Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Thu, 5 Mar 2026 20:34:06 +0000 Subject: [PATCH 507/601] remove bump functions from "extend" construction --- .../CovariantDerivative/Basic.lean | 164 ++++++-------- .../CovariantDerivative/Ehresmann.lean | 147 ++++++------- .../CovariantDerivative/LeviCivita.lean | 74 +++---- .../CovariantDerivative/Lift.lean | 63 +++--- .../CovariantDerivative/Torsion.lean | 37 ++-- .../CovariantDerivative/Trivial.lean | 30 +-- .../Manifold/VectorBundle/Extend.lean | 123 ++++------- .../Manifold/VectorBundle/Tensoriality.lean | 207 +++++++++--------- 8 files changed, 398 insertions(+), 447 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 9c0fcc74976eee..f32acf5d5bfeb8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -216,9 +216,7 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : ℕ∞} variable {s : Set M} {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma add_one_form [∀ (x : M), IsTopologicalAddGroup (V x)] - [∀ (x : M), ContinuousSMul 𝕜 (V x)] (hf : IsCovariantDerivativeOn F f s) +lemma add_one_form (hf : IsCovariantDerivativeOn F f s) (A : Π x : M, V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : IsCovariantDerivativeOn F (fun σ x ↦ f σ x + A x (σ x)) s where addσ {_σ _σ' _x} hσ hσ' hx := by @@ -342,62 +340,37 @@ lemma ContMDiffCovariantDerivative.affineCombination' [VectorBundle 𝕜 F V] end operations end CovariantDerivative -end any_field - -section real - -variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] - -- `F` model fiber - (n : WithTop ℕ∞) - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] - [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] - -- `V` vector bundle +variable {x : M} namespace IsCovariantDerivativeOn --- TODO can probably work for `IsManifold I 1 M`, --- by weakening the conditions for the `extend` construction -theorem ext [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] - {P P' : (Π x : M, TangentSpace I x →L[ℝ] V x)} {x} +omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +theorem ext [IsManifold I 1 M] + {P P' : (Π x : M, TangentSpace I x →L[𝕜] V x)} {x} (H : ∀ {X : Π x : M, TangentSpace I x}, MDiffAt (T% X) x → P x (X x) = P' x (X x)) : P x = P' x := by ext X₀ - rw [← extend_apply_self (I := I) (F := E) X₀] - exact H (mdifferentiable_extend ..) - -/-- `cov X σ x` only depends on `X` via `X x` -/ -lemma congr_X_at - {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - {X X' : Π x : M, TangentSpace I x} - {σ : Π x : M, V x} {x : M} - (hXX' : X x = X' x) : - cov σ x (X x) = cov σ x (X' x) := by - rw [hXX'] - -lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] - [FiniteDimensional ℝ E] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) - {σ : Π x : M, V x} - (hσ : MDiffAt (T% σ) x) - (f : SmoothBumpFunction I x) - (hx : x ∈ u) : - cov ((f : M → ℝ) • σ) x = cov σ x := by - have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) - rw [hcov.leibniz hσ hf hx, f.eq_one, f.eventuallyEq_one.mfderiv_eq] - rw [show mfderiv I 𝓘(ℝ, ℝ) 1 x = 0 by apply mfderiv_const] - simp - -lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [VectorBundle ℝ F V] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} + rw [← extend_apply_self (F := E) X₀] + exact H (mdifferentiableAt_extend ..) + +-- lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] +-- [FiniteDimensional 𝕜 E] +-- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] +-- {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} +-- {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) +-- {σ : Π x : M, V x} +-- (hσ : MDiffAt (T% σ) x) +-- (f : SmoothBumpFunction I x) +-- (hx : x ∈ u) : +-- cov ((f : M → 𝕜) • σ) x = cov σ x := by +-- have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) +-- rw [hcov.leibniz hσ hf hx, f.eq_one, f.eventuallyEq_one.mfderiv_eq] +-- rw [show mfderiv I 𝓘(𝕜, 𝕜) 1 x = 0 by apply mfderiv_const] +-- simp + +lemma congr_σ_of_eqOn [IsManifold I 1 M] + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) @@ -405,44 +378,60 @@ lemma congr_σ_of_eqOn [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M (hxs : s ∈ 𝓝 x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : cov σ x = cov σ' x := by - -- Choose a smooth bump function ψ with support around `x` contained in `s` - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hxs).mem_iff.1 hxs + classical + have hxs' : x ∈ s := mem_of_mem_nhds hxs + let ψ (x' : M) : 𝕜 := if x' ∈ s then 1 else 0 + have hψx : ψ x = 1 := by simp [ψ, hxs'] -- Observe that `ψ • σ = ψ • σ'` as dependent functions. - have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by - by_cases h : x ∈ s - · simp [hσσ' x h] - · simp [Function.notMem_support.mp fun a ↦ h (hψ a)] + have H (x' : M) : ((ψ : M → 𝕜) • σ) x' = ((ψ : M → 𝕜) • σ') x' := by + dsimp [ψ] + split_ifs with hx's + · simpa using hσσ' _ hx's + · simp + have hψ' : HasMFDerivAt I 𝓘(𝕜) ψ x 0 := by + have : HasMFDerivAt I 𝓘(𝕜, 𝕜) (fun x_1 ↦ (1:𝕜)) x 0 := hasMFDerivAt_const .. + refine this.congr_of_eventuallyEq ?_ + apply Filter.eventuallyEq_of_mem hxs + intro t ht + simp [ψ, ht] + have := hcov.leibniz hσ hψ'.mdifferentiableAt -- Then, it's a chain of (dependent) equalities. calc cov σ x - _ = cov ((ψ : M → ℝ) • σ) x := by - rw [hcov.congr_σ_smoothBumpFunction hσ ψ (mem_of_mem_nhds hxs)] - _ = cov ((ψ : M → ℝ) • σ') x := by rw [funext this] + _ = cov ((ψ : M → 𝕜) • σ) x := by + rw [hcov.leibniz hσ hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] + erw [ContinuousLinearMap.comp_zero] + simp + _ = cov ((ψ : M → 𝕜) • σ') x := by rw [funext H] _ = cov σ' x := by - rw [hcov.congr_σ_smoothBumpFunction hσ' ψ (mem_of_mem_nhds hxs)] + rw [hcov.leibniz hσ' hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] + erw [ContinuousLinearMap.comp_zero] + simp -- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x --- this should be easy using the projection formula below. +-- this should be easy using the projection formula in `CovariantDerivative.Ehresmann`. /-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ noncomputable def differenceAux - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : - (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x) := + (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : + (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := fun σ ↦ cov σ - cov' σ -variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] +variable [CompleteSpace 𝕜] + [IsManifold I 1 M] + [FiniteDimensional 𝕜 F] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] -open Classical in -/-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] - [FiniteDimensional ℝ F] [T2Space M] [FiniteDimensional ℝ E] [IsManifold I ∞ M] - [FiniteDimensional ℝ E] [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} +variable + {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) - (x : M) : V x →L[ℝ] TangentSpace I x →L[ℝ] V x := + +open Classical in +/-- The difference of two covariant derivatives, as a tensorial map -/ +noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := if hxs : x ∈ s then mkTensorAt I F (differenceAux cov cov') x (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) @@ -451,31 +440,16 @@ noncomputable def difference [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Spac 0 -- do we need this? -lemma difference_def [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] - [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] - [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - {s : Set M} {x : M} - (hcov : IsCovariantDerivativeOn F cov s) - (hcov' : IsCovariantDerivativeOn F cov' s) - (hx : x ∈ s := by trivial) (σ₀ : V x) : - difference hcov hcov' x σ₀ = - cov (extend I F σ₀) x - cov' (extend I F σ₀) x := by +-- omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in +lemma difference_def (hx : x ∈ s := by trivial) (σ₀ : V x) : difference hcov hcov' x σ₀ = + cov (extend F σ₀) x - cov' (extend F σ₀) x := by simp only [difference, hx, reduceDIte] rfl +-- omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in @[simp] -lemma difference_apply [∀ x, FiniteDimensional ℝ (V x)] [∀ x, T2Space (V x)] - [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ E] - [VectorBundle ℝ F V] [ContMDiffVectorBundle ∞ F V I] - {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} - {s : Set M} {x : M} - (hcov : IsCovariantDerivativeOn F cov s) - (hcov' : IsCovariantDerivativeOn F cov' s) - (hx : x ∈ s := by trivial) {σ : Π x, V x} - (hσ : MDiffAt (T% σ) x) : - difference hcov hcov' x (σ x) = - cov σ x - cov' σ x := by +lemma difference_apply (hx : x ∈ s := by trivial) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : + difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by simp only [difference, hx, reduceDIte] rw [mkTensorAt_apply _ _ _ hσ] rfl diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index c4795570a00c50..0c0fa0bae1eba7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -5,17 +5,9 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection -public import Mathlib.Geometry.Manifold.VectorBundle.Tangent -public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv -public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -public import Mathlib.Geometry.Manifold.BumpFunction public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.VectorBundle.Misc -public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -public import Mathlib.Geometry.Manifold.VectorField.LieBracket -public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial /-! @@ -35,15 +27,15 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] section real variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} + [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `F` model fiber (n : WithTop ℕ∞) {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] -- `V` vector bundle @@ -53,16 +45,16 @@ namespace IsCovariantDerivativeOn section projection_trivial_bundle -variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] +variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] + [IsManifold I 1 M] local notation "TM" => TangentSpace I -variable {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} {s : Set M} +variable {cov : (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F)} {s : Set M} noncomputable -def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) × F →L[ℝ] F := - .snd ℝ (TM x) F + (hcov.one_form x f ∘L .fst ℝ (TM x) F) +def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) × F →L[𝕜] F := + .snd 𝕜 (TM x) F + (hcov.one_form x f ∘L .fst 𝕜 (TM x) F) @[simp] lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : @@ -70,11 +62,11 @@ lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (σ : M → F) {x : M} (X₀ : TM x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - cov σ x X₀ = hcov.projection x (σ x) (X₀, mfderiv I 𝓘(ℝ, F) σ x X₀) := by + cov σ x X₀ = hcov.projection x (σ x) (X₀, mfderiv I 𝓘(𝕜, F) σ x X₀) := by simpa using congr($(hcov.eq_one_form hσ) X₀) noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : - Submodule ℝ (TM x × F) := + Submodule 𝕜 (TM x × F) := (hcov.projection x f).ker lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : @@ -89,16 +81,16 @@ lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f all_goals simp [horiz] set_option backward.isDefEq.respectTransparency false in -lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : F} - {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ +lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] (hcov : IsCovariantDerivativeOn F cov s) {x : M} + {f : F} {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ ∃ σ : M → F, MDiffAt (T% σ) x ∧ σ x = f ∧ - mfderiv I 𝓘(ℝ, F) σ x u = v ∧ + mfderiv I 𝓘(𝕜, F) σ x u = v ∧ cov σ x u = 0 := by constructor · intro huv simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv - let w : TangentSpace 𝓘(ℝ, F) f := v + let w : TangentSpace 𝓘(𝕜, F) f := v by_cases hu : u = 0 · subst hu replace huv : v = 0 := by simpa using huv @@ -130,20 +122,20 @@ namespace Bundle.Trivialization section to_trivialization -variable (e : Trivialization F (π F V)) [VectorBundle ℝ F V] [MemTrivializationAtlas e] +variable (e : Trivialization F (π F V)) [VectorBundle 𝕜 F V] [MemTrivializationAtlas e] [IsManifold I 1 M] noncomputable def pushCovDer - (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)) : - (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F) := - fun σ x ↦ e.continuousLinearMapAt ℝ x ∘L (cov (e.funToSec σ) x) + (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : + (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F) := + fun σ x ↦ e.continuousLinearMapAt 𝕜 x ∘L (cov (e.funToSec σ) x) -lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] +lemma pushCovDer_ofSect [FiniteDimensional 𝕜 F] + [IsManifold I 1 M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] - {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : IsCovariantDerivativeOn F cov e.baseSet) {X₀ : TangentSpace I x} {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) @@ -161,11 +153,11 @@ lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] simp [coe_linearMapAt, hx] -variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[ℝ] V x)} +variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) lemma pushCovDer_isCovariantDerivativeOn - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] {u : Set M} (hu : u ⊆ e.baseSet) (hcov : IsCovariantDerivativeOn F cov u) : @@ -184,7 +176,7 @@ lemma pushCovDer_isCovariantDerivativeOn rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] congr ext y - simp [e.symm_map_add ℝ, s, s'] + simp [e.symm_map_add 𝕜, s, s'] leibniz {σ g x} hσ hg hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := @@ -203,19 +195,19 @@ lemma pushCovDer_isCovariantDerivativeOn ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply, _root_.map_smul, add_right_inj, s] congr! 1 - exact e.linearMapAt_symmₗ (R := ℝ) (hu hx) (σ x) + exact e.linearMapAt_symmₗ (R := 𝕜) (hu hx) (σ x) variable {e} in lemma coordChangeL_pushCovDer - [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] + [IsManifold I 1 M] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {s : M → F} (hs : MDiffAt s x) : - e.coordChangeL ℝ e' x ∘L (e.pushCovDer cov s x) = - e'.pushCovDer cov (fun x ↦ e.coordChangeL ℝ e' x (s x)) x := by + e.coordChangeL 𝕜 e' x ∘L (e.pushCovDer cov s x) = + e'.pushCovDer cov (fun x ↦ e.coordChangeL 𝕜 e' x (s x)) x := by ext1 X₀ simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, Function.comp_apply] unfold pushCovDer @@ -230,7 +222,7 @@ lemma coordChangeL_pushCovDer rw [this] -- TODO: extract lemma? have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = - e'.symm x' ((fun x ↦ (coordChangeL ℝ e e' x) (s x)) x') := by + e'.symm x' ((fun x ↦ (coordChangeL 𝕜 e e' x) (s x)) x') := by rintro x' ⟨hx'e, hx'e'⟩ simp only rw [coordChangeL_apply e e' ⟨hx'e, hx'e'⟩] @@ -248,28 +240,29 @@ lemma coordChangeL_pushCovDer have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 exact this.mdifferentiableAt (zero_ne_one.symm) |>.clm_apply hs +variable [CompleteSpace 𝕜] variable {e} in -lemma coordChangeL_mem_horiz - [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] +lemma coordChangeL_mem_horiz [FiniteDimensional 𝕜 E] + [IsManifold I 1 M] [FiniteDimensional 𝕜 F] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov (u, w) ∈ hcove.horiz x v → - (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by + (u, e.coordChangeL 𝕜 e' x w) ∈ hcove'.horiz x (e.coordChangeL 𝕜 e' x v) := by have hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov have hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] rintro ⟨s, sdiff, sxv, sxuw, covs⟩ - use fun x ↦ e.coordChangeL ℝ e' x (s x), ?_, ?_, ?_ - · let X := extend I E u + use fun x ↦ e.coordChangeL 𝕜 e' x (s x), ?_, ?_, ?_ + · let X := extend E u have hX : MDiffAt (T% X) x := by -- TODO: extract as lemma? - exact (mdifferentiable_extend I E u).mdifferentiableAt + exact mdifferentiableAt_extend I E u -- TODO: investigate whether the following line comes from inconsistent ways to -- state assumptions rw [mdifferentiableAt_section_trivial_iff] at sdiff @@ -285,14 +278,14 @@ variable {e} in lemma coordChangeL_coordChangeL {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : - e'.coordChangeL ℝ e x (e.coordChangeL ℝ e' x v) = v := by + e'.coordChangeL 𝕜 e x (e.coordChangeL 𝕜 e' x v) = v := by have hx' := inter_comm _ _ ▸ hx - change ((coordChangeL ℝ e' e x) ∘ (coordChangeL ℝ e e' x)) v = v + change ((coordChangeL 𝕜 e' e x) ∘ (coordChangeL 𝕜 e e' x)) v = v rw [coe_coordChangeL _ _ hx] rw [coe_coordChangeL _ _ hx'] change - ((linearEquivAt ℝ e x hx'.2 ∘ (linearEquivAt ℝ e' x hx'.1).symm) ∘ - (linearEquivAt ℝ e' x hx'.1 ∘ (linearEquivAt ℝ e x hx'.2).symm)) + ((linearEquivAt 𝕜 e x hx'.2 ∘ (linearEquivAt 𝕜 e' x hx'.1).symm) ∘ + (linearEquivAt 𝕜 e' x hx'.1 ∘ (linearEquivAt 𝕜 e x hx'.2).symm)) v = v rw [Function.comp_assoc] conv => @@ -301,34 +294,34 @@ lemma coordChangeL_coordChangeL rfl rw [← Function.comp_assoc] change - ((linearEquivAt ℝ e x _) ∘ - (↑(linearEquivAt ℝ e' x hx'.1).symm ∘ₗ (linearEquivAt ℝ e' x hx'.1).toLinearMap) ∘ _) + ((linearEquivAt 𝕜 e x _) ∘ + (↑(linearEquivAt 𝕜 e' x hx'.1).symm ∘ₗ (linearEquivAt 𝕜 e' x hx'.1).toLinearMap) ∘ _) v = v - rw [(linearEquivAt ℝ e' x hx'.1).symm_comp] + rw [(linearEquivAt 𝕜 e' x hx'.1).symm_comp] simp only [LinearMap.id_coe, CompTriple.comp_eq] - change (↑(linearEquivAt ℝ e x hx'.2) ∘ₗ (linearEquivAt ℝ e x _).symm.toLinearMap) v = v - rw [(linearEquivAt ℝ e x hx'.2).comp_symm] + change (↑(linearEquivAt 𝕜 e x hx'.2) ∘ₗ (linearEquivAt 𝕜 e x _).symm.toLinearMap) v = v + rw [(linearEquivAt 𝕜 e x hx'.2).comp_symm] simp variable {e} in -lemma coordChangeL_mem_horiz_iff - [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] +lemma coordChangeL_mem_horiz_iff [FiniteDimensional 𝕜 E] + [IsManifold I 1 M] [FiniteDimensional 𝕜 F] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov (u, w) ∈ hcove.horiz x v ↔ - (u, e.coordChangeL ℝ e' x w) ∈ hcove'.horiz x (e.coordChangeL ℝ e' x v) := by + (u, e.coordChangeL 𝕜 e' x w) ∈ hcove'.horiz x (e.coordChangeL 𝕜 e' x v) := by refine ⟨e.coordChangeL_mem_horiz hcov hx, fun hu ↦ ?_⟩ - let v' := e.coordChangeL ℝ e' x v - let w' := e.coordChangeL ℝ e' x w + let v' := e.coordChangeL 𝕜 e' x v + let w' := e.coordChangeL 𝕜 e' x w rw [inter_comm] at hx hcov have hx' := inter_comm _ _ ▸ hx - have hvv' : v = e'.coordChangeL ℝ e x v' := (coordChangeL_coordChangeL hx' v).symm - have hww' : w = e'.coordChangeL ℝ e x w' := (coordChangeL_coordChangeL hx' w).symm + have hvv' : v = e'.coordChangeL 𝕜 e x v' := (coordChangeL_coordChangeL hx' v).symm + have hww' : w = e'.coordChangeL 𝕜 e x w' := (coordChangeL_coordChangeL hx' w).symm have key := e'.coordChangeL_mem_horiz hcov hx (w := w') (u := u) (v := v') ?_ · rw [← hvv', ← hww'] at key convert key using 2 @@ -343,10 +336,10 @@ end Bundle.Trivialization section horiz namespace CovariantDerivative -variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] - [T2Space M] [IsManifold I ∞ M] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] +variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] + [IsManifold I 1 M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] local notation "TM" => TangentSpace I @@ -354,15 +347,15 @@ local notation "TM" => TangentSpace I noncomputable def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - TangentSpace (I.prod 𝓘(ℝ, F)) v →L[ℝ] V v.proj := + TangentSpace (I.prod 𝓘(𝕜, F)) v →L[𝕜] V v.proj := letI t := trivializationAt F V v.proj haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (u := t.baseSet) subset_rfl (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) letI tproj := d_covDerOn.projection v.proj (t v).2 letI Tvt := t.deriv I v - t.symmL ℝ v.proj ∘L tproj ∘L Tvt + t.symmL 𝕜 v.proj ∘L tproj ∘L Tvt -omit [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] in +omit [FiniteDimensional 𝕜 F] in lemma isCovariantDerivativeOn_pushCovDer (cov : CovariantDerivative I F V) (e : Trivialization F (π F V)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := @@ -370,7 +363,7 @@ lemma isCovariantDerivativeOn_pushCovDer (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod - 𝓘(ℝ, F)) v) : + 𝓘(𝕜, F)) v) : letI t := trivializationAt F V v.proj haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t letI tproj := d_covDerOn.projection v.proj (t v).2 @@ -379,11 +372,11 @@ lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : - Submodule ℝ (TangentSpace (I.prod 𝓘(ℝ, F)) v) := + Submodule 𝕜 (TangentSpace (I.prod 𝓘(𝕜, F)) v) := (cov.proj v).ker lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} - (u : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + (u : TangentSpace (I.prod 𝓘(𝕜, F)) v) : u ∈ cov.horiz v ↔ cov.proj v u = 0 := by simp [horiz] @@ -397,7 +390,7 @@ lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalS let Tvt := t.deriv I v haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t let tproj := hcov.projection v.proj (t v).2 - let t' := t.continuousLinearEquivAt ℝ v.proj (mem_baseSet_trivializationAt F V v.proj) + let t' := t.continuousLinearEquivAt 𝕜 v.proj (mem_baseSet_trivializationAt F V v.proj) ext u change t'.symm (tproj (Tvt u)) = 0 ↔ tproj (Tvt u) = 0 simp @@ -424,13 +417,13 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] {σ : Π x : M, V x} (x : M) (hσ : MDiffAt (T% σ) x) : cov σ x = cov.proj (σ x) ∘L - (mfderiv I (I.prod 𝓘(ℝ, F)) (T% σ) x) := by + (mfderiv I (I.prod 𝓘(𝕜, F)) (T% σ) x) := by stop let t := trivializationAt F V x let s := fun x ↦ (t (σ x)).2 let Tσx := mfderiv% (T% σ) x -- FIXME `mfderiv%` fails in next line (fixed on master?) - let Ttσx := mfderiv (I.prod 𝓘(ℝ, F)) (I.prod 𝓘(ℝ, F)) t (σ x) + let Ttσx := mfderiv (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) t (σ x) ext1 X₀ change cov σ x X₀ = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) X₀) have hcov := cov.isCovariantDerivativeOn_pushCovDer t diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 536340ac81008b..31c8788f00d939 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -37,7 +37,7 @@ set_option backward.isDefEq.respectTransparency false variable {n : WithTop ℕ∞} {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I ∞ M] + {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] -- don't need this assumption (yet?) -- [IsRiemannianManifold I M] @@ -61,7 +61,7 @@ local notation "⟪" X ", " Y "⟫" => product I X Y -- Basic API for the product of two vector fields. section product -omit [IsManifold I ∞ M] +omit [IsManifold I 2 M] lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl @@ -140,19 +140,19 @@ end product -- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) -- only hold point-wise. They abstract the expanding and unexpanding of `product`. -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in lemma product_congr_left {x} (h : X x = X' x) : product I X Y x = product I X' Y x := by rw [product_apply, h, ← product_apply] -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in lemma product_congr_left₂ {x} (h : X x = X' x + X'' x) : product I X Y x = product I X' Y x + product I X'' Y x := by rw [product_apply, h, inner_add_left, ← product_apply] -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in lemma product_congr_right {x} (h : Y x = Y' x) : product I X Y x = product I X Y' x := by rw [product_apply, h, ← product_apply] -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : product I X Y x = product I X Y' x + product I X Y'' x := by rw [product_apply, h, inner_add_right, ← product_apply] @@ -388,14 +388,14 @@ noncomputable abbrev rhs_aux : M → ℝ := fun x ↦ (mfderiv% ⟪Y, Z⟫ x (X section rhs_aux variable (Y Z) in -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by ext x simp only [rhs_aux] congr 2 exact product_swap I Z Y -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in variable (X X' Y Z) in lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by ext x @@ -430,12 +430,12 @@ lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) ext x exact rhs_aux_addZ_apply I X (hY x) (hZ x) (hZ' x) -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in variable (X Y Z) in lemma rhs_aux_smulX_apply (f : M → ℝ) (x) : rhs_aux I (f • X) Y Z x = f x • rhs_aux I X Y Z x := by simp [rhs_aux] -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in variable (X Y Z) in lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by ext x @@ -518,7 +518,7 @@ If `∇` is a Levi-Civita connection on `TM`, then `⟨∇ X Y, Z⟩ = leviCivitaRhs I X Y Z` for all smooth vector fields `X`, `Y` and `Z`. -/ noncomputable def leviCivitaRhs : M → ℝ := (1 / 2 : ℝ) • leviCivitaRhs' I X Y Z -omit [IsManifold I ∞ M] in +omit [IsManifold I 2 M] in lemma leviCivitaRhs_apply : leviCivitaRhs I X Y Z x = (1 / 2 : ℝ) • leviCivitaRhs' I X Y Z x := rfl @@ -843,6 +843,7 @@ lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional ℝ E] section +omit [IsManifold I 2 M] [IsContMDiffRiemannianBundle I 1 E (TangentSpace I (M := M))] in variable {I} in lemma congr_of_forall_product_apply [FiniteDimensional ℝ E] {Y Y' : TangentSpace I x} (h : ∀ Z : TangentSpace I x, inner ℝ Y Z = inner ℝ Y' Z) : Y = Y' := by @@ -853,6 +854,7 @@ lemma congr_of_forall_product_apply [FiniteDimensional ℝ E] {Y Y' : TangentSpa ext Z₀ simpa [Φ, product] using h Z₀ +omit [IsContMDiffRiemannianBundle I 1 E (TangentSpace I (M := M))] in variable {I} in /-- If two vector fields `X` and `X'` on `M` satisfy the relation `⟨X, Z⟩ = ⟨X', Z⟩` for all vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ @@ -862,7 +864,7 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] ext1 x apply congr_of_forall_product_apply intro Z₀ - simpa [product] using congr($(h (_root_.extend I E Z₀)) x) + simpa [product] using congr($(h (_root_.extend E Z₀)) x) /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ @@ -878,15 +880,13 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) apply Φ.injective ext Z₀ - let Z := _root_.extend I E Z₀ - have hZ := mdifferentiableAt_extend I E Z₀ x + let Z := _root_.extend E Z₀ + have hZ := mdifferentiableAt_extend I E Z₀ suffices inner ℝ (cov Y x (X x)) (Z x) = inner ℝ (cov' Y x (X x)) (Z x) by simpa [Φ, Z] trans leviCivitaRhs I X Y Z x · rw [← hcov.eq_leviCivitaRhs I hX hY hZ] · rw [← hcov'.eq_leviCivitaRhs I hX hY hZ] -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] - open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : @@ -976,14 +976,14 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : dite_eq_ite, LinearMap.coe_toContinuousLinearMap', IsLinearMap.mk'_apply, LinearMap.mk₂_apply, ContinuousLinearMap.add_apply] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] - · apply leviCivitaRhs_addY_apply _ (mdifferentiable_extend ..) hY hY' - exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · apply leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) hY hY' + exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. leibniz {Y f x} hY hf _ := by unfold lcAux dsimp @@ -1007,23 +1007,21 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : IsLinearMap.mk'_apply, LinearMap.mk₂_apply, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] - · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend I E X₀) (Y := Y) - (Z := _root_.extend I E Z₀) (x := x) (f := f) + · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend E X₀) (Y := Y) + (Z := _root_.extend E Z₀) (x := x) (f := f) convert key hf ?_ hY ?_ · simp · simp [Φ, product] - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. exact MDifferentiableAt.smul_section hf hY end -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] - -- TODO: make g part of the notation! variable (M) in /-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: @@ -1055,17 +1053,17 @@ lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : trans (inner ℝ (((LeviCivitaConnection I M) Y x) (X x)) Z) - (inner ℝ (((LeviCivitaConnection I M) X x) (Y x)) Z) · apply inner_sub_left - have hZ' : _root_.extend I E Z x = Z := extend_apply_self Z + have hZ' : _root_.extend E Z x = Z := extend_apply_self Z rw [← hZ'] - rw [leviCivitaConnection_apply I hY hX (mdifferentiable_extend ..)] - rw [leviCivitaConnection_apply I hX hY (mdifferentiable_extend ..)] + rw [leviCivitaConnection_apply I hY hX (mdifferentiableAt_extend ..)] + rw [leviCivitaConnection_apply I hX hY (mdifferentiableAt_extend ..)] simp only [leviCivitaRhs_apply] -- XXX: should there be leviCivitaRhs'_apply? simp only [leviCivitaRhs', Pi.add_apply, Pi.sub_apply, product_apply] simp only [VectorField.mlieBracket_swap (V := Y) (W := X)] simp only [Pi.neg_apply, inner_neg_right, sub_neg_eq_add] set C := inner ℝ Z (VectorField.mlieBracket I X Y x) - set Z' := _root_.extend I E Z + set Z' := _root_.extend E Z simp only [VectorField.mlieBracket_swap (V := Z') (W := X)] simp only [VectorField.mlieBracket_swap (V := Z') (W := Y)] simp only [Pi.neg_apply, inner_neg_right] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index e107d6457741c6..c7895ad1649c9d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -31,19 +31,19 @@ end section variable - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] - [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] - [FiniteDimensional ℝ E] - [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] - {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} + {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + [FiniteDimensional 𝕜 F] [IsManifold I 1 M] + {cov : (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) noncomputable def IsCovariantDerivativeOn.lift_vec (x : M) (f : F) : - TangentSpace I x →L[ℝ] TangentSpace I x × F := - .prod (.id ℝ _) (-hcov.one_form x f) + TangentSpace I x →L[𝕜] TangentSpace I x × F := + .prod (.id 𝕜 _) (-hcov.one_form x f) @[simp] lemma IsCovariantDerivativeOn.lift_vec_apply (x : M) (f : F) (u : TangentSpace I x) : @@ -52,7 +52,7 @@ lemma IsCovariantDerivativeOn.lift_vec_apply (x : M) (f : F) (u : TangentSpace I @[simp] lemma IsCovariantDerivativeOn.fst_comp_lift_vec (x : M) (f : F) : - .fst ℝ _ _ ∘L hcov.lift_vec x f = .id ℝ _ := by + .fst 𝕜 _ _ ∘L hcov.lift_vec x f = .id 𝕜 _ := by ext u simp @@ -77,20 +77,21 @@ end section variable -{E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] - [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] {V : M → Type*} - [TopologicalSpace (TotalSpace F V)] [(x : M) → AddCommGroup (V x)] [(x : M) → Module ℝ (V x)] - [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] [FiniteDimensional ℝ E] - [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul ℝ (V x)] - [FiniteDimensional ℝ F] [T2Space M] - [IsManifold I ∞ M] [VectorBundle ℝ F V] {cov : CovariantDerivative I F V} + {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {V : M → Type*} + [TopologicalSpace (TotalSpace F V)] [(x : M) → AddCommGroup (V x)] [(x : M) → Module 𝕜 (V x)] + [(x : M) → TopologicalSpace (V x)] [FiberBundle F V] + [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] + [FiniteDimensional 𝕜 F] + [IsManifold I 1 M] [VectorBundle 𝕜 F V] {cov : CovariantDerivative I F V} [ContMDiffVectorBundle 1 F V I] /-- Horizontal lift of a vector tangent to the base at a point in the corresponding fiber. -/ noncomputable def CovariantDerivative.lift_vec (v : TotalSpace F V) : - TangentSpace I v.proj →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, F)) v := + TangentSpace I v.proj →L[𝕜] TangentSpace (I.prod 𝓘(𝕜, F)) v := letI t := trivializationAt F V v.proj have hcov := cov.isCovariantDerivativeOn_pushCovDer t letI tlift := hcov.lift_vec v.proj (t v).2 @@ -129,7 +130,7 @@ lemma CovariantDerivative.lift_vec_horiz {v : TotalSpace F V} (u : TangentSpace Trivialization.symmL_apply, Function.comp_apply] rw [t.deriv_derivInv_apply (FiberBundle.mem_baseSet_trivializationAt' v.proj)] suffices t.symm v.proj 0 = 0 by simpa - exact (t.symmL ℝ v.proj).map_zero + exact (t.symmL 𝕜 v.proj).map_zero @[simp] lemma CovariantDerivative.proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : @@ -139,15 +140,15 @@ lemma CovariantDerivative.proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I @[simp] lemma CovariantDerivative.mfderiv_proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : - mfderiv (I.prod 𝓘(ℝ, F)) I TotalSpace.proj v (cov.lift_vec v u) = u := by + mfderiv (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v (cov.lift_vec v u) = u := by unfold CovariantDerivative.lift_vec simp [FiberBundle.mem_baseSet_trivializationAt' v.proj] lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace I v.proj) - (w : TangentSpace (I.prod 𝓘(ℝ, F)) v) : + (w : TangentSpace (I.prod 𝓘(𝕜, F)) v) : cov.lift_vec v u = w ↔ cov.proj v w = 0 ∧ - mfderiv (I.prod 𝓘(ℝ, F)) I (TotalSpace.proj : TotalSpace F V → M) v w = u := by + mfderiv (I.prod 𝓘(𝕜, F)) I (TotalSpace.proj : TotalSpace F V → M) v w = u := by constructor · rintro rfl simp @@ -164,13 +165,13 @@ lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace · change t.symm v.proj ((hcov.projection v.proj (t v).2) ((t.deriv I v) w)) = 0 at h apply t.injective_symm mem refold_let t - simp [h, t.symm_map_zero ℝ] + simp [h, t.symm_map_zero 𝕜] · rw [← h', t.mfderiv_proj_fst_deriv mem] -- noncomputable -- def CovariantDerivative.lift_vec' -- (p : TotalSpace E ((TotalSpace.proj : (TotalSpace F V → M)) *ᵖ (TangentSpace I))) : --- TangentSpace (I.prod 𝓘(ℝ, F)) p.1 := +-- TangentSpace (I.prod 𝓘(𝕜, F)) p.1 := -- letI t := trivializationAt F V p.1.proj -- haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn -- (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) @@ -179,7 +180,8 @@ lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace end section integralCurve -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] (γ : ℝ → M) (v : (x : M) → TangentSpace I x) (t₀ : ℝ) @@ -227,7 +229,7 @@ lemma IsMIntegralCurveAt.eventually_isMIntegralCurveAt ∀ᶠ t in 𝓝 t₀, IsMIntegralCurveAt γ X t := eventually_eventually_nhds.2 hγX -variable [IsManifold I ∞ M] +variable [IsManifold I 1 M] set_option linter.flexible false in --FIXME lemma IsMIntegralCurveAt.acceleration {X : Π x : M, TangentSpace I x} @@ -254,15 +256,14 @@ end integralCurve section geodesics variable - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] - [ChartedSpace H M] [T2Space M] - [IsManifold I ∞ M] + [ChartedSpace H M] + [IsManifold I 2 M] (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) -- FIXME: bug in `mfderiv%`? -- FIXME: missing elaborator support to find I.tangent -omit [FiniteDimensional ℝ E] [T2Space M] in variable (I) in @[simp] lemma proj_acceleration {γ : ℝ → M} {t : ℝ} (h : MDiffAt (velocity I γ) t) : @@ -279,6 +280,8 @@ I γ t).2 := by rw [comp_eq] at this exact congr($this (1 : ℝ)).symm +variable [FiniteDimensional ℝ E] + lemma IsMIntegralCurveAt.proj_acceleration {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) (hγX : IsMIntegralCurveAt γ X t₀) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 36487db067fde6..7bf9c36a948a18 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -26,21 +26,21 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] - {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} - {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] (n : WithTop ℕ∞) {V : M → Type*} - [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] + {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] (n : WithTop ℕ∞) {V : M → Type*} + [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] -- TODO: where is a good namespace for this? /-- The torsion of a covariant derivative on the tangent bundle `TM` -/ noncomputable def Bundle.torsionFun - (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) : + (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := fun X Y x ↦ cov Y x (X x) - cov X x (Y x) - VectorField.mlieBracket I X Y x variable - {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)} {X X' Y : Π x : M, TangentSpace I x} variable (f X) in @@ -58,7 +58,7 @@ lemma torsionFun_antisymm : torsionFun cov X Y = - torsionFun cov Y X := by namespace IsCovariantDerivativeOn -variable [IsManifold I ∞ M] {U : Set M} +variable [IsManifold I 2 M] {U : Set M} variable (Y) in lemma torsionFun_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) @@ -76,7 +76,7 @@ lemma torsionFun_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivative variable (Y) in lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) - {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : + {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : torsionFun cov (f • X) Y x = f x • torsionFun cov X Y x := by simp only [torsionFun] rw [hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] @@ -88,14 +88,14 @@ lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative set A := f x • (cov X x) (Y x) set B := f x • (cov Y x) (X x) set C := f x • VectorField.mlieBracket I X Y x - set D := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + set D := mfderiv% f x (Y x) change B - (A + (bar _ D) • X x) - (-(bar _ D) • X x + C) = B - A - C module lemma torsionFun_smul_right_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[ℝ] TangentSpace I x} + {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) - {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) (hx : x ∈ U := by trivial) : + {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) (hx : x ∈ U := by trivial) : torsionFun F X (f • Y) x = f x • torsionFun F X Y x := by rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply X hf hX, torsionFun_antisymm X] @@ -103,10 +103,10 @@ lemma torsionFun_smul_right_apply [CompleteSpace E] section -variable [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] +variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : - TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] TangentSpace I x := + TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := mk2TensorAt I E (Bundle.torsionFun cov) (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_left_apply τ hf hσ) (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionFun_add_left_apply τ hσ hσ') @@ -124,7 +124,7 @@ end end IsCovariantDerivativeOn -- /-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ -- noncomputable def IsTorsionFreeOn --- (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) +-- (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) -- (U : Set M) : Prop := -- ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsionFun cov X Y x = 0 -- @@ -151,7 +151,8 @@ end IsCovariantDerivativeOn namespace CovariantDerivative open VectorField -variable [IsManifold I ∞ M] [FiniteDimensional ℝ E] [T2Space M] +variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] +variable [IsManifold I 2 M] variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- The torsion tensor of a covariant derivative on the tangent bundle of a manifold. -/ @@ -164,9 +165,9 @@ lemma torsion_vector_field_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) exacts [hX, hY] lemma torsion_apply (u v : TangentSpace I x) : - cov.torsion x u v = cov (extend I E v) x (extend I E u x) - - cov (extend I E u) x (extend I E v x) - - mlieBracket I (extend I E u) (extend I E v) x := by + cov.torsion x u v = cov (extend E v) x (extend E u x) + - cov (extend E u) x (extend E v x) + - mlieBracket I (extend E u) (extend E v) x := by unfold torsion IsCovariantDerivativeOn.torsion apply mk2TensorAt_apply_eq_extend diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index 7c9c2d1a4328f9..c0d7ec0078c5f6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -125,18 +125,18 @@ noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : end CovariantDerivative -section real +section variable {E : Type*} [NormedAddCommGroup E] - [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} + [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `F` model fiber (n : WithTop ℕ∞) {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] -- `V` vector bundle @@ -145,40 +145,40 @@ namespace IsCovariantDerivativeOn -- The classification of real connections over a trivial bundle section classification -variable [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] [T2Space M] [IsManifold I ∞ M] +variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [IsManifold I 1 M] /-- Classification of covariant derivatives over a trivial vector bundle: every connection is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term -/ -lemma exists_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} +lemma exists_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : - ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), + ∃ (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F), ∀ σ : M → F, ∀ x ∈ s, MDiffAt (T% σ) x → - letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) σ x cov σ x = d + A x (σ x) := by use hcov.difference (trivial I M F |>.mono <| subset_univ s) intro σ x hx hσ rw [hcov.difference_apply _ (by trivial) hσ] module -noncomputable def one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} +noncomputable def one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : - Π x : M, F →L[ℝ] TangentSpace I x →L[ℝ] F := + Π x : M, F →L[𝕜] TangentSpace I x →L[𝕜] F := hcov.exists_one_form.choose -lemma eq_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[ℝ] F)} +lemma eq_one_form {cov : (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {σ : M → F} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) σ x cov σ x = d + hcov.one_form x (σ x) := hcov.exists_one_form.choose_spec σ x hx hσ lemma _root_.CovariantDerivative.exists_one_form (cov : CovariantDerivative I F (Bundle.Trivial M F)) : - ∃ (A : (x : M) → F →L[ℝ] TangentSpace I x →L[ℝ] F), + ∃ (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F), ∀ σ : M → F, ∀ x, MDiffAt (T% σ) x → - letI d : TangentSpace I x →L[ℝ] F := mfderiv I 𝓘(ℝ, F) σ x + letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) σ x cov σ x = d + A x (σ x) := by simpa using cov.isCovariantDerivativeOn.exists_one_form diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean index 79047fd29836eb..60e1520b13d520 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -5,13 +5,15 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.BumpFunction public import Mathlib.Geometry.Manifold.VectorBundle.Basic -public import Mathlib.Geometry.Manifold.MFDeriv.Defs -import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +public import Mathlib.Geometry.Manifold.MFDeriv.Basic +import Mathlib.Geometry.Manifold.Notation /-! -# Extending an element of a vector bundle to a smooth section +# Locally extending an element of a vector bundle to a smooth section + +Unlike the other `extend`, this construction doesn't use bump functions, just extends naively on a +trivialization's domain. -/ @@ -21,95 +23,66 @@ open Bundle Filter Module Topology Set open scoped Manifold ContDiff section extend -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] +variable (F : Type*) [NormedAddCommGroup F] -- `F` model fiber - (n : WithTop ℕ∞) {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x, AddCommGroup (V x)] [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] + [FiberBundle F V] -- `V` vector bundle --- TODO: either change `localFrame` to make sure it is everywhere smooth --- or introduce a cut-off here. First option is probaly better. --- TODO: comment why we chose the second option in the end, and adapt the definition accordingly --- new definition: smooth a bump function, then smul with localExtensionOn +open Classical in /-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. The details of the extension are mostly unspecified: for covariant derivatives, the value of `s` at points other than `x` will not matter (except for shorter proofs). -Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. -/ -noncomputable def extend [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : +noncomputable def extend {x : M} (v₀ : V x) : (x' : M) → V x' := - letI b := Basis.ofVectorSpace ℝ F letI t := trivializationAt F V x - -- Choose a smooth bump function ψ near `x`, supported within t.baseSet - -- and return ψ • V₀ instead. - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - ψ.toFun • localExtensionOn b t v + let w : F := (t ⟨x, v₀⟩).2 + fun x' ↦ t.symm x' w variable {I F} --- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for --- *well-chosen* extensions (such as ours). --- so, one may argue this is mathematically wrong, but it encodes the "choice some extension --- with this and that property" nicely --- a different proof would be to argue only the value at a point matters for cov -@[simp] -lemma extend_add [FiniteDimensional ℝ F] [T2Space M] {x : M} (v v' : V x) : - extend I F (v + v') = extend I F v + extend I F v' := by - simp [extend] - -@[simp] -lemma extend_smul [FiniteDimensional ℝ F] [T2Space M] {a : ℝ} {x : M} (v : V x) : - extend I F (a • v) = a • extend I F v := by simp [extend]; module - -@[simp] -lemma extend_zero [FiniteDimensional ℝ F] [T2Space M] (x : M) : - extend I F (0 : V x) = 0 := by simp [extend] - -@[simp] lemma extend_apply_self [FiniteDimensional ℝ F] [T2Space M] {x : M} (v : V x) : - extend I F v x = v := by - simpa [extend] using - localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v +@[simp] lemma extend_apply_self {x : M} (v : V x) : + extend F v x = v := by + unfold extend + rw [Trivialization.symm_apply_apply_mk] + exact FiberBundle.mem_baseSet_trivializationAt' x variable (I F) -lemma contMDiff_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - CMDiff ∞ (T% (extend I F σ₀)) := by - letI t := trivializationAt F V x - letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) - have hx : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x - let ψ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - let hψ := - Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht - exact ContMDiffOn.smul_section_of_tsupport ψ.contMDiff.contMDiffOn t.open_baseSet hψ.1 - (contMDiffOn_localExtensionOn _ hx _) - --- TODO weaken regularity condition on `IsManifold` and `ContMDiffVectorBundle` hypotheses -lemma mdifferentiable_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) : - MDiff (T% (extend I F σ₀)) := - contMDiff_extend I F σ₀ |>.mdifferentiable (by simp) - -lemma mdifferentiableAt_extend [IsManifold I ∞ M] [FiniteDimensional ℝ F] [T2Space M] - [ContMDiffVectorBundle ∞ F V I] {x : M} (σ₀ : V x) (x' : M) : - MDiffAt (T% (extend I F σ₀)) x' := - mdifferentiable_extend I F σ₀ |>.mdifferentiableAt - -theorem contDiff_extend - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [FiniteDimensional ℝ E'] - (x : E) (y : E') : ContDiff ℝ ∞ (extend 𝓘(ℝ, E) E' y (x := x)) := by - rw [contDiff_iff_contDiffAt] - intro x' - rw [← contMDiffAt_iff_contDiffAt] - simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' +variable [NormedSpace 𝕜 F] + +-- TODO there is a lemma already with this name which should be renamed to something like +-- `Chart.contMDiffAt_extend` +lemma contMDiffAt_extend' {k} [IsManifold I k M] {x : M} (σ₀ : V x) : + CMDiffAt k (T% (extend F σ₀)) x := by + rw [contMDiffAt_section] + set t := trivializationAt F V x + let w : F := (t ⟨x, σ₀⟩).2 + have : ContMDiffAt I 𝓘(𝕜, F) k (fun x_1 ↦ w) x := contMDiffAt_const + refine this.congr_of_eventuallyEq ?_ + apply eventually_nhds_iff.mpr + refine ⟨t.baseSet, ?_, t.open_baseSet, ?_⟩ + · intro x hx + dsimp only + unfold extend + rw [t.mk_symm hx, t.apply_symm_apply' hx] + · exact FiberBundle.mem_baseSet_trivializationAt' x + +lemma mdifferentiableAt_extend [IsManifold I 1 M] {x : M} (σ₀ : V x) : + MDiffAt (T% (extend F σ₀)) x := + have := contMDiffAt_extend' (k := 1) I F σ₀ + this.mdifferentiableAt one_ne_zero + +-- TODO also prove `ContMDiffOn` and `MDifferentiableOn` in a neighbourhood of the point end extend diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 37c8eb4f8134f0..d20cc1146803fb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -21,46 +21,56 @@ open scoped Bundle Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [T2Space M] [IsManifold I ∞ M] +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] variable -- `F` model fiber - (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiniteDimensional 𝕜 F] -- `V` vector bundle (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] [VectorBundle ℝ F V] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] -variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace ℝ F'] [FiniteDimensional ℝ F] +variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] (V' : M → Type*) - [∀ x, AddCommGroup (V' x)] [∀ x, Module ℝ (V' x)] + [∀ x, AddCommGroup (V' x)] [∀ x, Module 𝕜 (V' x)] lemma tensoriality_criterion {φ : (Π x : M, V x) → (Π x, V' x)} {x} {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by have locality {σ σ'} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : φ σ x = φ σ' x := by - obtain ⟨ψ, _, hψ⟩ := (SmoothBumpFunction.nhds_basis_support (I := I) hσσ').mem_iff.1 hσσ' - have (x : M) : ((ψ : M → ℝ) • σ) x = ((ψ : M → ℝ) • σ') x := by - by_cases h : σ x = σ' x - · rw [Pi.smul_apply', Pi.smul_apply', h] - · simp [notMem_support.mp fun a ↦ h (hψ a)] - have hψ' : MDifferentiableAt I 𝓘(ℝ) ψ x := - ψ.contMDiffAt.mdifferentiableAt (by simp) + classical + rw [eventually_nhds_iff] at hσσ' + obtain ⟨t, htσσ', ht, hxt⟩ := hσσ' + let ψ (x' : M) : 𝕜 := if x' ∈ t then 1 else 0 + have hψx : ψ x = 1 := by simp [ψ, hxt] + have (x' : M) : ((ψ : M → 𝕜) • σ) x' = ((ψ : M → 𝕜) • σ') x' := by + dsimp [ψ] + split_ifs with hx't + · simpa using htσσ' _ hx't + · simp + have hψ' : MDifferentiableAt I 𝓘(𝕜) ψ x := by + have : MDifferentiableAt I 𝓘(𝕜, 𝕜) (fun x_1 ↦ (1:𝕜)) x := mdifferentiableAt_const + refine this.congr_of_eventuallyEq ?_ + apply eventually_nhds_iff.mpr + exact ⟨t, by simp [ψ], ht, hxt⟩ calc φ σ x - _ = φ ((ψ : M → ℝ) • σ) x := by simp [φ_smul _ _ hψ' hσ] - _ = φ ((ψ : M → ℝ) • σ') x := by rw [funext this] - _ = φ σ' x := by simp [φ_smul _ _ hψ' hσ'] - let ι : Type _ := Basis.ofVectorSpaceIndex ℝ F + _ = φ ((ψ : M → 𝕜) • σ) x := by simp [φ_smul _ _ hψ' hσ, hψx] + _ = φ ((ψ : M → 𝕜) • σ') x := by rw [funext this] + _ = φ σ' x := by simp [φ_smul _ _ hψ' hσ', hψx] + let ι : Type _ := Basis.ofVectorSpaceIndex 𝕜 F classical have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) (hσ : ∀ i, MDiffAt (T% (σ i)) x): @@ -68,8 +78,8 @@ lemma tensoriality_criterion induction s using Finset.induction_on with | empty => simp only [Finset.sum_empty] - have h₁ : MDiffAt (fun x' : M ↦ (0 : ℝ)) x := mdifferentiableAt_const - rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → ℝ) • fun x' ↦ 0 by simp;rfl] + have h₁ : MDiffAt (fun x' : M ↦ (0 : 𝕜)) x := mdifferentiableAt_const + rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → 𝕜) • fun x' ↦ 0 by simp;rfl] rw [φ_smul] · simp · exact h₁ @@ -80,7 +90,7 @@ lemma tensoriality_criterion simp only [Finset.sum_insert ha, ← h] exact φ_add _ _ (hσ a) (.sum_section hσ) have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) - let b := Basis.ofVectorSpace ℝ F + let b := Basis.ofVectorSpace 𝕜 F let t := trivializationAt F V x let s := t.localFrame b let c := t.localFrame_coeff I b @@ -114,11 +124,11 @@ lemma tensoriality_criterion₂ (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by @@ -134,195 +144,194 @@ lemma tensoriality_criterion₂ section tensoriality +variable [IsManifold I 1 M] + variable {V} -- TODO can probably remove the next two hypotheses, by transport - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] - -- TODO needed until `mdifferentiable_extend` is fixed to require the correct regularity - -- hypotheses - [ContMDiffVectorBundle ∞ F V I] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] variable {V'} -- TODO can probably remove the next three hypotheses, by transport [∀ x : M, TopologicalSpace (V' x)] [∀ x, IsTopologicalAddGroup (V' x)] - [∀ x, ContinuousSMul ℝ (V' x)] + [∀ x, ContinuousSMul 𝕜 (V' x)] [TopologicalSpace (TotalSpace F' V')] - [FiberBundle F' V'] [VectorBundle ℝ F' V'] + [FiberBundle F' V'] [VectorBundle 𝕜 F' V'] noncomputable def mkTensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x, V' x)) (x) - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) : - V x →L[ℝ] V' x := - let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x + V x →L[𝕜] V' x := + let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x (FiberBundle.mem_baseSet_trivializationAt' x) have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional LinearMap.toContinuousLinearMap { - toFun v := φ (_root_.extend I F v) x + toFun v := φ (_root_.extend F v) x map_add' v₁ v₂ := by rw [← φ_add] · apply tensoriality_criterion I F _ _ _ _ _ φ_smul φ_add - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · apply mdifferentiableAt_add_section - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · simp - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. map_smul' c v := by dsimp rw [← φ_smul (fun _ ↦ c)] · apply tensoriality_criterion I F _ _ _ _ _ φ_smul φ_add - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · apply MDifferentiableAt.smul_section · exact mdifferentiableAt_const - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · simp · exact mdifferentiable_const .. - · exact mdifferentiable_extend .. } + · exact mdifferentiableAt_extend .. } variable {I} in theorem mkTensorAt_apply -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x, V' x)} {x} - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : mkTensorAt I F φ x φ_smul φ_add (σ x) = φ σ x := by apply tensoriality_criterion I F _ _ _ hσ _ φ_smul φ_add - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · simp variable {I} in theorem mkTensorAt_apply_eq_extend -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x, V' x)} {x} - (φ_smul : ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → + (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) (σ : V x) : - mkTensorAt I F φ x φ_smul φ_add σ = φ (_root_.extend I F σ) x := + mkTensorAt I F φ x φ_smul φ_add σ = φ (_root_.extend F σ) x := rfl noncomputable def mkTensor -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x, V' x)) -- TODO could weaken `φ_smul` and `φ_add` to require the property only globally, is it useful? - (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) + (φ_smul : ∀ x, ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) (x : M) : - V x →L[ℝ] V' x := + V x →L[𝕜] V' x := mkTensorAt I F φ x (φ_smul x) (φ_add x) theorem contMDiff_mkTensor (φ : (Π x : M, V x) → (Π x, V' x)) - (φ_smul : ∀ x, ∀ f : M → ℝ, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) + (φ_smul : ∀ x, ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) -- hopefully this is the correct smoothness criterion! {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : -- elaborators not working here - let T (x : M) : TotalSpace (F →L[ℝ] F') (fun x ↦ V x →L[ℝ] V' x) := + let T (x : M) : TotalSpace (F →L[𝕜] F') (fun x ↦ V x →L[𝕜] V' x) := ⟨x, mkTensor I F φ φ_smul φ_add x⟩ - ContMDiff I (I.prod 𝓘(ℝ, F →L[ℝ] F')) k T := by + ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] F')) k T := by sorry -- TODO allow the two input types to differ noncomputable def mk2TensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : - V x →L[ℝ] V x →L[ℝ] V' x := - let Ψ : V x ≃L[ℝ] F := (trivializationAt F V x).continuousLinearEquivAt ℝ x + V x →L[𝕜] V x →L[𝕜] V' x := + let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x (FiberBundle.mem_baseSet_trivializationAt' x) have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional ℝ (V x) := Ψ.symm.toLinearEquiv.finiteDimensional - have H : IsBilinearMap ℝ - (fun (v w : V x) ↦ φ (_root_.extend I F v) (_root_.extend I F w) x) := + have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + have H : IsBilinearMap 𝕜 + (fun (v w : V x) ↦ φ (_root_.extend F v) (_root_.extend F w) x) := { add_left v₁ v₂ w := by rw [← σ_add] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · apply mdifferentiableAt_add_section - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · simp - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. smul_left c v w := by rw [← σ_smul (f := fun _ ↦ c)] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · apply MDifferentiableAt.smul_section · exact mdifferentiableAt_const - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · simp · exact mdifferentiable_const .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. add_right v w₁ w₂ := by rw [← τ_add] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · apply mdifferentiableAt_add_section - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · simp - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. smul_right c v w := by rw [← τ_smul (f := fun _ ↦ c)] · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · apply MDifferentiableAt.smul_section · exact mdifferentiableAt_const - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. · simp · exact mdifferentiable_const .. - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. } + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. } H.toContinuousLinearMap variable {I} in theorem mk2TensorAt_apply -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by apply tensoriality_criterion₂ I F _ _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiable_extend .. - · exact mdifferentiable_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · simp · simp @@ -330,35 +339,35 @@ variable {I} in theorem mk2TensorAt_apply_eq_extend -- `φ` explicit to make it easier to generate the side conditions at point of use {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - (σ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → ℝ, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (σ τ : V x) : mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add σ τ - = φ (_root_.extend I F σ) (_root_.extend I F τ) x := + = φ (_root_.extend F σ) (_root_.extend F τ) x := rfl theorem mk2TensorAt_add (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} - (φ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (φ_σ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (φ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (φ_τ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ σ (f • τ) x = f x • φ σ τ x) (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) - (ψ_σ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (ψ_σ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → ψ (f • σ) τ x = f x • ψ σ τ x) (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) - (ψ_τ_smul : ∀ (f : M → ℝ), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + (ψ_τ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → ψ σ (f • τ) x = f x • ψ σ τ x) (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : From cf9632ccac05a45bf00a25f10df40c04325554f5 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Thu, 5 Mar 2026 20:57:22 +0000 Subject: [PATCH 508/601] use lemma mk2TensorAt_apply_eq_extend --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 31c8788f00d939..735e19459bd07e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -972,9 +972,7 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : congr! 1 simp only [lcAux₀] ext X₀ Y₀ - simp only [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap, - dite_eq_ite, LinearMap.coe_toContinuousLinearMap', IsLinearMap.mk'_apply, LinearMap.mk₂_apply, - ContinuousLinearMap.add_apply] + simp only [mk2TensorAt_apply_eq_extend, dite_eq_ite, ContinuousLinearMap.add_apply] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] · apply leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) hY hY' exact mdifferentiableAt_extend .. @@ -1002,9 +1000,7 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.toSpanSingleton_apply, map_add, map_smul] ext Z₀ - simp only [lcAux₀, mk2TensorAt, IsBilinearMap.toContinuousLinearMap, - IsBilinearMap.toLinearMap, dite_eq_ite, LinearMap.coe_toContinuousLinearMap', - IsLinearMap.mk'_apply, LinearMap.mk₂_apply, ContinuousLinearMap.add_apply, + simp only [lcAux₀, mk2TensorAt_apply_eq_extend, dite_eq_ite, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend E X₀) (Y := Y) From 44aa8ed287021f25f023651859e426163ec23d17 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Thu, 5 Mar 2026 21:35:57 +0000 Subject: [PATCH 509/601] generalize mk2Tensor to different input types --- .../CovariantDerivative/LeviCivita.lean | 8 +- .../CovariantDerivative/Torsion.lean | 4 +- .../Manifold/VectorBundle/Tensoriality.lean | 105 ++++++++++-------- 3 files changed, 65 insertions(+), 52 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 735e19459bd07e..4905d9c154c362 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -316,7 +316,7 @@ variable {I} in /-- The tensor `∇ g` defined by a connection `∇` on a Riemannian manifold `(M, g)`. -/ @[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - mk2TensorAt I E (myfun I cov) + mk2TensorAt I E E (myfun I cov) (fun _f _σ _τ hf hσ hτ ↦ aux1 cov hf hσ hτ) (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) @@ -329,7 +329,7 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) MetricTensor cov x (Y x) (Z x) (X x) = bar _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by unfold MetricTensor - rw [mk2TensorAt_apply _ _ _ _ _ hY hZ] + rw [mk2TensorAt_apply _ _ _ _ _ _ hY hZ] simp only [myfun, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] conv => @@ -891,7 +891,7 @@ open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] ℝ := - mk2TensorAt I E (fun (X Z : Π x : M, TangentSpace I x) ↦ + mk2TensorAt I E E (fun (X Z : Π x : M, TangentSpace I x) ↦ if hX : MDiffAt (T% X) x then if hZ : MDiffAt (T% Z) x then leviCivitaRhs I X Y Z else 0 else 0) (x := x) @@ -927,7 +927,7 @@ theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : lcAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by unfold lcAux₀ - rw [mk2TensorAt_apply _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] + rw [mk2TensorAt_apply _ _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] noncomputable def lcAux₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 7bf9c36a948a18..bb8747de4a4be6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -107,7 +107,7 @@ variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := - mk2TensorAt I E (Bundle.torsionFun cov) + mk2TensorAt I E E (Bundle.torsionFun cov) (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_left_apply τ hf hσ) (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionFun_add_left_apply τ hσ hσ') (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_right_apply hf hτ) @@ -117,7 +117,7 @@ theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : torsion hcov x (X x) (Y x) = Bundle.torsionFun cov X Y x := - mk2TensorAt_apply _ _ _ _ _ hX hY + mk2TensorAt_apply _ _ _ _ _ _ hX hY end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index d20cc1146803fb..cd3aa9bf0a5a8b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -36,13 +36,18 @@ variable [FiberBundle F V] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] +variable + (F' : Type*) [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] [FiniteDimensional 𝕜 F'] + (V' : M → Type*) [TopologicalSpace (TotalSpace F' V')] + [∀ x, AddCommGroup (V' x)] [∀ x, Module 𝕜 (V' x)] [∀ x : M, TopologicalSpace (V' x)] + [FiberBundle F' V'] [VectorBundle 𝕜 F' V'] + [ContMDiffVectorBundle 1 F' V' I] -variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] - (V' : M → Type*) - [∀ x, AddCommGroup (V' x)] [∀ x, Module 𝕜 (V' x)] +variable (G : Type*) [NormedAddCommGroup G] [NormedSpace 𝕜 G] + (W : M → Type*) [∀ x, AddCommGroup (W x)] [∀ x, Module 𝕜 (W x)] lemma tensoriality_criterion - {φ : (Π x : M, V x) → (Π x, V' x)} {x} + {φ : (Π x : M, V x) → (Π x, W x)} {x} {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : σ x = σ' x) (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → @@ -118,8 +123,9 @@ lemma tensoriality_criterion include I in lemma tensoriality_criterion₂ - {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} - {σ σ' τ τ' : Π x : M, V x} + {φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)} {x} + {σ σ' : Π x : M, V x} + {τ τ' : Π x : M, V' x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) (hσσ' : σ x = σ' x) @@ -133,13 +139,13 @@ lemma tensoriality_criterion₂ (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by trans φ σ' τ x - · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ X τ + · let φ1 : (Π x : M, V x) → (Π x, W x) := fun X ↦ φ X τ change φ1 σ x = φ1 σ' x - apply tensoriality_criterion I F V V' hσ hσ' hσσ' + apply tensoriality_criterion I F V W hσ hσ' hσσ' exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ hτ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ' hτ] - · let φ1 : (Π x : M, V x) → (Π x, V' x) := fun X ↦ φ σ' X + · let φ1 : (Π x : M, V' x) → (Π x, W x) := fun X ↦ φ σ' X change φ1 τ x = φ1 τ' x - apply tensoriality_criterion I F V V' hτ hτ' hττ' + apply tensoriality_criterion I F' V' W hτ hτ' hττ' exacts [fun f τ hf hτ ↦ τ_smul _ hf hσ' hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hσ' hτ hτ'] section tensoriality @@ -153,21 +159,26 @@ variable variable {V'} + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] + +variable + {W} -- TODO can probably remove the next three hypotheses, by transport - [∀ x : M, TopologicalSpace (V' x)] - [∀ x, IsTopologicalAddGroup (V' x)] - [∀ x, ContinuousSMul 𝕜 (V' x)] - [TopologicalSpace (TotalSpace F' V')] - [FiberBundle F' V'] [VectorBundle 𝕜 F' V'] + [∀ x : M, TopologicalSpace (W x)] + [∀ x, IsTopologicalAddGroup (W x)] + [∀ x, ContinuousSMul 𝕜 (W x)] + [TopologicalSpace (TotalSpace G W)] + [FiberBundle G W] [VectorBundle 𝕜 G W] noncomputable def mkTensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x, V' x)) (x) + (φ : (Π x : M, V x) → (Π x, W x)) (x) (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) : - V x →L[𝕜] V' x := + V x →L[𝕜] W x := let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x (FiberBundle.mem_baseSet_trivializationAt' x) have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space @@ -199,7 +210,7 @@ noncomputable def mkTensorAt variable {I} in theorem mkTensorAt_apply -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x, V' x)} {x} + {φ : (Π x : M, V x) → (Π x, W x)} {x} (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → @@ -212,7 +223,7 @@ theorem mkTensorAt_apply variable {I} in theorem mkTensorAt_apply_eq_extend -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x, V' x)} {x} + {φ : (Π x : M, V x) → (Π x, W x)} {x} (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → @@ -222,30 +233,28 @@ theorem mkTensorAt_apply_eq_extend noncomputable def mkTensor -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x, V' x)) - -- TODO could weaken `φ_smul` and `φ_add` to require the property only globally, is it useful? + (φ : (Π x : M, V x) → (Π x, W x)) (φ_smul : ∀ x, ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) (x : M) : - V x →L[𝕜] V' x := + V x →L[𝕜] W x := mkTensorAt I F φ x (φ_smul x) (φ_add x) theorem contMDiff_mkTensor - (φ : (Π x : M, V x) → (Π x, V' x)) + (φ : (Π x : M, V x) → (Π x, W x)) (φ_smul : ∀ x, ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) -- hopefully this is the correct smoothness criterion! {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : -- elaborators not working here - let T (x : M) : TotalSpace (F →L[𝕜] F') (fun x ↦ V x →L[𝕜] V' x) := + let T (x : M) : TotalSpace (F →L[𝕜] G) (fun x ↦ V x →L[𝕜] W x) := ⟨x, mkTensor I F φ φ_smul φ_add x⟩ - ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] F')) k T := by + ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] G)) k T := by sorry --- TODO allow the two input types to differ noncomputable def mk2TensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} + (φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)) {x} (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → @@ -254,16 +263,20 @@ noncomputable def mk2TensorAt φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : - V x →L[𝕜] V x →L[𝕜] V' x := + V x →L[𝕜] V' x →L[𝕜] W x := let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x (FiberBundle.mem_baseSet_trivializationAt' x) have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + let Ψ' : V' x ≃L[𝕜] F' := (trivializationAt F' V' x).continuousLinearEquivAt 𝕜 x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V' x) := Ψ'.symm.toHomeomorph.t2Space + have : FiniteDimensional 𝕜 (V' x) := Ψ'.symm.toLinearEquiv.finiteDimensional have H : IsBilinearMap 𝕜 - (fun (v w : V x) ↦ φ (_root_.extend F v) (_root_.extend F w) x) := + (fun (v : V x) (w : V' x) ↦ φ (_root_.extend F v) (_root_.extend F' w) x) := { add_left v₁ v₂ w := by rw [← σ_add] - · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add · exact mdifferentiableAt_extend .. · apply mdifferentiableAt_add_section · exact mdifferentiableAt_extend .. @@ -276,7 +289,7 @@ noncomputable def mk2TensorAt · exact mdifferentiableAt_extend .. smul_left c v w := by rw [← σ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add · exact mdifferentiableAt_extend .. · apply MDifferentiableAt.smul_section · exact mdifferentiableAt_const @@ -289,7 +302,7 @@ noncomputable def mk2TensorAt · exact mdifferentiableAt_extend .. add_right v w₁ w₂ := by rw [← τ_add] - · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. @@ -302,7 +315,7 @@ noncomputable def mk2TensorAt · exact mdifferentiableAt_extend .. smul_right c v w := by rw [← τ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. @@ -318,7 +331,7 @@ noncomputable def mk2TensorAt variable {I} in theorem mk2TensorAt_apply -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + {φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)} {x} (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → @@ -327,9 +340,9 @@ theorem mk2TensorAt_apply φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) - {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V x} (hτ : MDiffAt (T% τ) x) : - mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by - apply tensoriality_criterion₂ I F _ _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : + mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by + apply tensoriality_criterion₂ I F _ F' _ _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · simp @@ -338,7 +351,7 @@ theorem mk2TensorAt_apply variable {I} in theorem mk2TensorAt_apply_eq_extend -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)} {x} + {φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)} {x} (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → @@ -347,13 +360,13 @@ theorem mk2TensorAt_apply_eq_extend φ σ (f • τ) x = f x • φ σ τ x) (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) - (σ τ : V x) : - mk2TensorAt I F φ σ_smul σ_add τ_smul τ_add σ τ - = φ (_root_.extend F σ) (_root_.extend F τ) x := + (σ : V x) (τ : V' x) : + mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add σ τ + = φ (_root_.extend F σ) (_root_.extend F' τ) x := rfl theorem mk2TensorAt_add - (φ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) {x} + (φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)) {x} (φ_σ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → φ (f • σ) τ x = f x • φ σ τ x) (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → @@ -362,7 +375,7 @@ theorem mk2TensorAt_add φ σ (f • τ) x = f x • φ σ τ x) (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) - (ψ : (Π x : M, V x) → (Π x : M, V x) → (Π x, V' x)) + (ψ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)) (ψ_σ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → ψ (f • σ) τ x = f x • ψ σ τ x) (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → @@ -371,7 +384,7 @@ theorem mk2TensorAt_add ψ σ (f • τ) x = f x • ψ σ τ x) (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : - mk2TensorAt I F (φ + ψ) + mk2TensorAt I F F' (φ + ψ) (fun {_ _ τ} hf hσ hτ ↦ (congr($(φ_σ_smul _ hf hσ hτ) + $(ψ_σ_smul _ hf hσ hτ))).trans (smul_add _ _ _).symm) @@ -386,8 +399,8 @@ theorem mk2TensorAt_add (congr($(φ_τ_add _ _ _ hσ hτ₁ hτ₂) + $(ψ_τ_add _ _ _ hσ hτ₁ hτ₂))).trans <| by dsimp abel) - = mk2TensorAt I F φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add - + mk2TensorAt I F ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by + = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add + + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by ext simp [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap] From 3e88f008439bd3ee68e3a4b051a2e277308e8189 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 18:04:39 +0000 Subject: [PATCH 510/601] Three people walk into a bar. Ouch! chore: rename bar to NormedSpace.fromTangentSpace and generalise to normed spaces. While at it, also use mfderiv% slightly more. --- Mathlib.lean | 1 - .../Geometry/Manifold/IsManifold/Basic.lean | 10 +++++ .../CovariantDerivative/Basic.lean | 9 +++-- .../CovariantDerivative/Ehresmann.lean | 4 +- .../CovariantDerivative/LeviCivita.lean | 34 ++++++++-------- .../CovariantDerivative/Torsion.lean | 4 +- .../Geometry/Manifold/VectorBundle/Misc.lean | 39 ------------------- .../Manifold/VectorBundle/Tensoriality.lean | 1 - 8 files changed, 37 insertions(+), 65 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Misc.lean diff --git a/Mathlib.lean b/Mathlib.lean index 54eb20b9ac42c7..b8a5db09b57980 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4432,7 +4432,6 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.IsBilinearPrelim public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame public import Mathlib.Geometry.Manifold.VectorBundle.Pullback public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian diff --git a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean index ac045c3fe72876..b27fd1c76a3ce7 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/Basic.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/Basic.lean @@ -1061,6 +1061,16 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} +set_option backward.isDefEq.respectTransparency false in +/-- Identifying the tangent space at a normed space with the normed space itself. +This canonical identification (which, in mathlib, is implemented using an abuse of definitional +equality) is very prevalent in a number of places: this device allows making it explicit. -/ +def NormedSpace.fromTangentSpace (v : E) : TangentSpace 𝓘(𝕜, E) v ≃L[𝕜] E where + toFun v := v + invFun v := v + map_add' := by simp + map_smul' := by simp + instance : Inhabited (TangentSpace I x) := ⟨0⟩ variable (M) in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index f32acf5d5bfeb8..fe5b6ab21a9580 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -17,7 +17,7 @@ TODO: add a more complete doc-string -/ -open Bundle Filter Module Topology Set +open Bundle Filter Module Topology Set NormedSpace open scoped Bundle Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @@ -53,7 +53,8 @@ structure IsCovariantDerivativeOn [IsManifold I 1 M] (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): f (g • σ) x = g x • f σ x + .toSpanSingleton 𝕜 (σ x) ∘L - (((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜) g x))) + (((fromTangentSpace (g x)).toContinuousLinearMap ∘L (mfderiv% g x))) + /-- A covariant derivative ∇ is called of class `C^k` iff, @@ -88,7 +89,7 @@ lemma of_subsingleton [hE : Subsingleton E] [TopologicalSpace (TotalSpace E V)] exact { addσ {σ σ' x} hσ hσ' hx := by simp [this] leibniz {σ g x} hσ hg hx := by - have H : (mfderiv I 𝓘(𝕜, 𝕜) g x) = 0 := + have H : (mfderiv% g x) = 0 := have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) Subsingleton.eq_zero _ simp [this, H] } @@ -192,7 +193,7 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] rw [← smul_add, (h i).addσ hσ hσ' hx] leibniz {σ g x} hσ hg hx := by set B := (ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L - ((bar (g x)).toContinuousLinearMap ∘L (mfderiv I 𝓘(𝕜, 𝕜) g x))) + ((fromTangentSpace (g x)).toContinuousLinearMap ∘L (mfderiv% g x))) calc ∑ i ∈ s, f i x • cov i (g • σ) x _ = ∑ i ∈ s, (g x • f i x • cov i σ x + f i x • B) := by congr! 1 with i hi diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 0c0fa0bae1eba7..eddccfe99aeffd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -7,7 +7,9 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.Notation -public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial /-! diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 4905d9c154c362..a6eeffabb289da 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -24,7 +24,7 @@ is an isometry) and prove the Levi-Civita connection is a metric connection -/ -open Bundle Filter Function Module Topology +open Bundle Filter Function Module NormedSpace Topology open scoped Bundle Manifold ContDiff @@ -213,7 +213,7 @@ private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, inner_smul_right, mfderiv_smul (hσ.inner_bundle' hτ) hf] - simp only [smul_eq_mul, Pi.mul_apply, bar, ContinuousLinearEquiv.coe_coe, + simp only [smul_eq_mul, Pi.mul_apply, fromTangentSpace, ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] conv => enter [1, 1, 1, 2, 2] @@ -273,8 +273,8 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] --set C := (mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) X --set D := (mfderiv I 𝓘(ℝ, ℝ) f x) X - simp only [smul_eq_mul, bar, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, - AddHom.coe_mk, inner_smul_right] + simp only [smul_eq_mul, fromTangentSpace, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, + LinearMap.coe_mk, AddHom.coe_mk, inner_smul_right] -- would be nice to finish by a tactic now! erw [mul_add, mul_add] rw [Pi.mul_apply, mul_neg, mul_neg, @@ -327,7 +327,7 @@ variable {I} in theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : MetricTensor cov x (Y x) (Z x) (X x) = - bar _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by + fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by unfold MetricTensor rw [mk2TensorAt_apply _ _ _ _ _ _ hY hZ] simp only [myfun, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, @@ -338,7 +338,7 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) conv => enter [1, 1, 2] erw [ContinuousLinearMap.comp_apply] - simp [product, real_inner_comm, bar] + simp [product, real_inner_comm, fromTangentSpace] /-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have @@ -356,7 +356,7 @@ lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x rw [IsCompatible] at hcov have : MetricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] rw [metricTensor_apply cov x hY hZ] at this - change (bar _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ + change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ exact isCompatible_apply_aux this lemma isCompatible_iff [FiniteDimensional ℝ E] : @@ -687,25 +687,25 @@ lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs' I X (f • Y) Z x = - f x • leviCivitaRhs' I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by + f x • leviCivitaRhs' I X Y Z x + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by simp only [leviCivitaRhs'] simp_rw [rhs_aux_smulX I Y Z X f] simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] rw [rhs_aux_smulY_apply I X hf hY hZ, rhs_aux_smulZ_apply I Z hf hX hY] -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? have h1 : ⟪Z, mlieBracket I (f • Y) X⟫ x = - - (bar _).toFun (((mfderiv% f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by + - (fromTangentSpace _).toFun (((mfderiv% f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] congr - · simp only [neg_smul, inner_neg_right, bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul, + · simp only [neg_smul, inner_neg_right, fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul, neg_mul, neg_inj] rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = - (bar _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by + (fromTangentSpace _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] congr - · simp only [bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul]; rw [real_inner_smul_right] + · simp only [fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul]; rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] rw [h1, h2, product_swap I Y Z] set A := rhs_aux I X Y Z x @@ -717,10 +717,10 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} set G1 := ⟪Y, Z⟫ x set G2 := ⟪X, Y⟫ x set dfx := (mfderiv I 𝓘(ℝ, ℝ) f x) - set H := (bar (f x)) (dfx (X x)) with H_eq - set K := (bar (f x)) (dfx (Z x)) with K_eq - change f x * A + (bar _).toFun (dfx (X x)) * G1 + f x * B - - (f x * C + (bar _).toFun (dfx (Z x)) * G2) + set H := (fromTangentSpace (f x)) (dfx (X x)) with H_eq + set K := (fromTangentSpace (f x)) (dfx (Z x)) with K_eq + change f x * A + (fromTangentSpace _).toFun (dfx (X x)) * G1 + f x * B + - (f x * C + (fromTangentSpace _).toFun (dfx (Z x)) * G2) - f x * D - (-H * G1 + f x * E) + (K * G2 + f x * F) = _ dsimp rw [← H_eq, ← K_eq] @@ -729,7 +729,7 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs I X (f • Y) Z x = - f x • leviCivitaRhs I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by + f x • leviCivitaRhs I X Y Z x + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] rw [smul_add, smul_comm] congr 1 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index bb8747de4a4be6..57fdfa75700c4a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -21,7 +21,7 @@ TODO: add a more complete doc-string @[expose] public section -- TODO: think if we want to expose all definitions! -open Bundle Filter Module Topology Set +open Bundle Filter Module Topology Set NormedSpace open scoped Bundle Manifold ContDiff @@ -89,7 +89,7 @@ lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative set B := f x • (cov Y x) (X x) set C := f x • VectorField.mlieBracket I X Y x set D := mfderiv% f x (Y x) - change B - (A + (bar _ D) • X x) - (-(bar _ D) • X x + C) = B - A - C + change B - (A + (fromTangentSpace _ D) • X x) - (-(fromTangentSpace _ D) • X x + C) = B - A - C module lemma torsionFun_smul_right_apply [CompleteSpace E] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean deleted file mode 100644 index a54026aa3d9ab0..00000000000000 --- a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean +++ /dev/null @@ -1,39 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ -module - -public import Mathlib.Geometry.Manifold.Notation -public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable - -/-! -# Miscellaneous pre-requisites for covariant derivatives - -TODO: this file should not exist; move everything in here to a proper place -(and PR it accordingly) - --/ - -@[expose] public section -- TODO: think if we want to expose all definitions! - -section prerequisites - -open Bundle Filter Function Topology Set - -open scoped Bundle Manifold ContDiff - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - - -set_option backward.isDefEq.respectTransparency false in -def bar (a : 𝕜) : TangentSpace 𝓘(𝕜) a ≃L[𝕜] 𝕜 where - toFun v := v - invFun v := v - map_add' := by simp - map_smul' := by simp - - - -end prerequisites diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index cd3aa9bf0a5a8b..32f14e186a22cb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -6,7 +6,6 @@ Authors: Patrick Massot, Michael Rothgang, Heather Macbeth module public import Mathlib.Geometry.Manifold.VectorBundle.Hom -public import Mathlib.Geometry.Manifold.VectorBundle.Misc public import Mathlib.Geometry.Manifold.VectorBundle.Extend import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame public import Mathlib.Geometry.Manifold.VectorBundle.IsBilinearPrelim From ad741cb9509701f72a007c9611605c117e0eddc0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 21:54:24 +0000 Subject: [PATCH 511/601] Small tweaks and nits --- .../VectorBundle/CovariantDerivative/Basic.lean | 2 +- .../CovariantDerivative/Ehresmann.lean | 4 +--- .../Geometry/Manifold/VectorBundle/Extend.lean | 16 ++++++---------- .../Manifold/VectorBundle/Tensoriality.lean | 13 ++++++------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index fe5b6ab21a9580..119f5fe0c59783 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -390,7 +390,7 @@ lemma congr_σ_of_eqOn [IsManifold I 1 M] · simpa using hσσ' _ hx's · simp have hψ' : HasMFDerivAt I 𝓘(𝕜) ψ x 0 := by - have : HasMFDerivAt I 𝓘(𝕜, 𝕜) (fun x_1 ↦ (1:𝕜)) x 0 := hasMFDerivAt_const .. + have : HasMFDerivAt I 𝓘(𝕜, 𝕜) (fun (_x : M) ↦ (1 : 𝕜)) x 0 := hasMFDerivAt_const .. refine this.congr_of_eventuallyEq ?_ apply Filter.eventuallyEq_of_mem hxs intro t ht diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index eddccfe99aeffd..c47f95bd03b82f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -262,9 +262,7 @@ lemma coordChangeL_mem_horiz [FiniteDimensional 𝕜 E] rintro ⟨s, sdiff, sxv, sxuw, covs⟩ use fun x ↦ e.coordChangeL 𝕜 e' x (s x), ?_, ?_, ?_ · let X := extend E u - have hX : MDiffAt (T% X) x := by - -- TODO: extract as lemma? - exact mdifferentiableAt_extend I E u + -- have hX : MDiffAt (T% X) x := mdifferentiableAt_extend I E u -- TODO: investigate whether the following line comes from inconsistent ways to -- state assumptions rw [mdifferentiableAt_section_trivial_iff] at sdiff diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean index 60e1520b13d520..2ef9f8cb2f75b7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -46,36 +46,32 @@ The details of the extension are mostly unspecified: for covariant derivatives, noncomputable def extend {x : M} (v₀ : V x) : (x' : M) → V x' := letI t := trivializationAt F V x - let w : F := (t ⟨x, v₀⟩).2 + letI w : F := (t ⟨x, v₀⟩).2 fun x' ↦ t.symm x' w -variable {I F} - +variable {I F} in @[simp] lemma extend_apply_self {x : M} (v : V x) : extend F v x = v := by unfold extend - rw [Trivialization.symm_apply_apply_mk] - exact FiberBundle.mem_baseSet_trivializationAt' x - -variable (I F) + simp [FiberBundle.mem_baseSet_trivializationAt' x] variable [NormedSpace 𝕜 F] -- TODO there is a lemma already with this name which should be renamed to something like --- `Chart.contMDiffAt_extend` +-- `Chart.contMDiffAt_extend` or `OpenPartialHomeomorph.contMDiffAt_extend` lemma contMDiffAt_extend' {k} [IsManifold I k M] {x : M} (σ₀ : V x) : CMDiffAt k (T% (extend F σ₀)) x := by rw [contMDiffAt_section] set t := trivializationAt F V x let w : F := (t ⟨x, σ₀⟩).2 - have : ContMDiffAt I 𝓘(𝕜, F) k (fun x_1 ↦ w) x := contMDiffAt_const + have : CMDiffAt k (fun (_x : M) ↦ w) x := contMDiffAt_const refine this.congr_of_eventuallyEq ?_ apply eventually_nhds_iff.mpr refine ⟨t.baseSet, ?_, t.open_baseSet, ?_⟩ · intro x hx dsimp only unfold extend - rw [t.mk_symm hx, t.apply_symm_apply' hx] + simp [t, hx, w] · exact FiberBundle.mem_baseSet_trivializationAt' x lemma mdifferentiableAt_extend [IsManifold I 1 M] {x : M} (σ₀ : V x) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 32f14e186a22cb..aee0dd56191a27 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -21,8 +21,7 @@ open scoped Bundle Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} [TopologicalSpace M] [ChartedSpace H M] @@ -60,19 +59,19 @@ lemma tensoriality_criterion obtain ⟨t, htσσ', ht, hxt⟩ := hσσ' let ψ (x' : M) : 𝕜 := if x' ∈ t then 1 else 0 have hψx : ψ x = 1 := by simp [ψ, hxt] - have (x' : M) : ((ψ : M → 𝕜) • σ) x' = ((ψ : M → 𝕜) • σ') x' := by + have (x' : M) : (ψ • σ) x' = (ψ • σ') x' := by dsimp [ψ] split_ifs with hx't · simpa using htσσ' _ hx't · simp - have hψ' : MDifferentiableAt I 𝓘(𝕜) ψ x := by - have : MDifferentiableAt I 𝓘(𝕜, 𝕜) (fun x_1 ↦ (1:𝕜)) x := mdifferentiableAt_const + have hψ' : MDiffAt ψ x := by + have : MDiffAt (fun (_x : M) ↦ (1 : 𝕜)) x := mdifferentiableAt_const refine this.congr_of_eventuallyEq ?_ apply eventually_nhds_iff.mpr exact ⟨t, by simp [ψ], ht, hxt⟩ calc φ σ x - _ = φ ((ψ : M → 𝕜) • σ) x := by simp [φ_smul _ _ hψ' hσ, hψx] - _ = φ ((ψ : M → 𝕜) • σ') x := by rw [funext this] + _ = φ (ψ • σ) x := by simp [φ_smul _ _ hψ' hσ, hψx] + _ = φ (ψ • σ') x := by rw [funext this] _ = φ σ' x := by simp [φ_smul _ _ hψ' hσ', hψx] let ι : Type _ := Basis.ofVectorSpaceIndex 𝕜 F classical From 10cf13081db6c158c8c40a7629a81d906745035e Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Thu, 5 Mar 2026 22:12:39 +0000 Subject: [PATCH 512/601] fill in TODO lemmas for extend --- .../Manifold/VectorBundle/Extend.lean | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean index 2ef9f8cb2f75b7..71b861640c5736 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -43,20 +43,36 @@ open Classical in The details of the extension are mostly unspecified: for covariant derivatives, the value of `s` at points other than `x` will not matter (except for shorter proofs). -/ -noncomputable def extend {x : M} (v₀ : V x) : - (x' : M) → V x' := +noncomputable def extend {x : M} (v₀ : V x) (x' : M) : V x' := letI t := trivializationAt F V x letI w : F := (t ⟨x, v₀⟩).2 - fun x' ↦ t.symm x' w + t.symm x' w variable {I F} in -@[simp] lemma extend_apply_self {x : M} (v : V x) : - extend F v x = v := by - unfold extend - simp [FiberBundle.mem_baseSet_trivializationAt' x] +@[simp] lemma extend_apply_self {x : M} (v : V x) : extend F v x = v := by + simp [extend, FiberBundle.mem_baseSet_trivializationAt' x] variable [NormedSpace 𝕜 F] +lemma exists_contMDiffOn_extend {k} [IsManifold I k M] [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] + [ContMDiffVectorBundle k F V I] {x₀ : M} (σ₀ : V x₀) : + ∃ s ∈ 𝓝 x₀, ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (T% (extend F σ₀)) s := by + set t := trivializationAt F V x₀ + refine ⟨t.baseSet, ?_, ?_⟩ + · refine t.open_baseSet.mem_nhds ?_ + exact FiberBundle.mem_baseSet_trivializationAt' x₀ + suffices ContMDiffOn I 𝓘(𝕜, F) k (fun x ↦ (t ⟨x, extend F σ₀ x⟩).2) t.baseSet by + intro x hx + rw [t.contMDiffWithinAt_section _ hx] + exact this x hx + let w : F := (t ⟨x₀, σ₀⟩).2 + have : ContMDiffOn I 𝓘(𝕜, F) k (fun x_1 ↦ w) t.baseSet := contMDiffOn_const + refine this.congr ?_ + intro x hx + dsimp only + unfold extend + rw [t.mk_symm hx, t.apply_symm_apply' hx] + -- TODO there is a lemma already with this name which should be renamed to something like -- `Chart.contMDiffAt_extend` or `OpenPartialHomeomorph.contMDiffAt_extend` lemma contMDiffAt_extend' {k} [IsManifold I k M] {x : M} (σ₀ : V x) : @@ -74,11 +90,14 @@ lemma contMDiffAt_extend' {k} [IsManifold I k M] {x : M} (σ₀ : V x) : simp [t, hx, w] · exact FiberBundle.mem_baseSet_trivializationAt' x +lemma exists_mdifferentiableOn_extend [IsManifold I 1 M] [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] + [ContMDiffVectorBundle 1 F V I] {x₀ : M} (σ₀ : V x₀) : + ∃ s ∈ 𝓝 x₀, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (T% (extend F σ₀)) s := by + obtain ⟨s, hs, hsσ⟩ := exists_contMDiffOn_extend (k := 1) I F σ₀ + exact ⟨s, hs, hsσ.mdifferentiableOn one_ne_zero⟩ + lemma mdifferentiableAt_extend [IsManifold I 1 M] {x : M} (σ₀ : V x) : MDiffAt (T% (extend F σ₀)) x := - have := contMDiffAt_extend' (k := 1) I F σ₀ - this.mdifferentiableAt one_ne_zero - --- TODO also prove `ContMDiffOn` and `MDifferentiableOn` in a neighbourhood of the point + (contMDiffAt_extend' (k := 1) I F σ₀).mdifferentiableAt one_ne_zero end extend From 856836f7072e37f1bed8155811ab7522750b23dd Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Thu, 5 Mar 2026 22:33:38 +0000 Subject: [PATCH 513/601] Characterisation of compatibility and progress towards it: enough for tonight --- .../CovariantDerivative/Ehresmann.lean | 1 - .../CovariantDerivative/LeviCivita.lean | 51 ++++++++++++++++--- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index c47f95bd03b82f..4660ec1de55bc6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -6,7 +6,6 @@ Authors: Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim -public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index a6eeffabb289da..0d5f68a30a8c9a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -340,6 +340,16 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) erw [ContinuousLinearMap.comp_apply] simp [product, real_inner_comm, fromTangentSpace] +variable {I} in +-- XXX: the torsion tensor has only this version, none matching `metricTensor_apply` +theorem metricTensor_apply' [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : + MetricTensor cov x Y₀ Z₀ X₀ = + fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) + - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x + - ⟪extend E Y₀, ∇ extend E Z₀, (extend E X₀)⟫ x := by + simpa [extend_apply_self] using metricTensor_apply cov x + (X := extend E X₀) (mdifferentiableAt_extend I E Y₀) (mdifferentiableAt_extend I E Z₀) + /-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ @@ -360,11 +370,17 @@ lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x exact isCompatible_apply_aux this lemma isCompatible_iff [FiniteDimensional ℝ E] : - cov.IsCompatible ↔ ∀ {x : M} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x), + cov.IsCompatible ↔ ∀ {x : M} (X : (x : M) → TangentSpace I x) {Y Z : (x : M) → TangentSpace I x} + (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by - refine ⟨fun hcov x hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ + refine ⟨fun hcov x X Y Z hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ unfold IsCompatible - sorry + ext x X₀ Y₀ Z₀ + rw [metricTensor_apply', sub_sub, sub_eq_iff_eq_add'] + simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] + convert h (_root_.extend E Z₀) (mdifferentiableAt_extend I E X₀) + (mdifferentiableAt_extend I E Y₀) + simp [fromTangentSpace, extend_apply_self] /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. @@ -687,7 +703,8 @@ lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : ℝ} lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs' I X (f • Y) Z x = - f x • leviCivitaRhs' I X Y Z x + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by + f x • leviCivitaRhs' I X Y Z x + + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) • 2 * ⟪Y, Z⟫ x := by simp only [leviCivitaRhs'] simp_rw [rhs_aux_smulX I Y Z X f] simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] @@ -702,10 +719,12 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = - (fromTangentSpace _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by + (fromTangentSpace _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x + + f x • ⟪X, mlieBracket I Z Y⟫ x := by simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] congr - · simp only [fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul]; rw [real_inner_smul_right] + · simp only [fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul] + rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] rw [h1, h2, product_swap I Y Z] set A := rhs_aux I X Y Z x @@ -729,7 +748,8 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : leviCivitaRhs I X (f • Y) Z x = - f x • leviCivitaRhs I X Y Z x + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by + f x • leviCivitaRhs I X Y Z x + + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) • ⟪Y, Z⟫ x := by simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] rw [smul_add, smul_comm] congr 1 @@ -1035,10 +1055,27 @@ theorem leviCivitaConnection_apply [FiniteDimensional ℝ E] {x : M} inner ℝ (LeviCivitaConnection I M Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := lcAux_apply _ hX hY hZ +-- Why is everything SOOOO slow here? lemma leviCivitaConnection_isCompatible [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsCompatible := by + rw [isCompatible_iff] + intro x X Y Z hY hZ + symm + unfold product + dsimp + have hX : MDiffAt (T% X) x := sorry -- missing hypothesis, it seems + rw [leviCivitaConnection_apply I hX hY hZ] + have : inner ℝ (Y x) (((LeviCivitaConnection I M) Z x) (X x)) = + inner ℝ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) := sorry + rw [this] + have : inner ℝ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) = leviCivitaRhs I X Z Y x := by + rw [leviCivitaConnection_apply I hX hZ hY] + rw [leviCivitaConnection_apply I hX hZ hY] + rw [leviCivitaRhs_apply, leviCivitaRhs_apply] + -- to be continued sorry +#exit lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsTorsionFree := by have a := (LeviCivitaConnection I M).isCovariantDerivativeOn From e0639d990be1f6a1d4f31b259272ef92217a1244 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 00:35:17 +0000 Subject: [PATCH 514/601] Torsion-freeness is done. (Just one broken proof to fix, erw issues.) --- .../CovariantDerivative/LeviCivita.lean | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0d5f68a30a8c9a..8b5bb7e01d4a6f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -370,15 +370,15 @@ lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x exact isCompatible_apply_aux this lemma isCompatible_iff [FiniteDimensional ℝ E] : - cov.IsCompatible ↔ ∀ {x : M} (X : (x : M) → TangentSpace I x) {Y Z : (x : M) → TangentSpace I x} - (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), + cov.IsCompatible ↔ ∀ {x : M} {X Y Z : (x : M) → TangentSpace I x} + (_hX : MDiffAt (T% X) x) (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by - refine ⟨fun hcov x X Y Z hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ + refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ unfold IsCompatible ext x X₀ Y₀ Z₀ rw [metricTensor_apply', sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] - convert h (_root_.extend E Z₀) (mdifferentiableAt_extend I E X₀) + convert h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I E Y₀) simp [fromTangentSpace, extend_apply_self] @@ -711,11 +711,12 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} rw [rhs_aux_smulY_apply I X hf hY hZ, rhs_aux_smulZ_apply I Z hf hX hY] -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? have h1 : ⟪Z, mlieBracket I (f • Y) X⟫ x = - - (fromTangentSpace _).toFun (((mfderiv% f x) (X x))) • ⟪Z, Y⟫ x + f x • ⟪Z, mlieBracket I Y X⟫ x := by + - (fromTangentSpace _).toFun (((mfderiv% f x) (X x))) • ⟪Z, Y⟫ x + + f x • ⟪Z, mlieBracket I Y X⟫ x := by simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] congr - · simp only [neg_smul, inner_neg_right, fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul, - neg_mul, neg_inj] + · simp only [neg_smul, inner_neg_right, fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, + smul_eq_mul, neg_mul, neg_inj] rw [real_inner_smul_right] · rw [inner_smul_right_eq_smul] have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = @@ -1055,27 +1056,43 @@ theorem leviCivitaConnection_apply [FiniteDimensional ℝ E] {x : M} inner ℝ (LeviCivitaConnection I M Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := lcAux_apply _ hX hY hZ --- Why is everything SOOOO slow here? +-- Side computation for `leviCivitaConnection_isCompatible`. +lemma leviCivitaConnection_isCompatible_aux [FiniteDimensional ℝ E] + {x : M} {X Y Z : (x : M) → TangentSpace I x} : + leviCivitaRhs I X Y Z x + leviCivitaRhs I X Z Y x = + ((mfderiv% fun x ↦ inner ℝ (Y x) (Z x)) x) (X x) := by + simp only [leviCivitaRhs, Pi.smul_apply, ← smul_add, leviCivitaRhs'] + -- Normalise the expressions by swapping arguments for rhs_aux and mlieBracket, + -- until the swappable arguments are in order X < Y < Z. + rw [rhs_aux_swap I Z Y, rhs_aux_swap I Z X, rhs_aux_swap I Y X, + VectorField.mlieBracket_swap (V := Z) (W := Y), + VectorField.mlieBracket_swap (V := Y) (W := X), + VectorField.mlieBracket_swap (V := Z) (W := X)] + -- Observe that the right hand side is rhx_aux X Y Z; then we just need to simplify and rearrange. + trans 1 / 2 * (rhs_aux I X Y Z x + rhs_aux I X Y Z x) + · simp + abel + · rw [← two_mul, ← mul_assoc, one_div, inv_mul_cancel₀ (by simp), one_mul] + +-- Why is everything so slow? lemma leviCivitaConnection_isCompatible [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsCompatible := by rw [isCompatible_iff] - intro x X Y Z hY hZ + intro x X Y Z hX hY hZ symm unfold product dsimp - have hX : MDiffAt (T% X) x := sorry -- missing hypothesis, it seems rw [leviCivitaConnection_apply I hX hY hZ] have : inner ℝ (Y x) (((LeviCivitaConnection I M) Z x) (X x)) = - inner ℝ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) := sorry + inner ℝ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) := by + rw [real_inner_comm] + -- TODO: why does the following line not work, but `rw [this]` does? + --rw [real_inner_comm] rw [this] have : inner ℝ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) = leviCivitaRhs I X Z Y x := by rw [leviCivitaConnection_apply I hX hZ hY] - rw [leviCivitaConnection_apply I hX hZ hY] - rw [leviCivitaRhs_apply, leviCivitaRhs_apply] - -- to be continued - sorry + rw [leviCivitaConnection_apply I hX hZ hY, leviCivitaConnection_isCompatible_aux] -#exit lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsTorsionFree := by have a := (LeviCivitaConnection I M).isCovariantDerivativeOn @@ -1111,11 +1128,10 @@ lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : match_scalars <;> simp norm_num -#exit - lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_isTorsionFree I⟩ +#exit -- TODO: move this section to `Torsion.lean` section From 15255f59b9bb40ed6fd7d50b6ddeadad52918da1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 00:59:20 +0000 Subject: [PATCH 515/601] Comment on naming scheme --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 1 + .../Manifold/VectorBundle/CovariantDerivative/Torsion.lean | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 8b5bb7e01d4a6f..aa22c3871113aa 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -246,6 +246,7 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply] -- bug: abel fails, but module works + -- hypothesis: B, B', C, C' are in ℝ, while A and A' are in the tangent space at ℝ instead module variable {I} in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 57fdfa75700c4a..2327900eaa7c05 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -158,6 +158,8 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- The torsion tensor of a covariant derivative on the tangent bundle of a manifold. -/ noncomputable def torsion := cov.isCovariantDerivativeOn.torsion +-- TODO: decide on a good naming scheme; `vector_field_apply` and `apply` or perhaps +-- `apply` and `apply_extend`? And synchronise with the compatibility file. lemma torsion_vector_field_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : cov.torsion x (X x) (Y x) = cov Y x (X x) - cov X x (Y x) - mlieBracket I X Y x := by unfold torsion IsCovariantDerivativeOn.torsion From 7b46dfd5eac8b412b5e6f6ad3eb104b8001a70d7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 01:10:16 +0000 Subject: [PATCH 516/601] chore: move material on metric connections to a new file --- Mathlib.lean | 1 + .../CovariantDerivative/LeviCivita.lean | 325 +-------------- .../CovariantDerivative/Metric.lean | 387 ++++++++++++++++++ 3 files changed, 391 insertions(+), 322 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean diff --git a/Mathlib.lean b/Mathlib.lean index b8a5db09b57980..953b1e69cca576 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4419,6 +4419,7 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index aa22c3871113aa..42f68d19513fdd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -6,8 +6,8 @@ Authors: Patrick Massot, Michael Rothgang, Heather Macbeth module public import Mathlib.Analysis.InnerProductSpace.Dual +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion -public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian public import Mathlib.Util.PrintSorries /-! @@ -51,130 +51,6 @@ the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} -/-- The scalar product of two vector fields -/ -noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := - fun x ↦ inner ℝ (X x) (Y x) --- Riemannian.lean shows that `product` is C^k if X and Y are - -local notation "⟪" X ", " Y "⟫" => product I X Y - --- Basic API for the product of two vector fields. -section product - -omit [IsManifold I 2 M] - -lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl - -variable (X Y) in -lemma product_swap : ⟪Y, X⟫ = ⟪X, Y⟫ := by - ext x - apply real_inner_comm - -variable (X) in -@[simp] -lemma product_zero_left : ⟪0, X⟫ = 0 := by - ext x - simp [product] - -@[simp] -lemma product_zero_right : ⟪X, 0⟫ = 0 := by rw [product_swap, product_zero_left] - -variable (X X' Y) in -lemma product_add_left : ⟪X + X', Y⟫ = ⟪X, Y⟫ + ⟪X', Y⟫ := by - ext x - simp [product, InnerProductSpace.add_left] - -variable (X X' Y) in -@[simp] -lemma product_add_left_apply (x) : ⟪X + X', Y⟫ x = ⟪X, Y⟫ x + ⟪X', Y⟫ x := by - simp [product, InnerProductSpace.add_left] - -variable (X Y Y') in -lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by - rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] - -variable (X X' Y) in -@[simp] -lemma product_add_right_apply (x) : ⟪X, Y + Y'⟫ x = ⟪X, Y⟫ x + ⟪X, Y'⟫ x := by - rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left_apply] - -variable (X Y) in -@[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] - -variable (X Y) in -@[simp] lemma product_neg_right : ⟪X, -Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] - -variable (X X' Y) in -lemma product_sub_left : ⟪X - X', Y⟫ = ⟪X, Y⟫ - ⟪X', Y⟫ := by - ext x - simp [product, inner_sub_left] - -variable (X Y Y') in -lemma product_sub_right : ⟪X, Y - Y'⟫ = ⟪X, Y⟫ - ⟪X, Y'⟫ := by - ext x - simp [product, inner_sub_right] - -variable (X Y) in -lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by - ext x - simp [product, real_inner_smul_left] - -variable (X Y) in -@[simp] -lemma product_smul_const_left (a : ℝ) : product I (a • X) Y = a • product I X Y := by - ext x - simp [product, real_inner_smul_left] - -variable (X Y) in -lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by - ext x - simp [product, real_inner_smul_right] - -variable (X Y) in -@[simp] -lemma product_smul_const_right (a : ℝ) : product I X (a • Y) = a • product I X Y := by - ext x - simp [product, real_inner_smul_right] - -end product - --- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) --- only hold point-wise. They abstract the expanding and unexpanding of `product`. -omit [IsManifold I 2 M] in -lemma product_congr_left {x} (h : X x = X' x) : product I X Y x = product I X' Y x := by - rw [product_apply, h, ← product_apply] - -omit [IsManifold I 2 M] in -lemma product_congr_left₂ {x} (h : X x = X' x + X'' x) : - product I X Y x = product I X' Y x + product I X'' Y x := by - rw [product_apply, h, inner_add_left, ← product_apply] -omit [IsManifold I 2 M] in -lemma product_congr_right {x} (h : Y x = Y' x) : product I X Y x = product I X Y' x := by - rw [product_apply, h, ← product_apply] - -omit [IsManifold I 2 M] in -lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : - product I X Y x = product I X Y' x + product I X Y'' x := by - rw [product_apply, h, inner_add_right, ← product_apply] - -/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` -yields an error -synthesized type class instance is not definitionally equal to expression inferred by typing rules, -synthesized - fun x ↦ instNormedAddCommGroupOfRiemannianBundle x -inferred - fun b ↦ inst✝⁷ -/ --- TODO: diagnose and fix this, and replace by `MDifferentiable(At).inner_bundle! - -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in -lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := - MDifferentiable.inner_bundle hY hZ - -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in -lemma MDifferentiableAt.inner_bundle' {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - MDiffAt ⟪Y, Z⟫ x := - MDifferentiableAt.inner_bundle hY hZ - namespace CovariantDerivative -- Let `cov` be a covariant derivative on `TM`. @@ -184,205 +60,8 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) -noncomputable def myfun (Y Z : Π x : M, TangentSpace I x) : - Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ - letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x - b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) - variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] -variable {I} in -private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} - (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - myfun I cov (f • σ) τ x = f x • myfun I cov σ τ x := by - unfold myfun - rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] - ext X - simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, - RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, - ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', - coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] - erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.add_apply] - conv => - enter [1, 1, 2, 1] - erw [ContinuousLinearMap.smul_apply] - rw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, - ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, - innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, - inner_smul_right, mfderiv_smul (hσ.inner_bundle' hτ) hf] - simp only [smul_eq_mul, Pi.mul_apply, fromTangentSpace, ContinuousLinearEquiv.coe_coe, - ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] - conv => - enter [1, 1, 1, 2, 2] - dsimp [product] - rw [real_inner_comm] - rw [← sub_eq_zero] - ring - -variable {I} in -private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) - (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : - myfun I cov (σ + σ') τ x = myfun I cov σ τ x + myfun I cov σ' τ x := by - simp only [myfun] - ext X - simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, - Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] - rw [product_add_left, - mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), - cov.isCovariantDerivativeOn.addσ hσ hσ', - ContinuousLinearMap.comp_add] - erw [ContinuousLinearMap.coe_sub'] - rw [Pi.sub_apply] - erw [ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] - -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x - -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) - -- set B' := ((innerSL ℝ) (τ x)).comp (cov σ' x) - -- set C := inner ℝ (σ x) ((cov τ x) X) - -- set C' := inner ℝ (σ' x) ((cov τ x) X) - erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, - ContinuousLinearMap.sub_apply] - -- bug: abel fails, but module works - -- hypothesis: B, B', C, C' are in ℝ, while A and A' are in the tangent space at ℝ instead - module - -variable {I} in -private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} - (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - myfun I cov σ (f • τ) x = f x • myfun I cov σ τ x := by - unfold myfun - rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] - ext X - simp only [smul_eq_mul, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, - ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, - ContinuousLinearMap.coe_sub', Pi.sub_apply, ContinuousLinearMap.add_apply, - ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.smul_apply, - comp_apply, ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply] - erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] - --set A := inner ℝ (σ x) ((cov τ x) X) - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.smul_apply] - conv => - enter [1, 1, 2, 2] - erw [ContinuousLinearMap.comp_apply] - dsimp - --set B := inner ℝ (τ x) ((cov σ x) X) - erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] - --set C := (mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) X - --set D := (mfderiv I 𝓘(ℝ, ℝ) f x) X - simp only [smul_eq_mul, fromTangentSpace, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, - LinearMap.coe_mk, AddHom.coe_mk, inner_smul_right] - -- would be nice to finish by a tactic now! - erw [mul_add, mul_add] - rw [Pi.mul_apply, mul_neg, mul_neg, - ← sub_eq_add_neg, ← sub_eq_add_neg, sub_add_eq_sub_sub] - match_scalars <;> all_goals simp - -variable {I} in -private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) - (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : - myfun I cov σ (τ + τ') x = myfun I cov σ τ x + myfun I cov σ τ' x := by - unfold myfun - ext X - simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', - ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, - ContinuousLinearMap.add_apply] - rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), - cov.isCovariantDerivativeOn.addσ hτ hτ'] - dsimp - rw [inner_add_right] - erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, - ContinuousLinearMap.add_apply, ContinuousLinearMap.comp_apply] - /- TODO: proof used to be done before merging rc4; was: - conv => - enter [2, 2, 1, 2] - erw [ContinuousLinearMap.comp_apply] - rw [innerSL_apply_apply] - conv => - enter [2, 2, 1, 2] - erw [innerSL_apply_apply] - module -/ - sorry - -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x - -- set C := inner ℝ (σ x) ((cov τ x) X) - -- set C' := inner ℝ (σ x) ((cov τ' x) X) - -- set D := (cov σ x) X - -variable {I} in -/-- The tensor `∇ g` defined by a connection `∇` on a Riemannian manifold `(M, g)`. -/ -@[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : - TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - mk2TensorAt I E E (myfun I cov) - (fun _f _σ _τ hf hσ hτ ↦ aux1 cov hf hσ hτ) - (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) - (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) - (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') - --- TODO: should we have ∇ X Y and ∇ X Z instead? -variable {I} in -theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) - (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - MetricTensor cov x (Y x) (Z x) (X x) = - fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by - unfold MetricTensor - rw [mk2TensorAt_apply _ _ _ _ _ _ hY hZ] - simp only [myfun, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, - Pi.sub_apply, comp_apply] - conv => - enter [1, 1] - erw [ContinuousLinearMap.sub_apply] - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.comp_apply] - simp [product, real_inner_comm, fromTangentSpace] - -variable {I} in --- XXX: the torsion tensor has only this version, none matching `metricTensor_apply` -theorem metricTensor_apply' [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : - MetricTensor cov x Y₀ Z₀ X₀ = - fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) - - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x - - ⟪extend E Y₀, ∇ extend E Z₀, (extend E X₀)⟫ x := by - simpa [extend_apply_self] using metricTensor_apply cov x - (X := extend E X₀) (mdifferentiableAt_extend I E Y₀) (mdifferentiableAt_extend I E Z₀) - -/-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with -the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have -`X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ -def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 - --- Auxiliary computation for `IsCompatible_apply`. --- TODO: inlining this lemma does not work -private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + C := by grind - -variable {I} in -lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} - (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by - rw [IsCompatible] at hcov - have : MetricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] - rw [metricTensor_apply cov x hY hZ] at this - change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ - exact isCompatible_apply_aux this - -lemma isCompatible_iff [FiniteDimensional ℝ E] : - cov.IsCompatible ↔ ∀ {x : M} {X Y Z : (x : M) → TangentSpace I x} - (_hX : MDiffAt (T% X) x) (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by - refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ - unfold IsCompatible - ext x X₀ Y₀ Z₀ - rw [metricTensor_apply', sub_sub, sub_eq_iff_eq_add'] - simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] - convert h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) - (mdifferentiableAt_extend I E Y₀) - simp [fromTangentSpace, extend_apply_self] - /-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** iff it is torsion-free and compatible with `g`. Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a @@ -390,6 +69,8 @@ version depending on a choice of Riemannian metric on `M`. -/ def IsLeviCivitaConnection [FiniteDimensional ℝ E] : Prop := cov.IsCompatible ∧ cov.IsTorsionFree +local notation "⟪" X ", " Y "⟫" => product I X Y + variable (X Y Z) in /-- The first term in the definition of the candidate Levi-Civita connection: `rhs_aux I X Y Z = X ⟨Y, Z⟩ = x ↦ d(⟨Y, Z⟩)_x (X x)`. diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean new file mode 100644 index 00000000000000..8126d2e73ecc07 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -0,0 +1,387 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian + +/-! # Metric connections + +This file defines connections on a Riemannian manifold which are compatible with the ambient metric. + +TODO extend this doc-string! + + +TODO: more generally, define a notion of metric connections (e.g., those whose parallel transport +is an isometry) and prove the Levi-Civita connection is a metric connection + +-/ + +open Bundle Filter Function Module NormedSpace Topology + +open scoped Bundle Manifold ContDiff + +@[expose] public section -- TODO: think if we want to expose all definitions! + +-- TODO: revisit and fix this once the dust has settled +set_option backward.isDefEq.respectTransparency false + +-- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. +variable {n : WithTop ℕ∞} + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] + [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] + +/-! Compatible connections: a connection on `TM` is compatible with the metric on `M` iff +`∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all sufficiently nice vector fields `X`, `Y` and +`Z` on `M`. In our definition, we ask for this identity to at each `x : M`, whenever `X`, `Y` and +`Z` are differentiable at `x`. +The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: +the left hand side at `x` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ + +variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} + +/-- The scalar product of two vector fields -/ +noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := + fun x ↦ inner ℝ (X x) (Y x) + +-- `product` is C^k if X and Y are: this is shown in `Riemannian.lean` + +local notation "⟪" X ", " Y "⟫" => product I X Y + +-- Basic API for the product of two vector fields. +section product + +omit [IsManifold I 2 M] + +lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl + +variable (X Y) in +lemma product_swap : ⟪Y, X⟫ = ⟪X, Y⟫ := by + ext x + apply real_inner_comm + +variable (X) in +@[simp] +lemma product_zero_left : ⟪0, X⟫ = 0 := by + ext x + simp [product] + +@[simp] +lemma product_zero_right : ⟪X, 0⟫ = 0 := by rw [product_swap, product_zero_left] + +variable (X X' Y) in +lemma product_add_left : ⟪X + X', Y⟫ = ⟪X, Y⟫ + ⟪X', Y⟫ := by + ext x + simp [product, InnerProductSpace.add_left] + +variable (X X' Y) in +@[simp] +lemma product_add_left_apply (x) : ⟪X + X', Y⟫ x = ⟪X, Y⟫ x + ⟪X', Y⟫ x := by + simp [product, InnerProductSpace.add_left] + +variable (X Y Y') in +lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by + rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] + +variable (X X' Y) in +@[simp] +lemma product_add_right_apply (x) : ⟪X, Y + Y'⟫ x = ⟪X, Y⟫ x + ⟪X, Y'⟫ x := by + rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left_apply] + +variable (X Y) in +@[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] + +variable (X Y) in +@[simp] lemma product_neg_right : ⟪X, -Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] + +variable (X X' Y) in +lemma product_sub_left : ⟪X - X', Y⟫ = ⟪X, Y⟫ - ⟪X', Y⟫ := by + ext x + simp [product, inner_sub_left] + +variable (X Y Y') in +lemma product_sub_right : ⟪X, Y - Y'⟫ = ⟪X, Y⟫ - ⟪X, Y'⟫ := by + ext x + simp [product, inner_sub_right] + +variable (X Y) in +lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by + ext x + simp [product, real_inner_smul_left] + +variable (X Y) in +@[simp] +lemma product_smul_const_left (a : ℝ) : product I (a • X) Y = a • product I X Y := by + ext x + simp [product, real_inner_smul_left] + +variable (X Y) in +lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by + ext x + simp [product, real_inner_smul_right] + +variable (X Y) in +@[simp] +lemma product_smul_const_right (a : ℝ) : product I X (a • Y) = a • product I X Y := by + ext x + simp [product, real_inner_smul_right] + +end product + +-- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) +-- only hold point-wise. They abstract the expanding and unexpanding of `product`. +omit [IsManifold I 2 M] in +lemma product_congr_left {x} (h : X x = X' x) : product I X Y x = product I X' Y x := by + rw [product_apply, h, ← product_apply] + +omit [IsManifold I 2 M] in +lemma product_congr_left₂ {x} (h : X x = X' x + X'' x) : + product I X Y x = product I X' Y x + product I X'' Y x := by + rw [product_apply, h, inner_add_left, ← product_apply] +omit [IsManifold I 2 M] in +lemma product_congr_right {x} (h : Y x = Y' x) : product I X Y x = product I X Y' x := by + rw [product_apply, h, ← product_apply] + +omit [IsManifold I 2 M] in +lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : + product I X Y x = product I X Y' x + product I X Y'' x := by + rw [product_apply, h, inner_add_right, ← product_apply] + +/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` +yields an error +synthesized type class instance is not definitionally equal to expression inferred by typing rules, +synthesized + fun x ↦ instNormedAddCommGroupOfRiemannianBundle x +inferred + fun b ↦ inst✝⁷ -/ +-- TODO: diagnose and fix this, and replace by `MDifferentiable(At).inner_bundle! + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := + MDifferentiable.inner_bundle hY hZ + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +lemma MDifferentiableAt.inner_bundle' {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + MDiffAt ⟪Y, Z⟫ x := + MDifferentiableAt.inner_bundle hY hZ + +namespace CovariantDerivative + +-- Let `cov` be a covariant derivative on `TM`. +-- TODO: include in cheat sheet! +variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) + +/-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ +local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) + +/-- The function defining the metric or compatibility tensor `∇ g` -/ +noncomputable def metricTensorFun (Y Z : Π x : M, TangentSpace I x) : + Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ + letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x + b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] + +variable {I} in +private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} + (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + metricTensorFun I cov (f • σ) τ x = f x • metricTensorFun I cov σ τ x := by + unfold metricTensorFun + rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] + ext X + simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, + RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, + ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', + coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] + erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] + conv => + enter [1, 1, 2] + erw [ContinuousLinearMap.add_apply] + conv => + enter [1, 1, 2, 1] + erw [ContinuousLinearMap.smul_apply] + rw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, + ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, + innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, + inner_smul_right, mfderiv_smul (hσ.inner_bundle' hτ) hf] + simp only [smul_eq_mul, Pi.mul_apply, fromTangentSpace, ContinuousLinearEquiv.coe_coe, + ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] + conv => + enter [1, 1, 1, 2, 2] + dsimp [product] + rw [real_inner_comm] + rw [← sub_eq_zero] + ring + +variable {I} in +private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : + metricTensorFun I cov (σ + σ') τ x = + metricTensorFun I cov σ τ x + metricTensorFun I cov σ' τ x := by + simp only [metricTensorFun] + ext X + simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, + Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] + rw [product_add_left, + mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), + cov.isCovariantDerivativeOn.addσ hσ hσ', + ContinuousLinearMap.comp_add] + erw [ContinuousLinearMap.coe_sub'] + rw [Pi.sub_apply] + erw [ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] + -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x + -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) + -- set B' := ((innerSL ℝ) (τ x)).comp (cov σ' x) + -- set C := inner ℝ (σ x) ((cov τ x) X) + -- set C' := inner ℝ (σ' x) ((cov τ x) X) + erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, + ContinuousLinearMap.sub_apply] + -- bug: abel fails, but module works + -- hypothesis: B, B', C, C' are in ℝ, while A and A' are in the tangent space at ℝ instead + module + +variable {I} in +private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} + (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + metricTensorFun I cov σ (f • τ) x = f x • metricTensorFun I cov σ τ x := by + unfold metricTensorFun + rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] + ext X + simp only [smul_eq_mul, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, + ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, + ContinuousLinearMap.coe_sub', Pi.sub_apply, ContinuousLinearMap.add_apply, + ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.smul_apply, + comp_apply, ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply] + erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] + --set A := inner ℝ (σ x) ((cov τ x) X) + conv => + enter [1, 1, 2] + erw [ContinuousLinearMap.smul_apply] + conv => + enter [1, 1, 2, 2] + erw [ContinuousLinearMap.comp_apply] + dsimp + --set B := inner ℝ (τ x) ((cov σ x) X) + erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] + --set C := (mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) X + --set D := (mfderiv I 𝓘(ℝ, ℝ) f x) X + simp only [smul_eq_mul, fromTangentSpace, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, + LinearMap.coe_mk, AddHom.coe_mk, inner_smul_right] + -- would be nice to finish by a tactic now! + erw [mul_add, mul_add] + rw [Pi.mul_apply, mul_neg, mul_neg, + ← sub_eq_add_neg, ← sub_eq_add_neg, sub_add_eq_sub_sub] + match_scalars <;> all_goals simp + +variable {I} in +private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) + (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : + metricTensorFun I cov σ (τ + τ') x = + metricTensorFun I cov σ τ x + metricTensorFun I cov σ τ' x := by + unfold metricTensorFun + ext X + simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', + ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, + ContinuousLinearMap.add_apply] + rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), + cov.isCovariantDerivativeOn.addσ hτ hτ'] + dsimp + rw [inner_add_right] + erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, + ContinuousLinearMap.add_apply, ContinuousLinearMap.comp_apply] + /- TODO: proof used to be done before merging rc4; was: + conv => + enter [2, 2, 1, 2] + erw [ContinuousLinearMap.comp_apply] + rw [innerSL_apply_apply] + conv => + enter [2, 2, 1, 2] + erw [innerSL_apply_apply] + module -/ + sorry + -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x + -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x + -- set C := inner ℝ (σ x) ((cov τ x) X) + -- set C' := inner ℝ (σ x) ((cov τ' x) X) + -- set D := (cov σ x) X + +variable {I} in +/-- The tensor `∇ g` defined by a connection `∇` on a Riemannian manifold `(M, g)`. -/ +@[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : + TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := + mk2TensorAt I E E (metricTensorFun I cov) + (fun _f _σ _τ hf hσ hτ ↦ aux1 cov hf hσ hτ) + (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) + (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) + (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') + +-- TODO: should we have ∇ X Y and ∇ X Z instead? +variable {I} in +theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + MetricTensor cov x (Y x) (Z x) (X x) = + fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by + unfold MetricTensor + rw [mk2TensorAt_apply _ _ _ _ _ _ hY hZ] + simp only [metricTensorFun, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', + coe_innerSL_apply, Pi.sub_apply, comp_apply] + conv => + enter [1, 1] + erw [ContinuousLinearMap.sub_apply] + conv => + enter [1, 1, 2] + erw [ContinuousLinearMap.comp_apply] + simp [product, real_inner_comm, fromTangentSpace] + +variable {I} in +-- TODO: make naming consistent with `torsion` (which uses `vector_field_apply` and `apply` instead) +theorem metricTensor_apply' [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : + MetricTensor cov x Y₀ Z₀ X₀ = + fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) + - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x + - ⟪extend E Y₀, ∇ extend E Z₀, (extend E X₀)⟫ x := by + simpa [extend_apply_self] using metricTensor_apply cov x + (X := extend E X₀) (mdifferentiableAt_extend I E Y₀) (mdifferentiableAt_extend I E Z₀) + +/-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with +the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have +`X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ +def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 + +-- Auxiliary computation for `IsCompatible_apply`. +-- TODO: inlining this lemma does not work +private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + C := by grind + +-- TODO: give a better name; maybe inline? +variable {I} in +lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by + rw [IsCompatible] at hcov + have : MetricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] + rw [metricTensor_apply cov x hY hZ] at this + change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ + exact isCompatible_apply_aux this + +lemma isCompatible_iff [FiniteDimensional ℝ E] : + cov.IsCompatible ↔ ∀ {x : M} {X Y Z : (x : M) → TangentSpace I x} + (_hX : MDiffAt (T% X) x) (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), + mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by + refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ + unfold IsCompatible + ext x X₀ Y₀ Z₀ + rw [metricTensor_apply', sub_sub, sub_eq_iff_eq_add'] + simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] + convert h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) + (mdifferentiableAt_extend I E Y₀) + simp [fromTangentSpace, extend_apply_self] + +end CovariantDerivative From 1ab8a9acf49594fb9f92d5c48d53b7ba84d1f53b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 01:18:51 +0000 Subject: [PATCH 517/601] File authors; one better lemma name --- .../Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean | 3 ++- .../Manifold/VectorBundle/CovariantDerivative/Torsion.lean | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 42f68d19513fdd..d9047c02e232e5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -810,7 +810,8 @@ lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : match_scalars <;> simp norm_num -lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := +lemma leviCivitaConnection_isLeviCivitaConnection [FiniteDimensional ℝ E] : + (LeviCivitaConnection I M).IsLeviCivitaConnection := ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_isTorsionFree I⟩ #exit diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 2327900eaa7c05..132f5f148b02e7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module From 1be81af62a0f4c28e79875993588fe6b05dc9e36 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 6 Mar 2026 12:28:19 +0100 Subject: [PATCH 518/601] =?UTF-8?q?Remove=20=CF=83=20from=20fields=20and?= =?UTF-8?q?=20lemma=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CovariantDerivative/Basic.lean | 144 ++++++------------ .../CovariantDerivative/Ehresmann.lean | 12 +- .../CovariantDerivative/LeviCivita.lean | 2 +- .../CovariantDerivative/Metric.lean | 4 +- .../CovariantDerivative/Torsion.lean | 2 +- .../CovariantDerivative/Trivial.lean | 4 +- .../Manifold/VectorBundle/Extend.lean | 4 +- 7 files changed, 61 insertions(+), 111 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 119f5fe0c59783..edc0135bf0a47b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -24,36 +24,36 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! -section any_field -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -- [FiniteDimensional 𝕜 E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] +/-! +## Local theory over any field -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] +In this section `M` is manifold over any nontrivially normed field `𝕜` and `V` is +a vector bundle over `M` with model fiber `F`. +-/ -variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -- `F` model fiber - (n : WithTop ℕ∞) +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] {V : M → Type*} [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] - [FiberBundle F V] --[VectorBundle 𝕜 F V] - -- `V` vector bundle + [FiberBundle F V] -structure IsCovariantDerivativeOn [IsManifold I 1 M] +/-- A function from sections of a vector bundle $V$ over a manifold $M$ to sections of $Hom(TM, E)$ +is a covariant derivative over a set $s$ in $M$ if it is additive and satisfies the Leibniz when +applied to sections that are differentiable at a point of $s$. -/ +structure IsCovariantDerivativeOn (f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (s : Set M := Set.univ) : Prop where - -- All the same axioms as CovariantDerivative, but restricted to the set s. - addσ {σ σ' : Π x : M, V x} {x} - (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) - (hx : x ∈ s := by trivial) : + add {σ σ' : Π x : M, V x} {x} + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : f (σ + σ') x = f σ x + f σ' x leibniz {σ : Π x : M, V x} {g : M → 𝕜} {x} - (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial): + (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial) : f (g • σ) x = g x • f σ x - + .toSpanSingleton 𝕜 (σ x) ∘L - (((fromTangentSpace (g x)).toContinuousLinearMap ∘L (mfderiv% g x))) + + .toSpanSingleton 𝕜 (σ x) ∘L (fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv% g x) /-- @@ -65,84 +65,52 @@ class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (u : Set M) where contMDiff : ∀ {σ : Π x : M, V x}, CMDiff[u] (k + 1) (T% σ) → - let f (x : M) : TotalSpace (E →L[𝕜] F) fun x ↦ TangentSpace I x →L[𝕜] V x := ⟨x, cov σ x⟩ + letI f (x : M) : TotalSpace (E →L[𝕜] F) fun x ↦ TangentSpace I x →L[𝕜] V x := ⟨x, cov σ x⟩ ContMDiffOn I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k f u - -- elaborators not working here, TODO investigate - -- ContMDiffOn I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k (T% (cov σ)) u - -- CMDiff[u] k f + -- TODO elaborators are not working here. We want to use `T% (cov σ)` and CMDiff[u] k f variable {F} namespace IsCovariantDerivativeOn -variable [IsManifold I 1 M] - -variable (E) in -/-- If `E` is the trivial vector space, [HM: i.e. the manifold is zero-dimensional??] -the axioms of a covariant derivative are vacuous. -/ -lemma of_subsingleton [hE : Subsingleton E] [TopologicalSpace (TotalSpace E V)] [FiberBundle E V] - (f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : - IsCovariantDerivativeOn E f Set.univ := by - have (Y) (x) : f Y x = 0 := by - have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - exact Subsingleton.eq_zero _ - exact { - addσ {σ σ' x} hσ hσ' hx := by simp [this] - leibniz {σ g x} hσ hg hx := by - have H : (mfderiv% g x) = 0 := - have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) - Subsingleton.eq_zero _ - simp [this, H] } - section changing_set /-! Changing set -In this changing we change `s` in `IsCovariantDerivativeOn F f s`. +In this section changing we change `s` in `IsCovariantDerivativeOn F f s`, proving the condition is +monotone and local. -/ lemma mono {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s t : Set M} (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where - addσ {_σ _σ' _x} hσ hσ' hx := hf.addσ hσ hσ' (hst hx) + add {_σ _σ' _x} hσ hσ' hx := hf.add hσ hσ' (hst hx) leibniz {_σ _f _x} hσ hf' hx := hf.leibniz hσ hf' (hst hx) lemma iUnion {ι : Type*} {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : ι → Set M} (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) : IsCovariantDerivativeOn F f (⋃ i, s i) where - addσ {_σ _σ' _x} hσ hσ' hx := by + add {_σ _σ' _x} hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).addσ hσ hσ' + exact (hf i).add hσ hσ' leibniz {σ f x} hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hf i).leibniz hσ hf' end changing_set -/- Congruence properties -/ -section - -lemma congr {f g : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} - (hf : IsCovariantDerivativeOn F f s) - -- Is this too strong? Will see! - (hfg : ∀ {σ : Π x : M, V x}, ∀ {x}, x ∈ s → f σ x = g σ x) : - IsCovariantDerivativeOn F g s where - addσ hσ hσ' hx := by simp [← hfg hx, hf.addσ hσ hσ'] - leibniz hσ hf' hx := by simp [← hfg hx, hf.leibniz hσ hf'] - -end section computational_properties variable {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} @[simp] -lemma zeroσ [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) +lemma zero [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) {x} (hx : x ∈ s := by trivial) : f 0 x = 0 := by - simpa using (hf.addσ (mdifferentiableAt_zeroSection ..) + simpa using (hf.add (mdifferentiableAt_zeroSection ..) (mdifferentiableAt_zeroSection ..) : f (0 + 0) x = _) -theorem smul_const_σ (hf : IsCovariantDerivativeOn F f s) +theorem smul_const (hf : IsCovariantDerivativeOn F f s) {σ : Π x : M, V x} {x} (a : 𝕜) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : f (a • σ) x = a • f σ x := by @@ -161,15 +129,15 @@ def affineCombination {f' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : IsCovariantDerivativeOn F (fun σ ↦ (g • (f σ)) + (1 - g) • (f' σ)) s where - addσ {_σ _σ' x} hσ hσ' hx := by - simp [hf.addσ hσ hσ', hf'.addσ hσ hσ'] + add {_σ _σ' x} hσ hσ' hx := by + simp [hf.add hσ hσ', hf'.add hσ hσ'] module leibniz {σ φ x} hσ hφ hx := by simp [hf.leibniz hσ hφ, hf'.leibniz hσ hφ] module /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination +lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) @@ -186,11 +154,11 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : IsCovariantDerivativeOn F (fun σ x ↦ ∑ i ∈ s, (f i x) • (cov i) σ x) u where - addσ {_σ _σ' _x} hσ hσ' hx := by + add {_σ _σ' _x} hσ hσ' hx := by rw [← Finset.sum_add_distrib] congr ext i - rw [← smul_add, (h i).addσ hσ hσ' hx] + rw [← smul_add, (h i).add hσ hσ' hx] leibniz {σ g x} hσ hg hx := by set B := (ContinuousLinearMap.toSpanSingleton 𝕜 (σ x) ∘L ((fromTangentSpace (g x)).toContinuousLinearMap ∘L (mfderiv% g x))) @@ -204,7 +172,7 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] _ = g x • ∑ i ∈ s, f i x • cov i σ x + B := by rw [hf]; simp /-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : ℕ∞} +lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' [IsManifold I 1 M] {n : ℕ∞} [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) @@ -220,8 +188,8 @@ variable {s : Set M} lemma add_one_form (hf : IsCovariantDerivativeOn F f s) (A : Π x : M, V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : IsCovariantDerivativeOn F (fun σ x ↦ f σ x + A x (σ x)) s where - addσ {_σ _σ' _x} hσ hσ' hx := by - simp [hf.addσ hσ hσ'] + add {_σ _σ' _x} hσ hσ' hx := by + simp [hf.add hσ hσ'] abel leibniz {σ g x} hσ hg hx := by simp [hf.leibniz hσ hg] @@ -236,7 +204,7 @@ end IsCovariantDerivativeOn variable (I F V) in /-- Caution: `cov Y x (X x)` corresponds to `∇ X Y` in textbooks! -/ @[ext] -structure CovariantDerivative [IsManifold I 1 M] where +structure CovariantDerivative where toFun : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) isCovariantDerivativeOn : IsCovariantDerivativeOn F toFun Set.univ @@ -244,8 +212,6 @@ namespace CovariantDerivative attribute [coe] toFun -variable [IsManifold I 1 M] - /-- Coercion of a `CovariantDerivative` to function -/ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := @@ -275,13 +241,13 @@ A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ -class ContMDiffCovariantDerivative [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) - (k : ℕ∞) where +class ContMDiffCovariantDerivative [IsManifold I 1 M] [VectorBundle 𝕜 F V] + (cov : CovariantDerivative I F V) (k : ℕ∞) where contMDiff : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ @[simp] -lemma contMDiffCovariantDerivativeOn_univ_iff [VectorBundle 𝕜 F V] {cov : CovariantDerivative I F V} - {k : ℕ∞} : +lemma contMDiffCovariantDerivativeOn_univ_iff [IsManifold I 1 M] [VectorBundle 𝕜 F V] + {cov : CovariantDerivative I F V} {k : ℕ∞} : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ ↔ ContMDiffCovariantDerivative cov k := ⟨fun h ↦ ⟨h⟩, fun h ↦ h.contMDiff⟩ @@ -291,9 +257,9 @@ lemma contMDiffCovariantDerivativeOn_univ_iff [VectorBundle 𝕜 F V] {cov : Cov section computational_properties @[simp] -lemma zeroσ [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 := by +lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 := by ext1 x - simp [cov.isCovariantDerivativeOn.zeroσ] + simp [cov.isCovariantDerivativeOn.zero] end computational_properties @@ -316,7 +282,7 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.affineCombination [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.affineCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : @@ -325,7 +291,7 @@ lemma ContMDiffCovariantDerivative.affineCombination [VectorBundle 𝕜 F V] ContMDiffCovariantDerivativeOn.affineCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff /-- An affine combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.affineCombination' [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.affineCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) @@ -355,22 +321,7 @@ theorem ext [IsManifold I 1 M] rw [← extend_apply_self (F := E) X₀] exact H (mdifferentiableAt_extend ..) --- lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] --- [FiniteDimensional 𝕜 E] --- [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] --- {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} --- {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) --- {σ : Π x : M, V x} --- (hσ : MDiffAt (T% σ) x) --- (f : SmoothBumpFunction I x) --- (hx : x ∈ u) : --- cov ((f : M → 𝕜) • σ) x = cov σ x := by --- have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) --- rw [hcov.leibniz hσ hf hx, f.eq_one, f.eventuallyEq_one.mfderiv_eq] --- rw [show mfderiv I 𝓘(𝕜, 𝕜) 1 x = 0 by apply mfderiv_const] --- simp - -lemma congr_σ_of_eqOn [IsManifold I 1 M] +lemma congr_of_eqOn [IsManifold I 1 M] {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {σ σ' : Π x : M, V x} @@ -421,7 +372,6 @@ noncomputable def differenceAux variable [CompleteSpace 𝕜] [IsManifold I 1 M] [FiniteDimensional 𝕜 F] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] variable @@ -436,7 +386,7 @@ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜 if hxs : x ∈ s then mkTensorAt I F (differenceAux cov cov') x (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) - (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.addσ hσ hσ', hcov'.addσ hσ hσ']; abel) + (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ']; abel) else 0 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 4660ec1de55bc6..17a6bed53a8347 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -143,7 +143,7 @@ lemma pushCovDer_ofSect [FiniteDimensional 𝕜 F] (hx : x ∈ e.baseSet := by assumption) : (e.pushCovDer cov) (fun x ↦ (e (σ x)).2) x X₀ = (e (cov σ x X₀)).2 := by have : cov (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov σ x := by - apply hcov.congr_σ_of_eqOn _ hσ (e.baseSet_mem_nhds hx) + apply hcov.congr_of_eqOn _ hσ (e.baseSet_mem_nhds hx) · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? · stop rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] @@ -163,7 +163,7 @@ lemma pushCovDer_isCovariantDerivativeOn {u : Set M} (hu : u ⊆ e.baseSet) (hcov : IsCovariantDerivativeOn F cov u) : IsCovariantDerivativeOn F (e.pushCovDer cov) u where - addσ {σ σ' x} hσ hσ' hx := by + add {σ σ' x} hσ hσ' hx := by set s := (fun x' ↦ e.symm x' (σ x')) have hs : MDiffAt (T% s) x := by sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| @@ -174,7 +174,7 @@ lemma pushCovDer_isCovariantDerivativeOn --mdifferentiableAt_section_trivial_iff.1 hσ' unfold Trivialization.pushCovDer stop - rw [← ContinuousLinearMap.comp_add, ← hcov.addσ hs hs' hx] + rw [← ContinuousLinearMap.comp_add, ← hcov.add hs hs' hx] congr ext y simp [e.symm_map_add 𝕜, s, s'] @@ -235,7 +235,7 @@ lemma coordChangeL_pushCovDer (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) have hσ : MDiffAt (T% σ) x := mdifferentiableAt_section_of_function e hx.1 hs - rw [hcov.congr_σ_of_eqOn hσ ?_ mem this] + rw [hcov.congr_of_eqOnhσ ?_ mem this] -- TODO have automatation doing the next three lines… apply mdifferentiableAt_section_of_function e' hx.2 have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 @@ -449,11 +449,11 @@ end real -- isCovariantDerivativeOn := -- { addX X X' σ x _ := by simp -- smulX X σ c' x _ := by simp --- addσ X σ σ' x hσ hσ' hx := by +-- add X σ σ' x hσ hσ' hx := by -- rw [Bundle.Trivial.mdifferentiableAt_iff] at hσ hσ' -- rw [fderiv_add hσ hσ'] -- rfl --- smul_const_σ X σ a x hx := by simp [fderiv_const_smul_of_field a] +-- smul_constX σ a x hx := by simp [fderiv_const_smul_of_field a] -- leibniz X σ f x hσ hf hx := by -- have : fderiv 𝕜 (f • σ) x = f x • fderiv 𝕜 σ x + (fderiv 𝕜 f x).smulRight (σ x) := -- fderiv_smul (by simp_all) (by simp_all) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index d9047c02e232e5..23e3f4eab047a5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -666,7 +666,7 @@ theorem lcAux_apply [FiniteDimensional ℝ E] {x : M} lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : IsCovariantDerivativeOn E (lcAux I (M := M)) where - addσ {Y Y'} x hY hY' _ := by + add {Y Y'} x hY hY' _ := by unfold lcAux rw [dif_pos hY, dif_pos hY', dif_pos (mdifferentiableAt_add_section hY hY')] unfold lcAux₁ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 8126d2e73ecc07..cdb60ff91adafe 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -231,7 +231,7 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] rw [product_add_left, mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), - cov.isCovariantDerivativeOn.addσ hσ hσ', + cov.isCovariantDerivativeOn.add hσ hσ', ContinuousLinearMap.comp_add] erw [ContinuousLinearMap.coe_sub'] rw [Pi.sub_apply] @@ -292,7 +292,7 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), - cov.isCovariantDerivativeOn.addσ hτ hτ'] + cov.isCovariantDerivativeOn.add hτ hτ'] dsimp rw [inner_add_right] erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 132f5f148b02e7..985a70c65cb24e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -64,7 +64,7 @@ variable (Y) in lemma torsionFun_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : torsionFun cov (X + X') Y x = torsionFun cov X Y x + torsionFun cov X' Y x := by - simp [torsionFun, hcov.addσ hX hX', VectorField.mlieBracket_add_left hX hX'] + simp [torsionFun, hcov.add hX hX', VectorField.mlieBracket_add_left hX hX'] module lemma torsionFun_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index c0d7ec0078c5f6..00df06fd6bdf68 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -44,7 +44,7 @@ variable (I M F) in noncomputable def trivial [IsManifold I 1 M] : IsCovariantDerivativeOn F (V := Trivial M F) (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where - addσ {σ σ' x} hσ hσ' hx := by + add {σ σ' x} hσ hσ' hx := by rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' rw [mfderiv_add hσ hσ'] leibniz {σ f x} hσ hf hx := by @@ -73,7 +73,7 @@ variable (I M F) in noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where toFun s x := mfderiv I 𝓘(𝕜, F) s x isCovariantDerivativeOn := -- TODO use previous work - { addσ {σ σ' x} hσ hσ' hx := by + { add {σ σ' x} hσ hσ' hx := by rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' rw [mfderiv_add hσ hσ'] leibniz {σ f x} hσ hf hx := by diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean index 71b861640c5736..cf2d9cf66b33ad 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean @@ -12,8 +12,8 @@ import Mathlib.Geometry.Manifold.Notation /-! # Locally extending an element of a vector bundle to a smooth section -Unlike the other `extend`, this construction doesn't use bump functions, just extends naively on a -trivialization's domain. +This construction doesn't use bump functions, it just extends naively on a trivialization's domain. +So it is smooth only locally -/ From 5e646a59e928f05654ee04fe358115600ed74eec Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 11:29:08 +0000 Subject: [PATCH 519/601] chore(Metric): better variable management --- .../CovariantDerivative/Metric.lean | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index cdb60ff91adafe..9f23efc68e0903 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -59,15 +59,14 @@ local notation "⟪" X ", " Y "⟫" => product I X Y section product omit [IsManifold I 2 M] - lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl -variable (X Y) in +variable (X X' Y) + lemma product_swap : ⟪Y, X⟫ = ⟪X, Y⟫ := by ext x apply real_inner_comm -variable (X) in @[simp] lemma product_zero_left : ⟪0, X⟫ = 0 := by ext x @@ -76,58 +75,46 @@ lemma product_zero_left : ⟪0, X⟫ = 0 := by @[simp] lemma product_zero_right : ⟪X, 0⟫ = 0 := by rw [product_swap, product_zero_left] -variable (X X' Y) in lemma product_add_left : ⟪X + X', Y⟫ = ⟪X, Y⟫ + ⟪X', Y⟫ := by ext x simp [product, InnerProductSpace.add_left] -variable (X X' Y) in @[simp] lemma product_add_left_apply (x) : ⟪X + X', Y⟫ x = ⟪X, Y⟫ x + ⟪X', Y⟫ x := by simp [product, InnerProductSpace.add_left] -variable (X Y Y') in lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] -variable (X X' Y) in @[simp] lemma product_add_right_apply (x) : ⟪X, Y + Y'⟫ x = ⟪X, Y⟫ x + ⟪X, Y'⟫ x := by rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left_apply] -variable (X Y) in @[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] -variable (X Y) in @[simp] lemma product_neg_right : ⟪X, -Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] -variable (X X' Y) in lemma product_sub_left : ⟪X - X', Y⟫ = ⟪X, Y⟫ - ⟪X', Y⟫ := by ext x simp [product, inner_sub_left] -variable (X Y Y') in lemma product_sub_right : ⟪X, Y - Y'⟫ = ⟪X, Y⟫ - ⟪X, Y'⟫ := by ext x simp [product, inner_sub_right] -variable (X Y) in lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by ext x simp [product, real_inner_smul_left] -variable (X Y) in @[simp] lemma product_smul_const_left (a : ℝ) : product I (a • X) Y = a • product I X Y := by ext x simp [product, real_inner_smul_left] -variable (X Y) in lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by ext x simp [product, real_inner_smul_right] -variable (X Y) in @[simp] lemma product_smul_const_right (a : ℝ) : product I X (a • Y) = a • product I X Y := by ext x From a080f6dc56598c55653271786fe66546d0cbca8a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 11:34:56 +0000 Subject: [PATCH 520/601] chore(Torsion): better variable management --- .../CovariantDerivative/Torsion.lean | 18 +++++++++++------- .../CovariantDerivative/Torsion2.lean | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 985a70c65cb24e..c9ab03a0e2075c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -60,7 +60,10 @@ namespace IsCovariantDerivativeOn variable [IsManifold I 2 M] {U : Set M} -variable (Y) in +section + +variable (Y) + lemma torsionFun_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : torsionFun cov (X + X') Y x = torsionFun cov X Y x + torsionFun cov X' Y x := by @@ -74,7 +77,6 @@ lemma torsionFun_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivative hcov.torsionFun_add_left_apply _ hX hX', torsionFun_antisymm Y, torsionFun_antisymm Y] simp; abel -variable (Y) in lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : torsionFun cov (f • X) Y x = f x • torsionFun cov X Y x := by @@ -95,12 +97,14 @@ lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative lemma torsionFun_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) - {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) (hx : x ∈ U := by trivial) : - torsionFun F X (f • Y) x = f x • torsionFun F X Y x := by - rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply X hf hX, + {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : + torsionFun F Y (f • X) x = f x • torsionFun F Y X x := by + rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply Y hf hX, torsionFun_antisymm X] simp +end + section variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] @@ -110,8 +114,8 @@ noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : mk2TensorAt I E E (Bundle.torsionFun cov) (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_left_apply τ hf hσ) (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionFun_add_left_apply τ hσ hσ') - (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_right_apply hf hτ) - (fun {_ _ _ _} ↦ hcov.torsionFun_add_right_apply) + (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_right_apply σ hf hτ) + (fun σ τ τ' hσ hτ hτ' ↦ hcov.torsionFun_add_right_apply σ hτ hτ') theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean index b61b44f08240f8..ab4ad9662c7ae8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean @@ -76,7 +76,7 @@ variable {cov : CovariantDerivative I E (TangentSpace I : M → Type _)} -- congr with i -- have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry -- have hsi' : MDiffAt (T% (s i)) x := sorry --- have := hf.torsion_smul_right_apply (X := X) (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' +-- have := hf.torsion_smul_right_apply X (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' -- erw [← this] -- congr -- From 381368e7d024808a90cb534342694aa91f0479b7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 11:40:15 +0000 Subject: [PATCH 521/601] chore: synchronise naming of apply lemmas between torsion and metric --- .../VectorBundle/CovariantDerivative/Metric.lean | 5 ++--- .../CovariantDerivative/Torsion.lean | 16 +++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 9f23efc68e0903..6804541ff6d245 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -329,8 +329,7 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) simp [product, real_inner_comm, fromTangentSpace] variable {I} in --- TODO: make naming consistent with `torsion` (which uses `vector_field_apply` and `apply` instead) -theorem metricTensor_apply' [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : +theorem metricTensor_apply_extend [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : MetricTensor cov x Y₀ Z₀ X₀ = fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x @@ -365,7 +364,7 @@ lemma isCompatible_iff [FiniteDimensional ℝ E] : refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ unfold IsCompatible ext x X₀ Y₀ Z₀ - rw [metricTensor_apply', sub_sub, sub_eq_iff_eq_add'] + rw [metricTensor_apply_extend, sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] convert h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I E Y₀) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index c9ab03a0e2075c..7160f3c5b31cb4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -162,18 +162,16 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- The torsion tensor of a covariant derivative on the tangent bundle of a manifold. -/ noncomputable def torsion := cov.isCovariantDerivativeOn.torsion --- TODO: decide on a good naming scheme; `vector_field_apply` and `apply` or perhaps --- `apply` and `apply_extend`? And synchronise with the compatibility file. -lemma torsion_vector_field_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : +lemma torsion_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : cov.torsion x (X x) (Y x) = cov Y x (X x) - cov X x (Y x) - mlieBracket I X Y x := by unfold torsion IsCovariantDerivativeOn.torsion apply mk2TensorAt_apply exacts [hX, hY] -lemma torsion_apply (u v : TangentSpace I x) : - cov.torsion x u v = cov (extend E v) x (extend E u x) - - cov (extend E u) x (extend E v x) - - mlieBracket I (extend E u) (extend E v) x := by +lemma torsion_apply_extend (u v : TangentSpace I x) : + cov.torsion x u v = + cov (extend E v) x (extend E u x) - cov (extend E u) x (extend E v x) + - mlieBracket I (extend E u) (extend E v) x := by unfold torsion IsCovariantDerivativeOn.torsion apply mk2TensorAt_apply_eq_extend @@ -187,11 +185,11 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ constructor · intro h X Y x hX hY replace h := congr($h x (X x) (Y x)) - rw [cov.torsion_vector_field_apply hX hY] at h + rw [cov.torsion_apply hX hY] at h simpa [sub_eq_iff_eq_add'] using h · intro h ext x u v - rw [torsion_apply, h] + rw [torsion_apply_extend, h] · simp · apply mdifferentiableAt_extend · apply mdifferentiableAt_extend From a1b6dc9be546e815ff924167beacdc86f3b1e6e6 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 11:45:41 +0000 Subject: [PATCH 522/601] chore: add module doc-string (and minor tweaks) --- .../CovariantDerivative/Torsion.lean | 50 ++++++------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 7160f3c5b31cb4..6af7e12b2f3494 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -8,14 +8,20 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorField.LieBracket -/-! -# Torsion of a covariant derivative +/-! # Torsion of a covariant derivative -- define torsion of a covariant derivative (and its local version) -- torsion-free ness (local and global version) -- prove: torsion-freeness on `s` can be checked using a local frame on `s` +We define the torsion tensor of a covariant derivative on the tangent bundle `TM` of some +manifold `M` and derive a criterion for torsion-freeness. -TODO: add a more complete doc-string +## Main definitions and results + +* `Bundle.torsionFun`: the torsion of a covariant derivative on the tangent bundle `TM`, + as a bare function. Prefer to use `torsion` instead. +* `IsCovariantDerivativeOn.torsion`: the torsion tensor of an unbundled covariant derivative + on `TM` on some set `s ⊆ M` +* `CovariantDerivative.torsion`: the torsion tensor of a bundled covariant derivative on `TM` +* `CovariantDerivative.IsTorsionFree`: predicate for a bundled covariant derivative `∇` + to be torsion-free: `∇` is torsion free if and only if its torsion tensor vanishes -/ @@ -32,8 +38,8 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] --- TODO: where is a good namespace for this? -/-- The torsion of a covariant derivative on the tangent bundle `TM` -/ +/-- The torsion of a covariant derivative on the tangent bundle `TM`, as a bare function. +Prefer to use `torsion` (which is a two-tensor) instead. -/ noncomputable def Bundle.torsionFun (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := @@ -126,37 +132,11 @@ theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} end end IsCovariantDerivativeOn --- /-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ --- noncomputable def IsTorsionFreeOn --- (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) --- (U : Set M) : Prop := --- ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, torsionFun cov X Y x = 0 --- --- namespace IsTorsionFreeOn --- --- section changing_set --- --- /-! Changing set --- In this changing we change `s` in `IsTorsionFreeOn F f s`. --- -/ --- --- lemma mono {s t : Set M} (hf : IsTorsionFreeOn cov t) (hst : s ⊆ t) : IsTorsionFreeOn cov s := --- fun _ hx _ _ ↦ hf _ (hst hx) .. --- --- lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn cov (s i)) : --- IsTorsionFreeOn cov (⋃ i, s i) := by --- rintro x ⟨si, ⟨i, hi⟩, hxsi⟩ X Y --- exact hf i x (by simp [hi, hxsi]) X Y --- --- end changing_set --- --- end IsTorsionFreeOn namespace CovariantDerivative open VectorField -variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] -variable [IsManifold I 2 M] +variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] [IsManifold I 2 M] variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- The torsion tensor of a covariant derivative on the tangent bundle of a manifold. -/ From 8e7fc4edf543717eefc5ea7a85ae1a32a3e25c4b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 11:55:36 +0000 Subject: [PATCH 523/601] chore(Torsion): more auxiliary name for torsionFun --- .../CovariantDerivative/Torsion.lean | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 6af7e12b2f3494..7764e801c29563 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -15,8 +15,6 @@ manifold `M` and derive a criterion for torsion-freeness. ## Main definitions and results -* `Bundle.torsionFun`: the torsion of a covariant derivative on the tangent bundle `TM`, - as a bare function. Prefer to use `torsion` instead. * `IsCovariantDerivativeOn.torsion`: the torsion tensor of an unbundled covariant derivative on `TM` on some set `s ⊆ M` * `CovariantDerivative.torsion`: the torsion tensor of a bundled covariant derivative on `TM` @@ -38,9 +36,11 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] +namespace IsCovariantDerivativeOn + /-- The torsion of a covariant derivative on the tangent bundle `TM`, as a bare function. Prefer to use `torsion` (which is a two-tensor) instead. -/ -noncomputable def Bundle.torsionFun +noncomputable def torsionAux (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := fun X Y x ↦ cov Y x (X x) - cov X x (Y x) - VectorField.mlieBracket I X Y x @@ -50,43 +50,41 @@ variable {X X' Y : Π x : M, TangentSpace I x} variable (f X) in -lemma torsionFun_self : torsionFun cov X X = 0 := by +lemma torsionAux_self : IsCovariantDerivativeOn.torsionAux cov X X = 0 := by ext - simp [torsionFun] + simp [torsionAux] variable (X Y) in -lemma torsionFun_antisymm : torsionFun cov X Y = - torsionFun cov Y X := by +lemma torsionAux_antisymm : torsionAux cov X Y = - torsionAux cov Y X := by ext x - unfold torsionFun + unfold torsionAux rw [VectorField.mlieBracket_swap] dsimp module -namespace IsCovariantDerivativeOn - variable [IsManifold I 2 M] {U : Set M} section variable (Y) -lemma torsionFun_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) +lemma torsionAux_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : - torsionFun cov (X + X') Y x = torsionFun cov X Y x + torsionFun cov X' Y x := by - simp [torsionFun, hcov.add hX hX', VectorField.mlieBracket_add_left hX hX'] + torsionAux cov (X + X') Y x = torsionAux cov X Y x + torsionAux cov X' Y x := by + simp [torsionAux, hcov.add hX hX', VectorField.mlieBracket_add_left hX hX'] module -lemma torsionFun_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) +lemma torsionAux_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : - torsionFun cov Y (X + X') x = torsionFun cov Y X x + torsionFun cov Y X' x := by - rw [torsionFun_antisymm, Pi.neg_apply, - hcov.torsionFun_add_left_apply _ hX hX', torsionFun_antisymm Y, torsionFun_antisymm Y] + torsionAux cov Y (X + X') x = torsionAux cov Y X x + torsionAux cov Y X' x := by + rw [torsionAux_antisymm, Pi.neg_apply, + hcov.torsionAux_add_left_apply _ hX hX', torsionAux_antisymm Y, torsionAux_antisymm Y] simp; abel -lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) +lemma torsionAux_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : - torsionFun cov (f • X) Y x = f x • torsionFun cov X Y x := by - simp only [torsionFun] + torsionAux cov (f • X) Y x = f x • torsionAux cov X Y x := by + simp only [torsionAux] rw [hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] simp? [smul_sub] says simp only [Pi.smul_apply', map_smul, ContinuousLinearMap.add_apply, @@ -100,13 +98,13 @@ lemma torsionFun_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative change B - (A + (fromTangentSpace _ D) • X x) - (-(fromTangentSpace _ D) • X x + C) = B - A - C module -lemma torsionFun_smul_right_apply [CompleteSpace E] +lemma torsionAux_smul_right_apply [CompleteSpace E] {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} (hF : IsCovariantDerivativeOn E F U) {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : - torsionFun F Y (f • X) x = f x • torsionFun F Y X x := by - rw [torsionFun_antisymm, Pi.neg_apply, hF.torsionFun_smul_left_apply Y hf hX, - torsionFun_antisymm X] + torsionAux F Y (f • X) x = f x • torsionAux F Y X x := by + rw [torsionAux_antisymm, Pi.neg_apply, hF.torsionAux_smul_left_apply Y hf hX, + torsionAux_antisymm X] simp end @@ -117,16 +115,16 @@ variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := - mk2TensorAt I E E (Bundle.torsionFun cov) - (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_left_apply τ hf hσ) - (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionFun_add_left_apply τ hσ hσ') - (fun f σ τ hf hσ hτ ↦ hcov.torsionFun_smul_right_apply σ hf hτ) - (fun σ τ τ' hσ hτ hτ' ↦ hcov.torsionFun_add_right_apply σ hτ hτ') + mk2TensorAt I E E (torsionAux cov) + (fun f σ τ hf hσ hτ ↦ hcov.torsionAux_smul_left_apply τ hf hσ) + (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionAux_add_left_apply τ hσ hσ') + (fun f σ τ hf hσ hτ ↦ hcov.torsionAux_smul_right_apply σ hf hτ) + (fun σ τ τ' hσ hτ hτ' ↦ hcov.torsionAux_add_right_apply σ hτ hτ') theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : - torsion hcov x (X x) (Y x) = Bundle.torsionFun cov X Y x := + torsion hcov x (X x) (Y x) = torsionAux cov X Y x := mk2TensorAt_apply _ _ _ _ _ _ hX hY end @@ -136,6 +134,10 @@ end IsCovariantDerivativeOn namespace CovariantDerivative open VectorField +variable + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)} + {X X' Y : Π x : M, TangentSpace I x} + variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] [IsManifold I 2 M] variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) From af5b730546d52754eb676e7cbe7c110150828e7f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 11:57:58 +0000 Subject: [PATCH 524/601] chore(Metric): add detailed module doc-string Rename metricTensorFun to metricTensorAux as it's an implementation detail; rename MetricTensor to metricTensor to match the naming convention. --- .../CovariantDerivative/Metric.lean | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 6804541ff6d245..98f889974ad7a6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -11,25 +11,37 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian /-! # Metric connections This file defines connections on a Riemannian manifold which are compatible with the ambient metric. - -TODO extend this doc-string! - - -TODO: more generally, define a notion of metric connections (e.g., those whose parallel transport -is an isometry) and prove the Levi-Civita connection is a metric connection +A bundled connection `∇` on `(M, g)` is compatible with the metric `g` if and only if the metric +tensor `∇ g` (defined by `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)`) +vanishes on all differentiable vector fields. + +## Main definitions and results + +* `CovariantDerivative.metricTensor`: the tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` + defining when a connection `∇` on a Riemannian manifold `(M, g)` is compatible with the metric + `g`. +* `CovariantDerivative.metricTensor_apply` and `CovariantDerivative.metricTensor_apply` give + formulas for applying the metric tensor at `x` to vector fields which are differentiable at `x`, + resp. to extensions of tangent vectors at `x` to differentiable vector fields near `x`. +* `CovariantDerivative.IsCompatible`: predicate for a connection to be metric + `∇` is metric iff its `metricTensor` vanishes + +## TODO +* when mathlib has a notion of parallel transport, define metric connections on general + Riemannian bundles (characterised by parallel transport being an isometry) and prove the + equivalence to this definition -/ open Bundle Filter Function Module NormedSpace Topology - -open scoped Bundle Manifold ContDiff +open scoped Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! -- TODO: revisit and fix this once the dust has settled set_option backward.isDefEq.respectTransparency false --- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. +-- Let `M` be a `C^k` real manifold modeled on `(E, H)`, endowed with a Riemannian metric. variable {n : WithTop ℕ∞} {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) @@ -141,14 +153,14 @@ lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : product I X Y x = product I X Y' x + product I X Y'' x := by rw [product_apply, h, inner_add_right, ← product_apply] -/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` +/- TODO: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` yields an error synthesized type class instance is not definitionally equal to expression inferred by typing rules, synthesized fun x ↦ instNormedAddCommGroupOfRiemannianBundle x inferred - fun b ↦ inst✝⁷ -/ --- TODO: diagnose and fix this, and replace by `MDifferentiable(At).inner_bundle! + fun b ↦ inst✝⁷ +Diagnose and fix this, and then replace the below by `MDifferentiable(At).inner_bundle! -/ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := @@ -168,8 +180,9 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) -/-- The function defining the metric or compatibility tensor `∇ g` -/ -noncomputable def metricTensorFun (Y Z : Π x : M, TangentSpace I x) : +/-- The function defining the metric or compatibility tensor `∇ g`: +prefer using `metricTensor` instead -/ +noncomputable def metricTensorAux (Y Z : Π x : M, TangentSpace I x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) @@ -179,8 +192,8 @@ variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] variable {I} in private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - metricTensorFun I cov (f • σ) τ x = f x • metricTensorFun I cov σ τ x := by - unfold metricTensorFun + metricTensorAux I cov (f • σ) τ x = f x • metricTensorAux I cov σ τ x := by + unfold metricTensorAux rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] ext X simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, @@ -210,9 +223,9 @@ private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x variable {I} in private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : - metricTensorFun I cov (σ + σ') τ x = - metricTensorFun I cov σ τ x + metricTensorFun I cov σ' τ x := by - simp only [metricTensorFun] + metricTensorAux I cov (σ + σ') τ x = + metricTensorAux I cov σ τ x + metricTensorAux I cov σ' τ x := by + simp only [metricTensorAux] ext X simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] @@ -238,8 +251,8 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) variable {I} in private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - metricTensorFun I cov σ (f • τ) x = f x • metricTensorFun I cov σ τ x := by - unfold metricTensorFun + metricTensorAux I cov σ (f • τ) x = f x • metricTensorAux I cov σ τ x := by + unfold metricTensorAux rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] ext X simp only [smul_eq_mul, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, @@ -271,9 +284,9 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x variable {I} in private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : - metricTensorFun I cov σ (τ + τ') x = - metricTensorFun I cov σ τ x + metricTensorFun I cov σ τ' x := by - unfold metricTensorFun + metricTensorAux I cov σ (τ + τ') x = + metricTensorAux I cov σ τ x + metricTensorAux I cov σ τ' x := by + unfold metricTensorAux ext X simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, @@ -301,24 +314,24 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) -- set D := (cov σ x) X variable {I} in -/-- The tensor `∇ g` defined by a connection `∇` on a Riemannian manifold `(M, g)`. -/ -@[no_expose] noncomputable def MetricTensor [FiniteDimensional ℝ E] (x : M) : +/-- The tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection +`∇` on a Riemannian manifold `(M, g)` is compatible with the metric `g`. -/ +@[no_expose] noncomputable def metricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - mk2TensorAt I E E (metricTensorFun I cov) + mk2TensorAt I E E (metricTensorAux I cov) (fun _f _σ _τ hf hσ hτ ↦ aux1 cov hf hσ hτ) (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') --- TODO: should we have ∇ X Y and ∇ X Z instead? variable {I} in theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - MetricTensor cov x (Y x) (Z x) (X x) = + metricTensor cov x (Y x) (Z x) (X x) = fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by - unfold MetricTensor + unfold metricTensor rw [mk2TensorAt_apply _ _ _ _ _ _ hY hZ] - simp only [metricTensorFun, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', + simp only [metricTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] conv => enter [1, 1] @@ -330,7 +343,7 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) variable {I} in theorem metricTensor_apply_extend [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : - MetricTensor cov x Y₀ Z₀ X₀ = + metricTensor cov x Y₀ Z₀ X₀ = fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x - ⟪extend E Y₀, ∇ extend E Z₀, (extend E X₀)⟫ x := by @@ -340,7 +353,7 @@ theorem metricTensor_apply_extend [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z /-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ -def IsCompatible [FiniteDimensional ℝ E] : Prop := MetricTensor cov = 0 +def IsCompatible [FiniteDimensional ℝ E] : Prop := metricTensor cov = 0 -- Auxiliary computation for `IsCompatible_apply`. -- TODO: inlining this lemma does not work @@ -352,7 +365,7 @@ lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by rw [IsCompatible] at hcov - have : MetricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] + have : metricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] rw [metricTensor_apply cov x hY hZ] at this change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ exact isCompatible_apply_aux this From 05b909b25a5d14bb76565567d8b2425c97584037 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 6 Mar 2026 13:26:23 +0100 Subject: [PATCH 525/601] CovariantDerivative.Basic cleanup --- .../CovariantDerivative/Basic.lean | 338 +++++++++--------- .../CovariantDerivative/LeviCivita.lean | 4 +- .../CovariantDerivative/Trivial.lean | 6 +- 3 files changed, 171 insertions(+), 177 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index edc0135bf0a47b..364498d0111e39 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -15,6 +15,8 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators TODO: add a more complete doc-string +In the whole file `M` is manifold over any nontrivially normed field `𝕜` and `V` is +a vector bundle over `M` with model fiber `F`. -/ open Bundle Filter Module Topology Set NormedSpace @@ -25,10 +27,8 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! /-! -## Local theory over any field +## Local unbundled theory -In this section `M` is manifold over any nontrivially normed field `𝕜` and `V` is -a vector bundle over `M` with model fiber `F`. -/ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] @@ -45,17 +45,16 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] is a covariant derivative over a set $s$ in $M$ if it is additive and satisfies the Leibniz when applied to sections that are differentiable at a point of $s$. -/ structure IsCovariantDerivativeOn - (f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) + (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (s : Set M := Set.univ) : Prop where add {σ σ' : Π x : M, V x} {x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : - f (σ + σ') x = f σ x + f σ' x + cov (σ + σ') x = cov σ x + cov σ' x leibniz {σ : Π x : M, V x} {g : M → 𝕜} {x} (hσ : MDiffAt (T% σ) x) (hg : MDiffAt g x) (hx : x ∈ s := by trivial) : - f (g • σ) x = g x • f σ x + cov (g • σ) x = g x • cov σ x + .toSpanSingleton 𝕜 (σ x) ∘L (fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv% g x) - /-- A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. @@ -65,75 +64,132 @@ class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (u : Set M) where contMDiff : ∀ {σ : Π x : M, V x}, CMDiff[u] (k + 1) (T% σ) → - letI f (x : M) : TotalSpace (E →L[𝕜] F) fun x ↦ TangentSpace I x →L[𝕜] V x := ⟨x, cov σ x⟩ - ContMDiffOn I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k f u - -- TODO elaborators are not working here. We want to use `T% (cov σ)` and CMDiff[u] k f + letI cov (x : M) : TotalSpace (E →L[𝕜] F) fun x ↦ TangentSpace I x →L[𝕜] V x := ⟨x, cov σ x⟩ + ContMDiffOn I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k cov u + -- TODO elaborators are not working here. We want to use `T% (cov σ)` and CMDiff[u] k f variable {F} namespace IsCovariantDerivativeOn +-- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x +-- this should be easy using the projection formula in `CovariantDerivative.Ehresmann`. +-- In the mean time we use the following weaker result (which is convenient to apply anyway). + +/-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and + `σ'` agree at `x` and are differentiable there, then `cov σ x = cov σ x'`. -/ +lemma congr_of_eqOn + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + {σ σ' : Π x : M, V x} {x : M} + (hσ : MDiffAt (T% σ) x) + (hσ' : MDiffAt (T% σ') x) + (hxs : s ∈ 𝓝 x) + (hσσ' : ∀ x ∈ s, σ x = σ' x) : + cov σ x = cov σ' x := by + classical + have hxs' : x ∈ s := mem_of_mem_nhds hxs + let ψ (x' : M) : 𝕜 := if x' ∈ s then 1 else 0 + have hψx : ψ x = 1 := by simp [ψ, hxs'] + -- Observe that `ψ • σ = ψ • σ'` as dependent functions. + have H (x' : M) : ((ψ : M → 𝕜) • σ) x' = ((ψ : M → 𝕜) • σ') x' := by + dsimp [ψ] + split_ifs with hx's + · simpa using hσσ' _ hx's + · simp + have hψ' : HasMFDerivAt I 𝓘(𝕜) ψ x 0 := by + have : HasMFDerivAt I 𝓘(𝕜, 𝕜) (fun (_x : M) ↦ (1 : 𝕜)) x 0 := hasMFDerivAt_const .. + refine this.congr_of_eventuallyEq ?_ + apply Filter.eventuallyEq_of_mem hxs + intro t ht + simp [ψ, ht] + have := hcov.leibniz hσ hψ'.mdifferentiableAt + -- Then, it's a chain of (dependent) equalities. + calc cov σ x + _ = cov ((ψ : M → 𝕜) • σ) x := by + rw [hcov.leibniz hσ hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] + erw [ContinuousLinearMap.comp_zero] + simp + _ = cov ((ψ : M → 𝕜) • σ') x := by rw [funext H] + _ = cov σ' x := by + rw [hcov.leibniz hσ' hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] + erw [ContinuousLinearMap.comp_zero] + simp + section changing_set -/-! Changing set +/-! ### Changing set -In this section changing we change `s` in `IsCovariantDerivativeOn F f s`, proving the condition is +In this section, we change `s` in `IsCovariantDerivativeOn F cov s`, proving the condition is monotone and local. - -/ + lemma mono - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s t : Set M} - (hf : IsCovariantDerivativeOn F f t) (hst : s ⊆ t) : IsCovariantDerivativeOn F f s where - add {_σ _σ' _x} hσ hσ' hx := hf.add hσ hσ' (hst hx) - leibniz {_σ _f _x} hσ hf' hx := hf.leibniz hσ hf' (hst hx) - -lemma iUnion {ι : Type*} - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : ι → Set M} - (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) : IsCovariantDerivativeOn F f (⋃ i, s i) where + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s t : Set M} + (hcov : IsCovariantDerivativeOn F cov t) (hst : s ⊆ t) : IsCovariantDerivativeOn F cov s where + add {_σ _σ' _x} hσ hσ' hx := hcov.add hσ hσ' (hst hx) + leibniz {_σ _cov _x} hσ hcov' hx := hcov.leibniz hσ hcov' (hst hx) + +lemma iUnion {ι : Type*} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + {s : ι → Set M} (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) : + IsCovariantDerivativeOn F cov (⋃ i, s i) where add {_σ _σ' _x} hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).add hσ hσ' + exact (hcov i).add hσ hσ' leibniz {σ f x} hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx - exact (hf i).leibniz hσ hf' + exact (hcov i).leibniz hσ hf' end changing_set section computational_properties +/-! ### Computation properties -/ -variable {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} +variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} @[simp] -lemma zero [VectorBundle 𝕜 F V] (hf : IsCovariantDerivativeOn F f s) +lemma zero [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) {x} (hx : x ∈ s := by trivial) : - f 0 x = 0 := by - simpa using (hf.add (mdifferentiableAt_zeroSection ..) - (mdifferentiableAt_zeroSection ..) : f (0 + 0) x = _) + cov 0 x = 0 := by + simpa using (hcov.add (mdifferentiableAt_zeroSection ..) + (mdifferentiableAt_zeroSection ..) : cov (0 + 0) x = _) -theorem smul_const (hf : IsCovariantDerivativeOn F f s) +theorem smul_const (hcov : IsCovariantDerivativeOn F cov s) {σ : Π x : M, V x} {x} (a : 𝕜) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - f (a • σ) x = a • f σ x := by - simpa using hf.leibniz (g := fun _ ↦ a) hσ mdifferentiableAt_const + cov (a • σ) x = a • cov σ x := by + simpa using hcov.leibniz (g := fun _ ↦ a) hσ mdifferentiableAt_const end computational_properties section operations -variable {s : Set M} - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} +/-! ### Operations + +In this section we prove that: + +* affine combinations of covariant derivatives are covariant derivatives +* adding a one form taking values into endomorphisms of the vector bundle to a covariant + derivative gives a covariant derivative. See `add_on_form`. +* subtracting two covariant derivatives on some set gives a one form taking values into + endomorphisms of the vector bundle. See `difference`. + +Note: morally this means covariant derivatives form an affine space over the vector space of +one-forms taking values in endomorphisms of the bundle, but we don’t package it that way yet. +-/ +variable {s : Set M} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} /-- An affine combination of covariant derivatives is a covariant derivative. -/ @[simps] -def affineCombination - {f' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M → 𝕜) : - IsCovariantDerivativeOn F (fun σ ↦ (g • (f σ)) + (1 - g) • (f' σ)) s where +def affineCombination (hcov : IsCovariantDerivativeOn F cov s) + {cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + (hcov' : IsCovariantDerivativeOn F cov' s) (g : M → 𝕜) : + IsCovariantDerivativeOn F (fun σ ↦ (g • (cov σ)) + (1 - g) • (cov' σ)) s where add {_σ _σ' x} hσ hσ' hx := by - simp [hf.add hσ hσ', hf'.add hσ hσ'] + simp [hcov.add hσ hσ', hcov'.add hσ hσ'] module leibniz {σ φ x} hσ hφ hx := by - simp [hf.leibniz hσ hφ, hf'.leibniz hσ hφ] + simp [hcov.leibniz hσ hφ, hcov'.leibniz hσ hφ] module /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ @@ -182,31 +238,74 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' [IsManifold I 1 M simpa using ContMDiffOn.sum_section (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ) -variable {s : Set M} - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - -lemma add_one_form (hf : IsCovariantDerivativeOn F f s) +/-- Adding a one form taking values into endomorphisms of the vector bundle to a covariant + derivative gives a covariant derivative. -/ +lemma add_one_form (hcov : IsCovariantDerivativeOn F cov s) (A : Π x : M, V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : - IsCovariantDerivativeOn F (fun σ x ↦ f σ x + A x (σ x)) s where + IsCovariantDerivativeOn F (fun σ x ↦ cov σ x + A x (σ x)) s where add {_σ _σ' _x} hσ hσ' hx := by - simp [hf.add hσ hσ'] + simp [hcov.add hσ hσ'] abel leibniz {σ g x} hσ hg hx := by - simp [hf.leibniz hσ hg] + simp [hcov.leibniz hσ hg] module +section difference + +/-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(V) → Γ(V)`. +Future lemmas will upgrade this to a one-forme taking values in endomorphisms of `V`. -/ +noncomputable def differenceAux + (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : + (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := + fun σ ↦ cov σ - cov' σ + +-- We need more assumptions to use the tensoriality criterion in order to build the difference +-- operation. +variable [CompleteSpace 𝕜] + [IsManifold I 1 M] + [FiniteDimensional 𝕜 F] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + +variable + {cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) + +open scoped Classical in +/-- The difference of two covariant derivatives, as a tensorial map. -/ +noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := + if hxs : x ∈ s then + mkTensorAt I F (differenceAux cov cov') x + (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) + (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ']; abel) + else + 0 + +@[simp] +lemma difference_apply {x : M} (hx : x ∈ s := by trivial) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : + difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by + simp only [difference, hx, reduceDIte] + rw [mkTensorAt_apply _ _ _ hσ] + rfl + +end difference + end operations end IsCovariantDerivativeOn -/-! Bundled global covariant derivatives -/ +/-! ## Bundled global covariant derivatives -/ variable (I F V) in -/-- Caution: `cov Y x (X x)` corresponds to `∇ X Y` in textbooks! -/ +/-- +Bundled global covariant derivative on a vector bundle. +Caution: the argument order is slightly tricky: `cov Y x (X x)` corresponds to `∇ X Y x` on paper. +-/ @[ext] structure CovariantDerivative where toFun : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) - isCovariantDerivativeOn : IsCovariantDerivativeOn F toFun Set.univ + isCovariantDerivativeOnUniv : IsCovariantDerivativeOn F toFun Set.univ namespace CovariantDerivative @@ -217,24 +316,28 @@ instance : CoeFun (CovariantDerivative I F V) fun _ ↦ (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := ⟨fun e ↦ e.toFun⟩ -instance (cov : CovariantDerivative I F V) {s : Set M} : - IsCovariantDerivativeOn F cov s := by - apply cov.isCovariantDerivativeOn.mono (fun ⦃a⦄ a ↦ trivial) +lemma isCovariantDerivativeOn (cov : CovariantDerivative I F V) {s : Set M} : + IsCovariantDerivativeOn F cov s := + cov.isCovariantDerivativeOnUniv.mono (fun _ _ ↦ trivial) -/-- If `f : Vec(M) × Γ(E) → Vec(M)` is a covariant derivative on each set in an open cover, +@[simp] +lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 := by + ext1 x + simp [cov.isCovariantDerivativeOnUniv.zero] + +/-- If `f : Vec(M) × Γ(V) → Vec(M)` is a covariant derivative on each set in an open cover, it is a covariant derivative. -/ def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) (hs : ⋃ i, s i = Set.univ) : + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) (hs : ⋃ i, s i = Set.univ) : CovariantDerivative I F V := - ⟨f, hs ▸ IsCovariantDerivativeOn.iUnion hf⟩ + ⟨cov, hs ▸ IsCovariantDerivativeOn.iUnion hcov⟩ @[simp] lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set M} - {f : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - (hf : ∀ i, IsCovariantDerivativeOn F f (s i)) (hs : ⋃ i, s i = Set.univ) : - of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl - + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) (hs : ⋃ i, s i = Set.univ) : + of_isCovariantDerivativeOn_of_open_cover hcov hs = cov := rfl /-- A covariant derivative ∇ is called of class `C^k` iff, @@ -251,18 +354,6 @@ lemma contMDiffCovariantDerivativeOn_univ_iff [IsManifold I 1 M] [VectorBundle ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ ↔ ContMDiffCovariantDerivative cov k := ⟨fun h ↦ ⟨h⟩, fun h ↦ h.contMDiff⟩ --- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection --- is of class C^k (up to off-by-one errors) - -section computational_properties - -@[simp] -lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 := by - ext1 x - simp [cov.isCovariantDerivativeOn.zero] - -end computational_properties - section operations /-- An affine combination of covariant derivatives is a covariant derivative. -/ @@ -270,7 +361,7 @@ section operations def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : CovariantDerivative I F V where toFun := fun σ ↦ (g • (cov σ)) + (1 - g) • (cov' σ) - isCovariantDerivativeOn := + isCovariantDerivativeOnUniv := cov.isCovariantDerivativeOn.affineCombination cov'.isCovariantDerivativeOn _ /-- A finite affine combination of covariant derivatives is a covariant derivative. -/ @@ -278,7 +369,7 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where toFun t x := ∑ i ∈ s, (f i x) • (cov i) t x - isCovariantDerivativeOn := IsCovariantDerivativeOn.affineCombination' + isCovariantDerivativeOnUniv := IsCovariantDerivativeOn.affineCombination' (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ @@ -301,108 +392,11 @@ lemma ContMDiffCovariantDerivative.affineCombination' [IsManifold I 1 M] [Vector ContMDiffCovariantDerivativeOn.affineCombination' (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) --- Future: prove a version with a locally finite sum, and deduce that C^k connections always +-- TODO: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) end operations end CovariantDerivative -variable {x : M} -namespace IsCovariantDerivativeOn - -omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -theorem ext [IsManifold I 1 M] - {P P' : (Π x : M, TangentSpace I x →L[𝕜] V x)} {x} - (H : ∀ {X : Π x : M, TangentSpace I x}, MDiffAt (T% X) x → P x (X x) = P' x (X x)) : - P x = P' x := by - ext X₀ - rw [← extend_apply_self (F := E) X₀] - exact H (mdifferentiableAt_extend ..) - -lemma congr_of_eqOn [IsManifold I 1 M] - {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) - {σ σ' : Π x : M, V x} - (hσ : MDiffAt (T% σ) x) - (hσ' : MDiffAt (T% σ') x) - (hxs : s ∈ 𝓝 x) - (hσσ' : ∀ x ∈ s, σ x = σ' x) : - cov σ x = cov σ' x := by - classical - have hxs' : x ∈ s := mem_of_mem_nhds hxs - let ψ (x' : M) : 𝕜 := if x' ∈ s then 1 else 0 - have hψx : ψ x = 1 := by simp [ψ, hxs'] - -- Observe that `ψ • σ = ψ • σ'` as dependent functions. - have H (x' : M) : ((ψ : M → 𝕜) • σ) x' = ((ψ : M → 𝕜) • σ') x' := by - dsimp [ψ] - split_ifs with hx's - · simpa using hσσ' _ hx's - · simp - have hψ' : HasMFDerivAt I 𝓘(𝕜) ψ x 0 := by - have : HasMFDerivAt I 𝓘(𝕜, 𝕜) (fun (_x : M) ↦ (1 : 𝕜)) x 0 := hasMFDerivAt_const .. - refine this.congr_of_eventuallyEq ?_ - apply Filter.eventuallyEq_of_mem hxs - intro t ht - simp [ψ, ht] - have := hcov.leibniz hσ hψ'.mdifferentiableAt - -- Then, it's a chain of (dependent) equalities. - calc cov σ x - _ = cov ((ψ : M → 𝕜) • σ) x := by - rw [hcov.leibniz hσ hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] - erw [ContinuousLinearMap.comp_zero] - simp - _ = cov ((ψ : M → 𝕜) • σ') x := by rw [funext H] - _ = cov σ' x := by - rw [hcov.leibniz hσ' hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] - erw [ContinuousLinearMap.comp_zero] - simp - --- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x --- this should be easy using the projection formula in `CovariantDerivative.Ehresmann`. - -/-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(E) → Γ(E)`. -Future lemmas will upgrade this to a map `TM ⊕ E → E`. -/ -noncomputable def differenceAux - (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : - (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := - fun σ ↦ cov σ - cov' σ - -variable [CompleteSpace 𝕜] - [IsManifold I 1 M] - [FiniteDimensional 𝕜 F] - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] - -variable - {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - {s : Set M} - (hcov : IsCovariantDerivativeOn F cov s) - (hcov' : IsCovariantDerivativeOn F cov' s) - -open Classical in -/-- The difference of two covariant derivatives, as a tensorial map -/ -noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := - if hxs : x ∈ s then - mkTensorAt I F (differenceAux cov cov') x - (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) - (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ']; abel) - else - 0 - --- do we need this? --- omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -lemma difference_def (hx : x ∈ s := by trivial) (σ₀ : V x) : difference hcov hcov' x σ₀ = - cov (extend F σ₀) x - cov' (extend F σ₀) x := by - simp only [difference, hx, reduceDIte] - rfl - --- omit [∀ (x : M), IsTopologicalAddGroup (V x)] [∀ (x : M), ContinuousSMul 𝕜 (V x)] in -@[simp] -lemma difference_apply (hx : x ∈ s := by trivial) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : - difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by - simp only [difference, hx, reduceDIte] - rw [mkTensorAt_apply _ _ _ hσ] - rfl - -end IsCovariantDerivativeOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 23e3f4eab047a5..c6b2634f5dd0b7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -729,7 +729,7 @@ If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnect noncomputable def LeviCivitaConnection [FiniteDimensional ℝ E] : CovariantDerivative I E (TangentSpace I : M → Type _) where toFun := lcAux I - isCovariantDerivativeOn := isCovariantDerivativeOn_lcAux I + isCovariantDerivativeOnUniv := isCovariantDerivativeOn_lcAux I theorem leviCivitaConnection_apply [FiniteDimensional ℝ E] {x : M} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) @@ -777,7 +777,7 @@ lemma leviCivitaConnection_isCompatible [FiniteDimensional ℝ E] : lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsTorsionFree := by - have a := (LeviCivitaConnection I M).isCovariantDerivativeOn + have a := (LeviCivitaConnection I M).isCovariantDerivativeOnUniv rw [CovariantDerivative.isTorsionFree_iff] intro X Y x hX hY apply congr_of_forall_product_apply diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index 00df06fd6bdf68..a5b5aa98d3e4e4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -72,7 +72,7 @@ variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where toFun s x := mfderiv I 𝓘(𝕜, F) s x - isCovariantDerivativeOn := -- TODO use previous work + isCovariantDerivativeOnUniv := -- TODO use previous work { add {σ σ' x} hσ hσ' hx := by rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' rw [mfderiv_add hσ hσ'] @@ -118,7 +118,7 @@ lemma trivial_isSmooth : noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where toFun σ := fun x ↦ fderiv 𝕜 σ x + A x (σ x) - isCovariantDerivativeOn := by + isCovariantDerivativeOnUniv := by convert IsCovariantDerivativeOn.of_endomorphism (I := 𝓘(𝕜, E)) A ext f x v rw [mfderiv_eq_fderiv] @@ -180,7 +180,7 @@ lemma _root_.CovariantDerivative.exists_one_form ∀ σ : M → F, ∀ x, MDiffAt (T% σ) x → letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) σ x cov σ x = d + A x (σ x) := by - simpa using cov.isCovariantDerivativeOn.exists_one_form + simpa using cov.isCovariantDerivativeOnUniv.exists_one_form end classification From 7676417b34dc747d5fa4c492e91f7cb517f87b51 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:27:25 +0000 Subject: [PATCH 526/601] [pre-commit.ci lite] apply automatic fixes --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 364498d0111e39..dae678f991c20f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -398,5 +398,3 @@ lemma ContMDiffCovariantDerivative.affineCombination' [IsManifold I 1 M] [Vector end operations end CovariantDerivative - - From 45b7da1769dcad08589af023e86f4de588ac78c0 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 12:30:01 +0000 Subject: [PATCH 527/601] chore: move outdated code about Christoffel symbols to a new file --- Mathlib.lean | 1 + .../ChristoffelSymbols.lean | 319 ++++++++++++++++++ .../CovariantDerivative/LeviCivita.lean | 287 ---------------- 3 files changed, 320 insertions(+), 287 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean diff --git a/Mathlib.lean b/Mathlib.lean index 953b1e69cca576..6723147ce845ca 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4416,6 +4416,7 @@ public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.ChristoffelSymbols public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean new file mode 100644 index 00000000000000..ac3171e202f810 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean @@ -0,0 +1,319 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Rothgang +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.Dual +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame + +/-! # Christoffel symbols for a covariant derivative + +Old code for defining the Christoffel symbols of a connection: +it's not clear how much this will be used, +and it would need to be thoroughly updated to compile, given the other modifications made + +-/ +set_option backward.isDefEq.respectTransparency false + +namespace CovariantDerivative + +open Bundle Filter Function Module NormedSpace Topology +open scoped ContDiff Manifold + +variable {n : WithTop ℕ∞} + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) + {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] + [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] + {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} + (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) + [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x : M} + +-- TODO: move this section to `Torsion.lean` +section + +--omit [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] +--omit [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + +/-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` +with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, +this is a function `Γᵢⱼᵏ : M → ℝ`, whose value outside of `U` is meaningless. -/ +noncomputable def ChristoffelSymbol + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) + {U : Set M} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := + (LinearMap.piApply (hs.coeff k)) (fun x ↦ f (s i) x (s j x)) + +-- special case of `foobar` below; needed? +lemma ChristoffelSymbol.sum_eq + (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) + {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j : ι) (hx : x ∈ U) : + f (s i) x (s j x) = ∑ k, (ChristoffelSymbol I f hs i j k x) • (s k) x := by + simp only [ChristoffelSymbol, LinearMap.piApply_apply] + apply hs.coeff_sum_eq _ hx + +variable {U : Set M} + {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + +-- Note that this result is false if `{s i}` is merely a local frame. +lemma eq_product_apply [Fintype ι] + (hf : IsCovariantDerivativeOn E f U) + (hs : IsOrthonormalFrameOn I E n s U) + (i j k : ι) (hx : x ∈ U) : + ChristoffelSymbol I f hs.toIsLocalFrameOn i j k x = inner ℝ (f (s i) x (s j x)) (s k x) := by + -- Choose a linear order on ι: which one really does not matter for our result. + have : LinearOrder ι := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot ι := by sorry + sorry + -- was: rw [ChristoffelSymbol, hs.coeff_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] + +#exit +-- TODO: the next lines have a number of errors, and would need to be updated + +-- Lemma 4.3 in Lee, Chapter 5: first term still missing +lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeOn E f U) + (hs : IsLocalFrameOn I E 1 s U) {x : M} (hx : x ∈ U) : + f X x (Y x) = ∑ k, + letI S₁ := ∑ i, ∑ j, + ((LinearMap.piApply (hs.coeff i)) X) * (LinearMap.piApply (hs.coeff j) Y) + * (ChristoffelSymbol I f hs i j k) + letI S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! + S₁ x • s k x := by + have hY := hs.coeff_sum_eq Y hx + -- should this be a separate lemma also? + have : ∀ x ∈ U, Y x = ∑ i, hs.coeff i x (Y x) • s i x := by + intro x hx + apply hs.coeff_sum_eq Y hx + have : f X x (Y x) = f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by + -- apply `congr_σ_of_eventuallyEq` from Basic.lean (after restoring it) + -- want U to be a neighbourhood of x to make this work + sorry + rw [this] + -- straightforward computation: use linearity and Leibniz rule + sorry + +/- TODO: prove some basic properties, such as +- the Christoffel symbols are linear in cov +- if (s_i) is a smooth local frame on U, then cov is smooth on U iff each Christoffel symbol is (?) +- prove a `spec` equality +- deduce: two covariant derivatives are equal iff their Christoffel symbols are equal +-/ + +lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] + [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? + (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) + (hs : IsLocalFrameOn I E n s U) + (hfg : ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x) : + ∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X x (Y x) = g X x (Y x) := by + have (i j : ι) : ∀ x ∈ U, f (s i) (s j) x = g (s i) (s j) x := by + intro x hx + rw [hs.eq_iff_coeff hx] + exact fun k ↦ hfg i j k x hx + intro X Y x hx + -- use linearity (=formula for f in terms of Christoffel symbols) now, another separate lemma! + sorry + +/-- Two covariant derivatives on `U` are equal on `U` if and only if all of their +covariant derivatives w.r.t. some local frame on `U` are equal on `U`. -/ +lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ι] + [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? + (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) + (hs : IsLocalFrameOn I E n s U) : + (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X x (Y x) = g X x (Y x)) ↔ + ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x := + ⟨fun hfg _i _j _k _x hx ↦ hs.coeff_congr (hfg _ _ _ hx ) .., + fun h X Y x hx ↦ hf.congr_of_christoffelSymbol_eq I hg hs h X Y x hx⟩ + +-- TODO: global version for convenience, with an alias for the interesting direction! + +variable (hs : IsLocalFrameOn I E n s U) + +lemma christoffelSymbol_zero (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ι) : ChristoffelSymbol I 0 hs i j k = 0 := by + simp [ChristoffelSymbol] + +@[simp] +lemma christoffelSymbol_zero_apply (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ι) (x) : ChristoffelSymbol I 0 hs i j k x = 0 := by + simp [christoffelSymbol_zero] + +end + +-- Lemma 4.3 in Lee, Chapter 5: first term still missing +variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} + {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} + +-- XXX: generalise this to any field +variable {I} in +/-- `∇` is torsion-free on `U` if its torsion vanishes at each `x ∈ U` -/ +noncomputable def IsTorsionFreeOn + (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) + (U : Set M) : Prop := + ∀ x ∈ U, ∀ X Y : Π x : M, TangentSpace I x, IsCovariantDerivativeOn.torsionAux cov X Y x = 0 +namespace IsTorsionFreeOn +section changing_set +/-! Changing set +In this changing we change `s` in `IsTorsionFreeOn F f s`. +-/ +lemma mono {s t : Set M} (hf : IsTorsionFreeOn f t) (hst : s ⊆ t) : + IsTorsionFreeOn f s := + fun _ hx _ _ ↦ hf _ (hst hx) .. + +lemma iUnion {ι : Type*} {s : ι → Set M} (hf : ∀ i, IsTorsionFreeOn f (s i)) : + IsTorsionFreeOn cov (⋃ i, s i) := by + rintro x ⟨si, ⟨i, hi⟩, hxsi⟩ X Y + sorry -- was: exact hf i x (by simp [hi, hxsi]) X Y +end changing_set +end IsTorsionFreeOn + +-- errors: omit [IsContMDiffRiemannianBundle I 1 E fun x ↦ TangentSpace I x] in +/-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. +A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, +the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ +lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fintype ι] + [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? + (hf : IsCovariantDerivativeOn E f U) + {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) + (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : + IsTorsionFreeOn f U ↔ + ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by + rw [hf.isTorsionFreeOn_iff_localFrame (n := n) hs] + have (i j : ι) {x} (hx : x ∈ U) : + torsion f (s i) (s j) x = f (s i) x (s j x) - f (s j) x (s i x) := by + simp [torsion, hs'' i j ⟨x, hx⟩] + peel with i j + refine ⟨?_, ?_⟩ + · intro h k x hx + simp only [ChristoffelSymbol] + apply hs.coeff_congr + specialize h x hx + rw [this i j hx, sub_eq_zero] at h + exact h + · intro h x hx + rw [this i j hx, sub_eq_zero, hs.eq_iff_coeff hx] + exact fun k ↦ h k x hx + +-- Exercise 4.2(b) in Lee, Chapter 4 +/-- A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U` and +any local coordinate frame, the Christoffel symbols `Γᵢⱼᵏ` are symmetric. + +TODO: figure out the right quantifiers here! +right now, I just have one fixed coordinate frame... will this do?? +-/ +lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional ℝ E] [IsManifold I ∞ M] + (hf : IsCovariantDerivativeOn E f U) : + IsTorsionFreeOn f U ↔ + ∀ x ∈ U, + -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. + -- TODO: does the following do what I want?? + letI cs := ChristoffelSymbol I f + (trivializationAt E _ x).isLocalFrameOn_localFrame_baseSet I 1 ((Basis.ofVectorSpace ℝ E)) + ∀ i j k, cs i j k x = cs j i k x := by + letI t := (trivializationAt E (fun (x : M) ↦ TangentSpace I x)) + have hs (x) := + ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (t x)) + + -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! + rw [isTorsionFreeOn_iff_christoffelSymbols (ι := (↑(Basis.ofVectorSpaceIndex ℝ E))) I hf] + -- issues with quantifier order in the statement... prove both directions separately, at each x? + repeat sorry + +theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x : M) : + letI t := trivializationAt E (TangentSpace I) x; + letI hs := t.isLocalFrameOn_localFrame_baseSet I 1 (Basis.ofVectorSpace ℝ E) + ∀ x', x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), + ChristoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = + ChristoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by + by_cases hE : Subsingleton E + · have (y : M) (X : TangentSpace I y) : X = 0 := by + have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) + apply Subsingleton.eq_zero X + have (X : Π y : M, TangentSpace I y) : X = 0 := sorry + intro x'' hx'' i j k + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] + unfold lcCandidate + simp only [lcAux, hE, ↓reduceDIte] + + letI t := trivializationAt E (TangentSpace I) x; + letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t + have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k + -- now, use a congruence result and the first `have` + sorry + -- Note that hs is not necessarily an orthonormal frame, so we cannot simply rewrite + -- the Christoffel symbols as Γᵢⱼᵏ = ⟪∇ᵍ X Y, Z⟫`: however, the result we wants to prove boils + -- down to proving the same. + intro x' hx' i j + set t := trivializationAt E (TangentSpace I) x + set b := (Basis.ofVectorSpace ℝ E) + set s := t.localFrame b + set ι := ↑(Basis.ofVectorSpaceIndex ℝ E) + -- Same computation as above; extract as lemma! + let O : (x : M) → TangentSpace I x := fun x ↦ 0 + have need : ∀ i j, VectorField.mlieBracket I (s i) (s j) x' = O x' := sorry + have aux : ∀ k, ⟪LeviCivitaConnection I M (s i) (s j), (s k)⟫ x' + = ⟪LeviCivitaConnection I M (s j) (s i), (s k)⟫ x' := by + intro k + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] + unfold lcCandidate + rw [product_apply, product_apply] + simp only [lcAux, hE, ↓reduceDIte] + -- Choose a linear order on ι: which one really does not matter for our result. + have : LinearOrder ι := by + choose r wo using exists_wellOrder _ + exact r + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + have : Nonempty ι := b.index_nonempty + -- The linear ordering on the indexing set of `b` is only used in this proof, + -- so our choice does not matter. + have : LinearOrder ι := by + choose r wo using exists_wellOrder _ + exact r + have : Fintype ι := sorry + -- why does this fail? are there two different orders in play? + have : LocallyFiniteOrderBot ι := sorry + have : ∑ k', inner ℝ + (leviCivitaRhs I (s i) (s j) + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • + b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') + (s k x') = + ∑ k', inner ℝ + (leviCivitaRhs I (s j) (s i) + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • + b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') + (s k x') := by + congr with k' + simp only [leviCivitaRhs] + set sij := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x' + rw [inner_smul_left, inner_smul_left] + congr + simp [leviCivitaRhs'] + set S := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' + have need' : ∀ i, VectorField.mlieBracket I (s i) S x' = O x' := by + -- expand the definition of Gram-Schmidt and use need and linearity + sorry + have need'' : ∀ i, VectorField.mlieBracket I S (s i) x' = O x' := by + sorry -- swap and use need', or so + rw [product_congr_right I (need i j), product_congr_right I (need j i), + product_congr_right I (need' i), product_congr_right I (need'' i), + product_congr_right I (need' j), product_congr_right I (need'' j), + rhs_aux_swap I (s i) (s j), rhs_aux_swap I (s j) S, rhs_aux_swap I S (s i)] + simp [O] + abel + -- now, just rewrite `inner` to take out a sum: same lemma twice + convert this + · sorry + · sorry + + -- deduce the goal from `aux` + sorry + +end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index c6b2634f5dd0b7..c771c714d54ad3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -814,291 +814,4 @@ lemma leviCivitaConnection_isLeviCivitaConnection [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_isTorsionFree I⟩ -#exit --- TODO: move this section to `Torsion.lean` -section - ---omit [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] ---omit [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] - -/-- The **Christoffel symbol** of a covariant derivative on a set `U ⊆ M` -with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, -this is a function `Γᵢⱼᵏ : M → ℝ`, whose value outside of `U` is meaningless. -/ -noncomputable def ChristoffelSymbol - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) - {U : Set M} {ι : Type*} {s : ι → (x : M) → TangentSpace I x} - (hs : IsLocalFrameOn I E n s U) (i j k : ι) : M → ℝ := - hs.coeff k (fun x ↦ f (s i) x (s j x)) - --- special case of `foobar` below; needed? -lemma ChristoffelSymbol.sum_eq - (f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)) - {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} - (hs : IsLocalFrameOn I E n s U) (i j : ι) (hx : x ∈ U) : - f (s i) x (s j x) = ∑ k, (ChristoffelSymbol I f hs i j k x) • (s k) x := by - simp only [ChristoffelSymbol] - exact hs.coeff_sum_eq _ hx - -variable {U : Set M} - {f g : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - {ι : Type*} {s : ι → (x : M) → TangentSpace I x} - --- Note that this result is false if `{s i}` is merely a local frame. -lemma eq_product_apply [Fintype ι] - (hf : IsCovariantDerivativeOn E f U) - (hs : IsOrthonormalFrameOn I E n s U) - (i j k : ι) (hx : x ∈ U) : - ChristoffelSymbol I f hs.toIsLocalFrameOn i j k x = inner ℝ (f (s i) x (s j x)) (s k x) := by - -- Choose a linear order on ι: which one really does not matter for our result. - have : LinearOrder ι := by - choose r wo using exists_wellOrder _ - exact r - have : LocallyFiniteOrderBot ι := by sorry - rw [ChristoffelSymbol, hs.coeff_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] - --- Lemma 4.3 in Lee, Chapter 5: first term still missing -lemma foobar [Fintype ι] [FiniteDimensional ℝ E] (hf : IsCovariantDerivativeOn E f U) - (hs : IsLocalFrameOn I E 1 s U) {x : M} (hx : x ∈ U) : - f X x (Y x) = ∑ k, - letI S₁ := ∑ i, ∑ j, (hs.coeff i X) * (hs.coeff j Y) * (ChristoffelSymbol I f hs i j k) - letI S₂ : M → ℝ := sorry -- first summand in Leibniz' rule! - S₁ x • s k x := by - have hY := hs.coeff_sum_eq Y hx - -- should this be a separate lemma also? - have : ∀ x ∈ U, Y x = ∑ i, (hs.coeff i) Y x • s i x := by - intro x hx - apply hs.coeff_sum_eq Y hx - have : f X x (Y x) = f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by - -- apply `congr_σ_of_eventuallyEq` from Basic.lean (after restoring it) - -- want U to be a neighbourhood of x to make this work - sorry - rw [this] - -- straightforward computation: use linearity and Leibniz rule - sorry - -/- TODO: prove some basic properties, such as -- the Christoffel symbols are linear in cov -- if (s_i) is a smooth local frame on U, then cov is smooth on U iff each Christoffel symbol is (?) -- prove a `spec` equality -- deduce: two covariant derivatives are equal iff their Christoffel symbols are equal --/ - -lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ι] - [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? - (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) - (hs : IsLocalFrameOn I E n s U) - (hfg : ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x) : - ∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X x (Y x) = g X x (Y x) := by - have (i j : ι) : ∀ x ∈ U, f (s i) (s j) x = g (s i) (s j) x := by - intro x hx - rw [hs.eq_iff_coeff hx] - exact fun k ↦ hfg i j k x hx - intro X Y x hx - -- use linearity (=formula for f in terms of Christoffel symbols) now, another separate lemma! - sorry - -/-- Two covariant derivatives on `U` are equal on `U` if and only if all of their -covariant derivatives w.r.t. some local frame on `U` are equal on `U`. -/ -lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ι] - [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? - (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) - (hs : IsLocalFrameOn I E n s U) : - (∀ X Y : Π x : M, TangentSpace I x, ∀ x ∈ U, f X x (Y x) = g X x (Y x)) ↔ - ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x := - ⟨fun hfg _i _j _k _x hx ↦ hs.coeff_congr (hfg _ _ _ hx ) .., - fun h X Y x hx ↦ hf.congr_of_christoffelSymbol_eq I hg hs h X Y x hx⟩ - --- TODO: global version for convenience, with an alias for the interesting direction! - -variable (hs : IsLocalFrameOn I E n s U) - -lemma christoffelSymbol_zero (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} - (hs : IsLocalFrameOn I E n s U) (i j k : ι) : ChristoffelSymbol I 0 hs i j k = 0 := by - simp [ChristoffelSymbol] - -@[simp] -lemma christoffelSymbol_zero_apply (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} - (hs : IsLocalFrameOn I E n s U) (i j k : ι) (x) : ChristoffelSymbol I 0 hs i j k x = 0 := by - simp [christoffelSymbol_zero] - -end - --- Lemma 4.3 in Lee, Chapter 5: first term still missing -variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSpace I x} - {f : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[ℝ] TangentSpace I x)} - --- errors: omit [IsContMDiffRiemannianBundle I 1 E fun x ↦ TangentSpace I x] in -/-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. -A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U`, -the Christoffel symbols `Γᵢⱼᵏ` w.r.t. `{s i}` are symmetric. -/ -lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Fintype ι] - [FiniteDimensional ℝ E] -- TODO: this is implied by Finite ι, right? - (hf : IsCovariantDerivativeOn E f U) - {s : ι → (x : M) → TangentSpace I x} (hs : IsLocalFrameOn I E n s U) - (hs'' : ∀ i j, ∀ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : - IsTorsionFreeOn f U ↔ - ∀ i j k, ∀ x ∈ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by - rw [hf.isTorsionFreeOn_iff_localFrame (n := n) hs] - have (i j : ι) {x} (hx : x ∈ U) : - torsion f (s i) (s j) x = f (s i) x (s j x) - f (s j) x (s i x) := by - simp [torsion, hs'' i j ⟨x, hx⟩] - peel with i j - refine ⟨?_, ?_⟩ - · intro h k x hx - simp only [ChristoffelSymbol] - apply hs.coeff_congr - specialize h x hx - rw [this i j hx, sub_eq_zero] at h - exact h - · intro h x hx - rw [this i j hx, sub_eq_zero, hs.eq_iff_coeff hx] - exact fun k ↦ h k x hx - --- Exercise 4.2(b) in Lee, Chapter 4 -/-- A covariant derivative on `U` is torsion-free on `U` iff for each `x ∈ U` and -any local coordinate frame, the Christoffel symbols `Γᵢⱼᵏ` are symmetric. - -TODO: figure out the right quantifiers here! -right now, I just have one fixed coordinate frame... will this do?? --/ -lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional ℝ E] [IsManifold I ∞ M] - (hf : IsCovariantDerivativeOn E f U) : - IsTorsionFreeOn f U ↔ - ∀ x ∈ U, - -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. - -- TODO: does the following do what I want?? - letI cs := ChristoffelSymbol I f - ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (trivializationAt E _ x)) - ∀ i j k, cs i j k x = cs j i k x := by - letI t := (trivializationAt E (fun (x : M) ↦ TangentSpace I x)) - have hs (x) := - ((Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 (t x)) - - -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! - rw [isTorsionFreeOn_iff_christoffelSymbols (ι := (↑(Basis.ofVectorSpaceIndex ℝ E))) I hf] - -- issues with quantifier order in the statement... prove both directions separately, at each x? - repeat sorry - -theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x : M) : - letI t := trivializationAt E (TangentSpace I) x; - letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t - ∀ x', x' ∈ t.baseSet → ∀ (i j k : ↑(Basis.ofVectorSpaceIndex ℝ E)), - ChristoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = - ChristoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by - by_cases hE : Subsingleton E - · have (y : M) (X : TangentSpace I y) : X = 0 := by - have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) - apply Subsingleton.eq_zero X - have (X : Π y : M, TangentSpace I y) : X = 0 := sorry - intro x'' hx'' i j k - simp only [LeviCivitaConnection, LeviCivitaConnection_aux] - unfold lcCandidate - simp only [lcAux, hE, ↓reduceDIte] - - letI t := trivializationAt E (TangentSpace I) x; - letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t - have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k - -- now, use a congruence result and the first `have` - sorry - -- Note that hs is not necessarily an orthonormal frame, so we cannot simply rewrite - -- the Christoffel symbols as Γᵢⱼᵏ = ⟪∇ᵍ X Y, Z⟫`: however, the result we wants to prove boils - -- down to proving the same. - intro x' hx' i j - set t := trivializationAt E (TangentSpace I) x - set b := (Basis.ofVectorSpace ℝ E) - set s := b.localFrame t - set ι := ↑(Basis.ofVectorSpaceIndex ℝ E) - -- Same computation as above; extract as lemma! - let O : (x : M) → TangentSpace I x := fun x ↦ 0 - have need : ∀ i j, VectorField.mlieBracket I (s i) (s j) x' = O x' := sorry - have aux : ∀ k, ⟪LeviCivitaConnection I M (s i) (s j), (s k)⟫ x' - = ⟪LeviCivitaConnection I M (s j) (s i), (s k)⟫ x' := by - intro k - simp only [LeviCivitaConnection, LeviCivitaConnection_aux] - unfold lcCandidate - rw [product_apply, product_apply] - simp only [lcAux, hE, ↓reduceDIte] - -- Choose a linear order on ι: which one really does not matter for our result. - have : LinearOrder ι := by - choose r wo using exists_wellOrder _ - exact r - have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE - have : Nonempty ι := b.index_nonempty - -- The linear ordering on the indexing set of `b` is only used in this proof, - -- so our choice does not matter. - have : LinearOrder ι := by - choose r wo using exists_wellOrder _ - exact r - have : Fintype ι := sorry - -- why does this fail? are there two different orders in play? - have : LocallyFiniteOrderBot ι := sorry - have : ∑ k', inner ℝ - (leviCivitaRhs I (s i) (s j) - (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • - b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') - (s k x') = - ∑ k', inner ℝ - (leviCivitaRhs I (s j) (s i) - (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' • - b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') - (s k x') := by - congr with k' - simp only [leviCivitaRhs] - set sij := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x' - rw [inner_smul_left, inner_smul_left] - congr - simp [leviCivitaRhs'] - set S := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' - have need' : ∀ i, VectorField.mlieBracket I (s i) S x' = O x' := by - -- expand the definition of Gram-Schmidt and use need and linearity - sorry - have need'' : ∀ i, VectorField.mlieBracket I S (s i) x' = O x' := by - sorry -- swap and use need', or so - rw [product_congr_right I (need i j), product_congr_right I (need j i), - product_congr_right I (need' i), product_congr_right I (need'' i), - product_congr_right I (need' j), product_congr_right I (need'' j), - rhs_aux_swap I (s i) (s j), rhs_aux_swap I (s j) S, rhs_aux_swap I S (s i)] - simp [O] - abel - -- now, just rewrite `inner` to take out a sum: same lemma twice - convert this - · sorry - · sorry - - -- deduce the goal from `aux` - sorry - -lemma baz [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by - -- If `E` is trivial, the Levi-Civita connection is always zero and all proofs are trivial. - by_cases hE : Subsingleton E - · have (y : M) (X : TangentSpace I y) : X = 0 := by - have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) - apply Subsingleton.eq_zero X - refine ⟨?_, ?_⟩ - · intro X Y Z x - simp only [LeviCivitaConnection, LeviCivitaConnection_aux] - unfold lcCandidate - simp [this] - · simp only [isTorsionFree_def, LeviCivitaConnection, LeviCivitaConnection_aux] - unfold lcCandidate torsion - ext; simp [this] - refine ⟨?_, ?_⟩ - · intro X Y Z x - unfold LeviCivitaConnection LeviCivitaConnection_aux lcCandidate - simp only [lcAux, hE, ↓reduceDIte] - --simp [product_apply] - sorry -- compatible - · let s : M → Set M := fun x ↦ (trivializationAt E (fun (x : M) ↦ TangentSpace I x) x).baseSet - apply (LeviCivitaConnection I M).of_isTorsionFreeOn_of_open_cover (s := s) ?_ (by aesop) - intro x - simp only [s] - set t := fun x ↦ trivializationAt E (TangentSpace I : M → Type _) x with t_eq - have : IsCovariantDerivativeOn E (LeviCivitaConnection I M) (t x).baseSet := - isCovariantDerivativeOn_lcCandidate _ (t x) - rw [isTorsionFree_iff_christoffelSymbols' _ this] - intro x' hx' i j k - -- Now, compute christoffel symbols and be happy. - have := LeviCivitaConnection.christoffelSymbol_symm I x x' hx' i j k - sorry -- almost there, except x vs x' convert this - end CovariantDerivative From a32e69a737b2b9b8bf1af9d8b8afc187be5fdf71 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 6 Mar 2026 13:40:30 +0100 Subject: [PATCH 528/601] Add missing global operations --- .../CovariantDerivative/Basic.lean | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index dae678f991c20f..4375c44d4d1137 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -356,6 +356,20 @@ lemma contMDiffCovariantDerivativeOn_univ_iff [IsManifold I 1 M] [VectorBundle section operations +/-! ### Operations + +In this section we prove that: + +* affine combinations of covariant derivatives are covariant derivatives +* adding a one form taking values into endomorphisms of the vector bundle to a covariant + derivative gives a covariant derivative. See `add_on_form`. +* subtracting two covariant derivatives on some set gives a one form taking values into + endomorphisms of the vector bundle. See `difference`. + +Note: morally this means covariant derivatives form an affine space over the vector space of +one-forms taking values in endomorphisms of the bundle, but we don’t package it that way yet. +-/ + /-- An affine combination of covariant derivatives is a covariant derivative. -/ @[simps] def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : @@ -395,6 +409,27 @@ lemma ContMDiffCovariantDerivative.affineCombination' [IsManifold I 1 M] [Vector -- TODO: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) +/-- Adding a one form taking values into endomorphisms of the vector bundle to a covariant + derivative gives a covariant derivative. -/ +def add_one_form (cov : CovariantDerivative I F V) + (A : Π (x : M), V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : CovariantDerivative I F V where + toFun := fun σ x ↦ cov σ x + (A x) (σ x) + isCovariantDerivativeOnUniv := cov.isCovariantDerivativeOnUniv.add_one_form A + +section difference + +-- We need more assumptions to use the tensoriality criterion in order to build the difference +-- operation. +variable [CompleteSpace 𝕜] + [IsManifold I 1 M] + [FiniteDimensional 𝕜 F] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + +noncomputable def difference (cov cov' : CovariantDerivative I F V) : + Π (x : M), V x →L[𝕜] TangentSpace I x →L[𝕜] V x := + cov.isCovariantDerivativeOnUniv.difference cov'.isCovariantDerivativeOnUniv + +end difference end operations end CovariantDerivative From b2e648cbe708951a25f7e7ffe47df31918ca32b5 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 12:39:47 +0000 Subject: [PATCH 529/601] chore(LeviCivita): small clean-ups --- .../CovariantDerivative/LeviCivita.lean | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index c771c714d54ad3..51330c48f03564 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -8,48 +8,35 @@ module public import Mathlib.Analysis.InnerProductSpace.Dual public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion -public import Mathlib.Util.PrintSorries /-! -# The Levi-Civita connection +# The Levi-Civita connection on a Riemannian manifold -This file will define the Levi-Civita connection on any Riemannian manifold. -Details to be written! +This file defines the Levi-Civita connection on a (finite-dimensional) Riemannian manifold `(M, g)`. -TODO: refactor this file, to make Levi-Civita take a Riemannian metric instead! +## Main definitions and results -TODO: more generally, define a notion of metric connections (e.g., those whose parallel transport -is an isometry) and prove the Levi-Civita connection is a metric connection +## Implementation notes --/ -open Bundle Filter Function Module NormedSpace Topology +-/ -open scoped Bundle Manifold ContDiff +open Bundle Function NormedSpace +open scoped Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! -- TODO: revisit and fix this once the dust has settled set_option backward.isDefEq.respectTransparency false --- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. +-- Let `(M, g)` be a `C^k` real manifold modeled on `(E, H)`, endowed with a Riemannian metric `g`. variable {n : WithTop ℕ∞} {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] - -- don't need this assumption (yet?) - -- [IsRiemannianManifold I M] - -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] - -/-! Compatible connections: a connection on TM is compatible with the metric on M iff -`∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all vector fields X, Y and Z on `M`. -The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: -the left hand side at `X` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ - -variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} + {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} namespace CovariantDerivative From 94f67dd57c4b2bae68c12925d0ff4e83ac0eb285 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:15:21 +0000 Subject: [PATCH 530/601] refactor tensoriality to generalize codomain --- .../CovariantDerivative/Basic.lean | 18 +- .../CovariantDerivative/LeviCivita.lean | 80 +-- .../CovariantDerivative/Metric.lean | 19 +- .../CovariantDerivative/Torsion.lean | 28 +- .../Manifold/VectorBundle/Tensoriality.lean | 543 ++++++++---------- 5 files changed, 321 insertions(+), 367 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 4375c44d4d1137..9c653f10017a05 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -272,13 +272,23 @@ variable (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) +omit [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [VectorBundle 𝕜 F V] + [ContMDiffVectorBundle 1 F V I] in +theorem differenceAux_tensorial (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) + (x : M) (hx : x ∈ s) : TensorialAt I F (differenceAux cov cov' · x) x where + smul f σ hf hσ := by + simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf] + module + add σ σ' hσ hσ' := by + simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ'] + abel + open scoped Classical in /-- The difference of two covariant derivatives, as a tensorial map. -/ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := if hxs : x ∈ s then - mkTensorAt I F (differenceAux cov cov') x - (fun f σ hf hσ ↦ by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf]; module) - (fun σ σ' hσ hσ' ↦ by simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ']; abel) + TensorialAt.mkTensorAt _ x (differenceAux_tensorial hcov hcov' _ hxs) else 0 @@ -286,7 +296,7 @@ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜 lemma difference_apply {x : M} (hx : x ∈ s := by trivial) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by simp only [difference, hx, reduceDIte] - rw [mkTensorAt_apply _ _ _ hσ] + rw [TensorialAt.mkTensorAt_apply _ hσ] rfl end difference diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 51330c48f03564..f4ece60cd6fc72 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -577,39 +577,53 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] · rw [← hcov.eq_leviCivitaRhs I hX hY hZ] · rw [← hcov'.eq_leviCivitaRhs I hX hY hZ] +open Classical in +noncomputable def lcAux₀' (Y : Π x : M, TangentSpace I x) (x : M) + (X Z : Π x : M, TangentSpace I x) := + if MDiffAt (T% X) x then if MDiffAt (T% Z) x then + leviCivitaRhs I X Y Z + else 0 else 0 + +theorem leviCivitaRhs_tensorial₁ [FiniteDimensional ℝ E] + {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) (Z : Π x, TangentSpace I x) : + TensorialAt I E (lcAux₀' I Y x · Z x) x where + smul f X hf hX := by + dsimp [lcAux₀'] + rw [if_pos hX, if_pos] + · split_ifs with hZ + · exact leviCivitaRhs_smulX_apply hf hX hY hZ + · simp + · exact hf.smul_section hX + add X₁ X₂ hX₁ hX₂ := by + dsimp [lcAux₀'] + rw [if_pos hX₁, if_pos hX₂, if_pos] + · split_ifs with hZ + · exact leviCivitaRhs_addX_apply I hX₁ hX₂ hY hZ + · simp + · exact mdifferentiableAt_add_section hX₁ hX₂ + +theorem leviCivitaRhs_tensorial₂ [FiniteDimensional ℝ E] + {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) (X : Π x, TangentSpace I x) + (hX : MDiffAt (T% X) x) : + TensorialAt I E (lcAux₀' I Y x X · x) x where + smul f Z hf hZ := by + dsimp [lcAux₀'] + rw [if_pos hX, if_pos hZ, if_pos, if_pos hX] + · exact leviCivitaRhs_smulZ_apply I hf hX hY hZ + · exact hf.smul_section hZ + add Z₁ Z₂ hZ₁ hZ₂ := by + dsimp [lcAux₀'] + rw [if_pos hZ₁, if_pos hZ₂, if_pos hX, if_pos, if_pos hX, if_pos hX] + · exact leviCivitaRhs_addZ_apply I hX hY hZ₁ hZ₂ + · exact mdifferentiableAt_add_section hZ₁ hZ₂ + open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] ℝ := - mk2TensorAt I E E (fun (X Z : Π x : M, TangentSpace I x) ↦ - if hX : MDiffAt (T% X) x then if hZ : MDiffAt (T% Z) x then - leviCivitaRhs I X Y Z - else 0 else 0) (x := x) - (fun {f X Z} hf hX ↦ by - dsimp - rw [if_pos hX, if_pos] - · split_ifs with hZ - · exact leviCivitaRhs_smulX_apply hf hX hY - · simp - · exact hf.smul_section hX) - (fun {X₁ X₂ Z} hX₁ hX₂ ↦ by - dsimp - rw [if_pos hX₁, if_pos hX₂, if_pos] - · split_ifs with hZ - · exact leviCivitaRhs_addX_apply I hX₁ hX₂ hY - · simp - · exact mdifferentiableAt_add_section hX₁ hX₂) - (fun {f X Z} hf hX hZ ↦ by - dsimp - rw [if_pos hX, if_pos hZ, if_pos, if_pos hX] - · exact leviCivitaRhs_smulZ_apply I hf hX hY hZ - · exact hf.smul_section hZ) - (fun {X Z₁ Z₂} hX hZ₁ hZ₂ ↦ by - dsimp - rw [if_pos hZ₁, if_pos hZ₂, if_pos hX, if_pos, if_pos hX, if_pos hX] - · exact leviCivitaRhs_addZ_apply I hX hY hZ₁ hZ₂ - · exact mdifferentiableAt_add_section hZ₁ hZ₂ - ) + TensorialAt.mk2TensorAt _ (x := x) + (fun Z _ ↦ leviCivitaRhs_tensorial₁ _ _ hY Z) + (fun X hX ↦ leviCivitaRhs_tensorial₂ _ _ hY X hX) theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) @@ -617,7 +631,7 @@ theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : lcAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by unfold lcAux₀ - rw [mk2TensorAt_apply _ _ _ _ _ _ hX hZ, dif_pos hX, dif_pos hZ] + rw [TensorialAt.mk2TensorAt_apply _ _ hX hZ, lcAux₀', if_pos hX, if_pos hZ] noncomputable def lcAux₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : @@ -662,7 +676,7 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : congr! 1 simp only [lcAux₀] ext X₀ Y₀ - simp only [mk2TensorAt_apply_eq_extend, dite_eq_ite, ContinuousLinearMap.add_apply] + simp only [TensorialAt.mk2TensorAt_apply_eq_extend, ContinuousLinearMap.add_apply, lcAux₀'] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] · apply leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) hY hY' exact mdifferentiableAt_extend .. @@ -690,8 +704,8 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.toSpanSingleton_apply, map_add, map_smul] ext Z₀ - simp only [lcAux₀, mk2TensorAt_apply_eq_extend, dite_eq_ite, ContinuousLinearMap.add_apply, - ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] + simp only [lcAux₀, lcAux₀', TensorialAt.mk2TensorAt_apply_eq_extend, + ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend E X₀) (Y := Y) (Z := _root_.extend E Z₀) (x := x) (f := f) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 98f889974ad7a6..03e14628b4d2e5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -313,16 +313,23 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) -- set C' := inner ℝ (σ x) ((cov τ' x) X) -- set D := (cov σ x) X +theorem metricTensorAux_tensorial₁ (x : M) (τ : Π x, TangentSpace I x) (hτ : MDiffAt (T% τ) x) : + TensorialAt I E (metricTensorAux I cov · τ x) x where + smul _ _ hf hσ := aux1 cov hf hσ hτ + add σ σ' hσ hσ' := aux2 cov σ σ' τ hσ hσ' hτ + +theorem metricTensorAux_tensorial₂ (x : M) (σ : Π x, TangentSpace I x) (hσ : MDiffAt (T% σ) x) : + TensorialAt I E (metricTensorAux I cov σ · x) x where + smul _ _ hf hτ := aux3 cov hf hσ hτ + add τ τ' hτ hτ' := aux4 cov σ τ τ' hσ hτ hτ' + variable {I} in /-- The tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection `∇` on a Riemannian manifold `(M, g)` is compatible with the metric `g`. -/ @[no_expose] noncomputable def metricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - mk2TensorAt I E E (metricTensorAux I cov) - (fun _f _σ _τ hf hσ hτ ↦ aux1 cov hf hσ hτ) - (fun σ σ' τ hσ hσ' hτ ↦ aux2 cov σ σ' τ hσ hσ' hτ) - (fun _f _σ _τ hf hσ hτ ↦ aux3 cov hf hσ hτ) - (fun σ τ τ' hσ hτ hτ' ↦ aux4 cov σ τ τ' hσ hτ hτ') + TensorialAt.mk2TensorAt (metricTensorAux I cov · · x) + (metricTensorAux_tensorial₁ I cov x) (metricTensorAux_tensorial₂ I cov x) variable {I} in theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) @@ -330,7 +337,7 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) metricTensor cov x (Y x) (Z x) (X x) = fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by unfold metricTensor - rw [mk2TensorAt_apply _ _ _ _ _ _ hY hZ] + rw [TensorialAt.mk2TensorAt_apply _ _ hY hZ] simp only [metricTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] conv => diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 7764e801c29563..0cf9b549d2e6b0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -113,19 +113,31 @@ section variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] +-- TODO inline the lemmas that go into this +theorem torsionAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) (x : M) + (Y : Π x, TangentSpace I x) : + TensorialAt I E (torsionAux cov · Y x) x where + smul f X hf hX := hcov.torsionAux_smul_left_apply Y hf hX + add X X' hX hX' := hcov.torsionAux_add_left_apply Y hX hX' + +-- TODO inline the lemmas that go into this +theorem torsionAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) (x : M) + (X : Π x, TangentSpace I x) : + TensorialAt I E (torsionAux cov X · x) x where + smul f Y hf hY := hcov.torsionAux_smul_right_apply X hf hY + add Y Y' hY hY' := hcov.torsionAux_add_right_apply X hY hY' + noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := - mk2TensorAt I E E (torsionAux cov) - (fun f σ τ hf hσ hτ ↦ hcov.torsionAux_smul_left_apply τ hf hσ) - (fun σ σ' τ hσ hσ' hτ ↦ hcov.torsionAux_add_left_apply τ hσ hσ') - (fun f σ τ hf hσ hτ ↦ hcov.torsionAux_smul_right_apply σ hf hτ) - (fun σ τ τ' hσ hτ hτ' ↦ hcov.torsionAux_add_right_apply σ hτ hτ') + TensorialAt.mk2TensorAt (torsionAux cov · · x) + (fun τ _ ↦ hcov.torsionAux_tensorial₁ x τ) + (fun σ _ ↦ hcov.torsionAux_tensorial₂ x σ) theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : torsion hcov x (X x) (Y x) = torsionAux cov X Y x := - mk2TensorAt_apply _ _ _ _ _ _ hX hY + TensorialAt.mk2TensorAt_apply _ _ hX hY end @@ -147,7 +159,7 @@ noncomputable def torsion := cov.isCovariantDerivativeOn.torsion lemma torsion_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : cov.torsion x (X x) (Y x) = cov Y x (X x) - cov X x (Y x) - mlieBracket I X Y x := by unfold torsion IsCovariantDerivativeOn.torsion - apply mk2TensorAt_apply + apply TensorialAt.mk2TensorAt_apply exacts [hX, hY] lemma torsion_apply_extend (u v : TangentSpace I x) : @@ -155,7 +167,7 @@ lemma torsion_apply_extend (u v : TangentSpace I x) : cov (extend E v) x (extend E u x) - cov (extend E u) x (extend E v x) - mlieBracket I (extend E u) (extend E v) x := by unfold torsion IsCovariantDerivativeOn.torsion - apply mk2TensorAt_apply_eq_extend + apply TensorialAt.mk2TensorAt_apply_eq_extend /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ def IsTorsionFree : Prop := torsion cov = 0 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index aee0dd56191a27..e7f24a6e65abb4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -20,386 +20,297 @@ open scoped Bundle Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} [TopologicalSpace M] [ChartedSpace H M] variable - -- `F` model fiber - (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] [FiniteDimensional 𝕜 F] - -- `V` vector bundle - (V : M → Type*) [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] [VectorBundle 𝕜 F V] - [ContMDiffVectorBundle 1 F V I] + (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] + [FiberBundle F V] variable - (F' : Type*) [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] [FiniteDimensional 𝕜 F'] - (V' : M → Type*) [TopologicalSpace (TotalSpace F' V')] + (F' : Type*) [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] + {V' : M → Type*} [TopologicalSpace (TotalSpace F' V')] [∀ x, AddCommGroup (V' x)] [∀ x, Module 𝕜 (V' x)] [∀ x : M, TopologicalSpace (V' x)] - [FiberBundle F' V'] [VectorBundle 𝕜 F' V'] - [ContMDiffVectorBundle 1 F' V' I] + [FiberBundle F' V'] -variable (G : Type*) [NormedAddCommGroup G] [NormedSpace 𝕜 G] - (W : M → Type*) [∀ x, AddCommGroup (W x)] [∀ x, Module 𝕜 (W x)] +variable {A : Type*} [AddCommGroup A] [Module 𝕜 A] -lemma tensoriality_criterion - {φ : (Π x : M, V x) → (Π x, W x)} {x} - {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) - (hσσ' : σ x = σ' x) - (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') x = φ σ x + φ σ' x) : φ σ x = φ σ' x := by - have locality {σ σ'} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) - (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : φ σ x = φ σ' x := by - classical - rw [eventually_nhds_iff] at hσσ' - obtain ⟨t, htσσ', ht, hxt⟩ := hσσ' - let ψ (x' : M) : 𝕜 := if x' ∈ t then 1 else 0 - have hψx : ψ x = 1 := by simp [ψ, hxt] - have (x' : M) : (ψ • σ) x' = (ψ • σ') x' := by - dsimp [ψ] - split_ifs with hx't - · simpa using htσσ' _ hx't - · simp - have hψ' : MDiffAt ψ x := by - have : MDiffAt (fun (_x : M) ↦ (1 : 𝕜)) x := mdifferentiableAt_const - refine this.congr_of_eventuallyEq ?_ - apply eventually_nhds_iff.mpr - exact ⟨t, by simp [ψ], ht, hxt⟩ - calc φ σ x - _ = φ (ψ • σ) x := by simp [φ_smul _ _ hψ' hσ, hψx] - _ = φ (ψ • σ') x := by rw [funext this] - _ = φ σ' x := by simp [φ_smul _ _ hψ' hσ', hψx] - let ι : Type _ := Basis.ofVectorSpaceIndex 𝕜 F +structure TensorialAt (Φ : (Π x : M, V x) → A) (x : M) : + Prop where + smul : ∀ f : M → 𝕜, ∀ σ : Π x : M, V x, MDiffAt f x → MDiffAt (T% σ) x → Φ (f • σ) = f x • Φ σ + add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → Φ (σ + σ') = Φ σ + Φ σ' + +variable {Φ : (Π x : M, V x) → A} {x : M} +variable {I F F'} + +namespace TensorialAt + +theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : + Φ σ = Φ σ' := by classical - have sum_phi {s : Finset ι} (σ : ι → Π x : M, V x) - (hσ : ∀ i, MDiffAt (T% (σ i)) x): - φ (fun x' ↦ ∑ i ∈ s, σ i x') x = ∑ i ∈ s, φ (σ i) x := by - induction s using Finset.induction_on with - | empty => - simp only [Finset.sum_empty] - have h₁ : MDiffAt (fun x' : M ↦ (0 : 𝕜)) x := mdifferentiableAt_const - rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → 𝕜) • fun x' ↦ 0 by simp;rfl] - rw [φ_smul] - · simp - · exact h₁ - -- TODO: add mdifferentiable_zeroSection and/or use it! - apply (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero - | insert a s ha h => - change φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') x = _ - simp only [Finset.sum_insert ha, ← h] - exact φ_add _ _ (hσ a) (.sum_section hσ) - have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) - let b := Basis.ofVectorSpace 𝕜 F + rw [eventually_nhds_iff] at hσσ' + obtain ⟨t, htσσ', ht, hxt⟩ := hσσ' + let ψ (x' : M) : 𝕜 := if x' ∈ t then 1 else 0 + have hψx : ψ x = 1 := by simp [ψ, hxt] + have (x' : M) : (ψ • σ) x' = (ψ • σ') x' := by + dsimp [ψ] + split_ifs with hx't + · simpa using htσσ' _ hx't + · simp + have hψ' : MDiffAt ψ x := by + have : MDiffAt (fun (_x : M) ↦ (1 : 𝕜)) x := mdifferentiableAt_const + refine this.congr_of_eventuallyEq ?_ + apply eventually_nhds_iff.mpr + exact ⟨t, by simp [ψ], ht, hxt⟩ + calc Φ σ + _ = Φ (ψ • σ) := by simp [hΦ.smul _ _ hψ' hσ, hψx] + _ = Φ (ψ • σ') := by rw [funext this] + _ = Φ σ' := by simp [hΦ.smul _ _ hψ' hσ', hψx] + +variable [VectorBundle 𝕜 F V] [VectorBundle 𝕜 F' V'] + +theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι → Π x : M, V x) + (hσ : ∀ i, MDiffAt (T% (σ i)) x) : + Φ (fun x' ↦ ∑ i ∈ s, σ i x') = ∑ i ∈ s, Φ (σ i) := by + classical + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + have h₁ : MDiffAt (fun x' : M ↦ (0 : 𝕜)) x := mdifferentiableAt_const + rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → 𝕜) • fun x' ↦ 0 by simp;rfl] + rw [hΦ.smul] + · simp + · exact h₁ + -- TODO: add mdifferentiable_zeroSection and/or use it! + apply (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero + | insert a s ha h => + change Φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') = _ + simp only [Finset.sum_insert ha, ← h] + exact hΦ.add _ _ (hσ a) (.sum_section hσ) + +variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 F'] + [ContMDiffVectorBundle 1 F V I] [ContMDiffVectorBundle 1 F' V' I] + +lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : σ x = σ' x) : + Φ σ = Φ σ' := by + -- Select a local frame `s` for the bundle `V` near `x`, + -- and let `c` be the family of linear maps evaluating the coefficients of a section relative to + -- this frame let t := trivializationAt F V x + have x_mem : x ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt F V x + let b := Basis.ofVectorSpace 𝕜 F let s := t.localFrame b let c := t.localFrame_coeff I b - have hs (i) : MDiffAt (T% (s i)) x:= + have hs (i) : MDiffAt (T% (s i)) x := (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt (by simp) have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : MDiffAt (LinearMap.piApply (c i) σ) x := mdifferentiableAt_localFrame_coeff b x_mem hσ i - have hφ {σ : (x : M) → V x} - (hσ : MDiffAt (T% σ) x) : - φ σ x = φ (fun x' ↦ ∑ i, LinearMap.piApply (c i) σ x' • s i x') x := by - exact - locality hσ - (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) - (t.eventually_eq_localFrame_sum_coeff_smul b x_mem) - rw [hφ hσ, hφ hσ', sum_phi, sum_phi] - · change ∑ i, φ ((LinearMap.piApply (c i) σ) • (s i)) x = - ∑ i, φ ((LinearMap.piApply (c i) σ') • (s i)) x - congr - ext i - rw [φ_smul _ _ (hc hσ i) (hs i), φ_smul _ _ (hc hσ' i) (hs i)] - simp [hσσ'] + -- By the locality of the operation `(Φ · x)`, its value a + have hΦ_eq {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) : + Φ σ = Φ (fun x' ↦ ∑ i, LinearMap.piApply (c i) σ x' • s i x') := + hΦ.local hσ + (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) + (t.eventually_eq_localFrame_sum_coeff_smul b x_mem) + rw [hΦ_eq hσ, hΦ_eq hσ', hΦ.sum, hΦ.sum] + · congr! 1 with i + calc Φ ((LinearMap.piApply (c i) σ) • (s i)) + = c i x (σ x) • Φ (s i) := hΦ.smul _ _ (hc hσ i) (hs i) + _ = c i x (σ' x) • Φ (s i) := by rw [hσσ'] + _ = Φ ((LinearMap.piApply (c i) σ') • (s i)) := + hΦ.smul _ _ (hc hσ' i) (hs i) |>.symm · exact fun i ↦ (hc hσ' i).smul_section (hs i) · exact fun i ↦ (hc hσ i).smul_section (hs i) -include I in -lemma tensoriality_criterion₂ - {φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)} {x} +lemma pointwise₂ + {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} + (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) + (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ ·) x) {σ σ' : Π x : M, V x} {τ τ' : Π x : M, V' x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) (hσσ' : σ x = σ' x) - (hττ' : τ x = τ' x) - (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : φ σ τ x = φ σ' τ' x := by - trans φ σ' τ x - · let φ1 : (Π x : M, V x) → (Π x, W x) := fun X ↦ φ X τ - change φ1 σ x = φ1 σ' x - apply tensoriality_criterion I F V W hσ hσ' hσσ' - exacts [fun f σ hf hσ ↦ σ_smul _ hf hσ hτ, fun σ σ' hσ hσ' ↦ σ_add _ _ _ hσ hσ' hτ] - · let φ1 : (Π x : M, V' x) → (Π x, W x) := fun X ↦ φ σ' X - change φ1 τ x = φ1 τ' x - apply tensoriality_criterion I F' V' W hτ hτ' hττ' - exacts [fun f τ hf hτ ↦ τ_smul _ hf hσ' hτ, fun τ τ' hτ hτ' ↦ τ_add _ _ _ hσ' hτ hτ'] - -section tensoriality + (hττ' : τ x = τ' x) : + Φ σ τ = Φ σ' τ' := by + trans Φ σ' τ + · exact (hΦ₁ _ hτ).pointwise hσ hσ' hσσ' + · exact (hΦ₂ _ hσ').pointwise hτ hτ' hττ' variable [IsManifold I 1 M] - -variable - {V} - -- TODO can probably remove the next two hypotheses, by transport + -- TODO can probably remove the next four hypotheses, by transport [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] - -variable - {V'} - -- TODO can probably remove the next two hypotheses, by transport [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] - -variable - {W} - -- TODO can probably remove the next three hypotheses, by transport - [∀ x : M, TopologicalSpace (W x)] - [∀ x, IsTopologicalAddGroup (W x)] - [∀ x, ContinuousSMul 𝕜 (W x)] - [TopologicalSpace (TotalSpace G W)] - [FiberBundle G W] [VectorBundle 𝕜 G W] + [TopologicalSpace A] [IsTopologicalAddGroup A] [ContinuousSMul 𝕜 A] noncomputable def mkTensorAt - -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x, W x)) (x) - (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') x = φ σ x + φ σ' x) : - V x →L[𝕜] W x := - let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional - LinearMap.toContinuousLinearMap { - toFun v := φ (_root_.extend F v) x - map_add' v₁ v₂ := by - rw [← φ_add] - · apply tensoriality_criterion I F _ _ _ _ _ φ_smul φ_add - · exact mdifferentiableAt_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · simp + -- `Φ` explicit to make it easier to generate the side conditions at point of use + (Φ : (Π x : M, V x) → A) (x) (hΦ : TensorialAt I F (Φ) x) : + V x →L[𝕜] A := + let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space + have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + LinearMap.toContinuousLinearMap { + toFun v := Φ (_root_.extend F v) + map_add' v₁ v₂ := by + rw [← hΦ.add] + · apply hΦ.pointwise · exact mdifferentiableAt_extend .. + · apply mdifferentiableAt_add_section + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · simp + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + map_smul' c v := by + dsimp + rw [← hΦ.smul (fun _ ↦ c)] + · apply hΦ.pointwise · exact mdifferentiableAt_extend .. - map_smul' c v := by - dsimp - rw [← φ_smul (fun _ ↦ c)] - · apply tensoriality_criterion I F _ _ _ _ _ φ_smul φ_add + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const · exact mdifferentiableAt_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiable_const .. - · exact mdifferentiableAt_extend .. } + · simp + · exact mdifferentiable_const .. + · exact mdifferentiableAt_extend .. } -variable {I} in -theorem mkTensorAt_apply - -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x, W x)} {x} - (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') x = φ σ x + φ σ' x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : - mkTensorAt I F φ x φ_smul φ_add (σ x) = φ σ x := by - apply tensoriality_criterion I F _ _ _ hσ _ φ_smul φ_add - · exact mdifferentiableAt_extend .. +theorem mkTensorAt_apply {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F (Φ ·) x) + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : + mkTensorAt Φ x hΦ (σ x) = Φ σ := by + apply hΦ.pointwise _ hσ · simp + · exact mdifferentiableAt_extend .. -variable {I} in -theorem mkTensorAt_apply_eq_extend - -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x, W x)} {x} - (φ_smul : ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → - φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → - φ (σ + σ') x = φ σ x + φ σ' x) (σ : V x) : - mkTensorAt I F φ x φ_smul φ_add σ = φ (_root_.extend F σ) x := +theorem mkTensorAt_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F Φ x) + (σ : V x) : + mkTensorAt Φ x hΦ σ = Φ (_root_.extend F σ) := rfl -noncomputable def mkTensor - -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x, W x)) - (φ_smul : ∀ x, ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) - (x : M) : - V x →L[𝕜] W x := - mkTensorAt I F φ x (φ_smul x) (φ_add x) - -theorem contMDiff_mkTensor - (φ : (Π x : M, V x) → (Π x, W x)) - (φ_smul : ∀ x, ∀ f : M → 𝕜, ∀ σ, MDiffAt f x → MDiffAt (T% σ) x → φ (f • σ) x = f x • φ σ x) - (φ_add : ∀ x, ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → φ (σ + σ') x = φ σ x + φ σ' x) - -- hopefully this is the correct smoothness criterion! - {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : - -- elaborators not working here - let T (x : M) : TotalSpace (F →L[𝕜] G) (fun x ↦ V x →L[𝕜] W x) := - ⟨x, mkTensor I F φ φ_smul φ_add x⟩ - ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] G)) k T := by - sorry - noncomputable def mk2TensorAt -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)) {x} - (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) : - V x →L[𝕜] V' x →L[𝕜] W x := - let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional - let Ψ' : V' x ≃L[𝕜] F' := (trivializationAt F' V' x).continuousLinearEquivAt 𝕜 x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V' x) := Ψ'.symm.toHomeomorph.t2Space - have : FiniteDimensional 𝕜 (V' x) := Ψ'.symm.toLinearEquiv.finiteDimensional - have H : IsBilinearMap 𝕜 - (fun (v : V x) (w : V' x) ↦ φ (_root_.extend F v) (_root_.extend F' w) x) := - { add_left v₁ v₂ w := by - rw [← σ_add] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add - · exact mdifferentiableAt_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + (φ : (Π x : M, V x) → (Π x : M, V' x) → A) {x} + (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) + (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) : + V x →L[𝕜] V' x →L[𝕜] A := + let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space + have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + let Ψ' : V' x ≃L[𝕜] F' := (trivializationAt F' V' x).continuousLinearEquivAt 𝕜 x + (FiberBundle.mem_baseSet_trivializationAt' x) + have : T2Space (V' x) := Ψ'.symm.toHomeomorph.t2Space + have : FiniteDimensional 𝕜 (V' x) := Ψ'.symm.toLinearEquiv.finiteDimensional + have H : IsBilinearMap 𝕜 + (fun (v : V x) (w : V' x) ↦ φ (_root_.extend F v) (_root_.extend F' w)) := + { add_left v₁ v₂ w := by + rw [← (hφ₁ _ _).add] + · apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ _ _ _ _ rfl + · exact mdifferentiableAt_extend .. + · apply mdifferentiableAt_add_section · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. - · simp · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. + · simp + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + smul_left c v w := by + rw [← (hφ₁ _ _).smul (f := fun _ ↦ c)] + · apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ _ _ _ _ rfl · exact mdifferentiableAt_extend .. - smul_left c v w := by - rw [← σ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ _ rfl σ_smul σ_add τ_smul τ_add + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const · exact mdifferentiableAt_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiable_const .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. - add_right v w₁ w₂ := by - rw [← τ_add] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · simp + · simp + · exact mdifferentiable_const .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + add_right v w₁ w₂ := by + rw [← (hφ₂ _ _).add] + · apply TensorialAt.pointwise₂ hφ₁ hφ₂ · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. - smul_right c v w := by - rw [← τ_smul (f := fun _ ↦ c)] - · apply tensoriality_criterion₂ I F _ F' _ _ _ _ _ _ rfl _ σ_smul σ_add τ_smul τ_add + · apply mdifferentiableAt_add_section · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiable_const .. + · rfl + · simp + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. + smul_right c v w := by + rw [← (hφ₂ _ _).smul (f := fun _ ↦ c)] + · apply TensorialAt.pointwise₂ hφ₁ hφ₂ + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. } - H.toContinuousLinearMap + · apply MDifferentiableAt.smul_section + · exact mdifferentiableAt_const + · exact mdifferentiableAt_extend .. + · rfl + · simp + · exact mdifferentiable_const .. + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. } + H.toContinuousLinearMap -variable {I} in theorem mk2TensorAt_apply - -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)} {x} - (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} + (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) + (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : - mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add (σ x) (τ x) = φ σ τ x := by - apply tensoriality_criterion₂ I F _ F' _ _ _ hσ _ hτ _ _ σ_smul σ_add τ_smul τ_add - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + mk2TensorAt φ hφ₁ hφ₂ (σ x) (τ x) = φ σ τ := by + apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ hσ _ hτ · simp · simp + · exact mdifferentiableAt_extend .. + · exact mdifferentiableAt_extend .. -variable {I} in theorem mk2TensorAt_apply_eq_extend - -- `φ` explicit to make it easier to generate the side conditions at point of use - {φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)} {x} - (σ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (σ_add : ∀ σ σ' τ, MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (τ_smul : ∀ f : M → 𝕜, ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (τ_add : ∀ σ τ τ', MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) + {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} + (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) + (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) (σ : V x) (τ : V' x) : - mk2TensorAt I F F' φ σ_smul σ_add τ_smul τ_add σ τ - = φ (_root_.extend F σ) (_root_.extend F' τ) x := + mk2TensorAt φ hφ₁ hφ₂ σ τ + = φ (_root_.extend F σ) (_root_.extend F' τ) := rfl -theorem mk2TensorAt_add - (φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)) {x} - (φ_σ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ (f • σ) τ x = f x • φ σ τ x) - (φ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → - φ (σ + σ') τ x = φ σ τ x + φ σ' τ x) - (φ_τ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - φ σ (f • τ) x = f x • φ σ τ x) - (φ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → - φ σ (τ + τ') x = φ σ τ x + φ σ τ' x) - (ψ : (Π x : M, V x) → (Π x : M, V' x) → (Π x, W x)) - (ψ_σ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - ψ (f • σ) τ x = f x • ψ σ τ x) - (ψ_σ_add : ∀ (σ σ' τ), MDiffAt (T% σ) x → MDiffAt (T% σ') x → MDiffAt (T% τ) x → - ψ (σ + σ') τ x = ψ σ τ x + ψ σ' τ x) - (ψ_τ_smul : ∀ (f : M → 𝕜), ∀ {σ τ}, MDiffAt f x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → - ψ σ (f • τ) x = f x • ψ σ τ x) - (ψ_τ_add : ∀ (σ τ τ'), MDiffAt (T% σ) x → MDiffAt (T% τ) x → MDiffAt (T% τ') x → - ψ σ (τ + τ') x = ψ σ τ x + ψ σ τ' x) : - mk2TensorAt I F F' (φ + ψ) - (fun {_ _ τ} hf hσ hτ ↦ - (congr($(φ_σ_smul _ hf hσ hτ) + $(ψ_σ_smul _ hf hσ hτ))).trans - (smul_add _ _ _).symm) - (fun σ₁ σ₂ τ hσ₁ hσ₂ hτ ↦ - (congr($(φ_σ_add _ _ _ hσ₁ hσ₂ hτ) + $(ψ_σ_add _ _ _ hσ₁ hσ₂ hτ))).trans <| by - dsimp - abel) - (fun {_ σ _} hf hσ hτ ↦ - (congr($(φ_τ_smul _ hf hσ hτ) + $(ψ_τ_smul _ hf hσ hτ))).trans - (smul_add _ _ _).symm) - (fun σ {τ₁ τ₂} hσ hτ₁ hτ₂ ↦ - (congr($(φ_τ_add _ _ _ hσ hτ₁ hτ₂) + $(ψ_τ_add _ _ _ hσ hτ₁ hτ₂))).trans <| by - dsimp - abel) - = mk2TensorAt I F F' φ φ_σ_smul φ_σ_add φ_τ_smul φ_τ_add - + mk2TensorAt I F F' ψ ψ_σ_smul ψ_σ_add ψ_τ_smul ψ_τ_add := by - ext - simp [mk2TensorAt, IsBilinearMap.toContinuousLinearMap, IsBilinearMap.toLinearMap] +variable + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + +variable + -- TODO can probably remove the next two hypotheses, by transport + [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] + +variable + (G : Type*) [NormedAddCommGroup G] [NormedSpace 𝕜 G] + {W : M → Type*} [∀ x, AddCommGroup (W x)] [∀ x, Module 𝕜 (W x)] + -- TODO can probably remove the next three hypotheses, by transport + [∀ x : M, TopologicalSpace (W x)] [∀ x, IsTopologicalAddGroup (W x)] [∀ x, ContinuousSMul 𝕜 (W x)] + [TopologicalSpace (TotalSpace G W)] [FiberBundle G W] [VectorBundle 𝕜 G W] + +theorem contMDiff_mkTensorAt + (φ : (Π x : M, V x) → (Π x, W x)) + (hφ : ∀ x, TensorialAt I F (φ · x) x) + -- hopefully this is the correct smoothness criterion! + {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : + -- elaborators not working here + let T (x : M) : TotalSpace (F →L[𝕜] G) (fun x ↦ V x →L[𝕜] W x) := + ⟨x, mkTensorAt (φ · x) x (hφ x)⟩ + ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] G)) k T := by + sorry -end tensoriality +end TensorialAt From 85cc2c2806cb71894a4ea2a8e0e8e6a9dbdb1d38 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:19:26 +0000 Subject: [PATCH 531/601] eliminate "omit" --- .../VectorBundle/CovariantDerivative/Basic.lean | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 9c653f10017a05..1942306ef27bc8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -259,21 +259,12 @@ noncomputable def differenceAux (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := fun σ ↦ cov σ - cov' σ --- We need more assumptions to use the tensoriality criterion in order to build the difference --- operation. -variable [CompleteSpace 𝕜] - [IsManifold I 1 M] - [FiniteDimensional 𝕜 F] - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] - variable {cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) -omit [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [VectorBundle 𝕜 F V] - [ContMDiffVectorBundle 1 F V I] in theorem differenceAux_tensorial (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) (x : M) (hx : x ∈ s) : TensorialAt I F (differenceAux cov cov' · x) x where @@ -284,6 +275,13 @@ theorem differenceAux_tensorial (hcov : IsCovariantDerivativeOn F cov s) simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ'] abel +-- We need more assumptions to use the tensoriality criterion in order to build the difference +-- operation. +variable [CompleteSpace 𝕜] + [IsManifold I 1 M] + [FiniteDimensional 𝕜 F] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + open scoped Classical in /-- The difference of two covariant derivatives, as a tensorial map. -/ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := From a874b3198d6ae7ac966dc6b426245211c9fd953b Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:27:11 +0000 Subject: [PATCH 532/601] rename mkTensorAt --- .../CovariantDerivative/Basic.lean | 4 +-- .../CovariantDerivative/LeviCivita.lean | 8 ++--- .../CovariantDerivative/Metric.lean | 4 +-- .../CovariantDerivative/Torsion.lean | 12 ++++--- .../Manifold/VectorBundle/Tensoriality.lean | 35 ++++++++----------- 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 1942306ef27bc8..941639272961fb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -286,7 +286,7 @@ open scoped Classical in /-- The difference of two covariant derivatives, as a tensorial map. -/ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := if hxs : x ∈ s then - TensorialAt.mkTensorAt _ x (differenceAux_tensorial hcov hcov' _ hxs) + TensorialAt.mkHom _ x (differenceAux_tensorial hcov hcov' _ hxs) else 0 @@ -294,7 +294,7 @@ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜 lemma difference_apply {x : M} (hx : x ∈ s := by trivial) {σ : Π x, V x} (hσ : MDiffAt (T% σ) x) : difference hcov hcov' x (σ x) = cov σ x - cov' σ x := by simp only [difference, hx, reduceDIte] - rw [TensorialAt.mkTensorAt_apply _ hσ] + rw [TensorialAt.mkHom_apply _ hσ] rfl end difference diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index f4ece60cd6fc72..0e8dbe1b60678b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -621,7 +621,7 @@ open Classical in noncomputable def lcAux₀ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] ℝ := - TensorialAt.mk2TensorAt _ (x := x) + TensorialAt.mkHom₂ _ (x := x) (fun Z _ ↦ leviCivitaRhs_tensorial₁ _ _ hY Z) (fun X hX ↦ leviCivitaRhs_tensorial₂ _ _ hY X hX) @@ -631,7 +631,7 @@ theorem lcAux₀_apply [FiniteDimensional ℝ E] {x : M} {Z : Π x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : lcAux₀ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by unfold lcAux₀ - rw [TensorialAt.mk2TensorAt_apply _ _ hX hZ, lcAux₀', if_pos hX, if_pos hZ] + rw [TensorialAt.mkHom₂_apply _ _ hX hZ, lcAux₀', if_pos hX, if_pos hZ] noncomputable def lcAux₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : @@ -676,7 +676,7 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : congr! 1 simp only [lcAux₀] ext X₀ Y₀ - simp only [TensorialAt.mk2TensorAt_apply_eq_extend, ContinuousLinearMap.add_apply, lcAux₀'] + simp only [TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, lcAux₀'] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] · apply leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) hY hY' exact mdifferentiableAt_extend .. @@ -704,7 +704,7 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.toSpanSingleton_apply, map_add, map_smul] ext Z₀ - simp only [lcAux₀, lcAux₀', TensorialAt.mk2TensorAt_apply_eq_extend, + simp only [lcAux₀, lcAux₀', TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend E X₀) (Y := Y) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 03e14628b4d2e5..f4e264a3304eda 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -328,7 +328,7 @@ variable {I} in `∇` on a Riemannian manifold `(M, g)` is compatible with the metric `g`. -/ @[no_expose] noncomputable def metricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - TensorialAt.mk2TensorAt (metricTensorAux I cov · · x) + TensorialAt.mkHom₂ (metricTensorAux I cov · · x) (metricTensorAux_tensorial₁ I cov x) (metricTensorAux_tensorial₂ I cov x) variable {I} in @@ -337,7 +337,7 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) metricTensor cov x (Y x) (Z x) (X x) = fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by unfold metricTensor - rw [TensorialAt.mk2TensorAt_apply _ _ hY hZ] + rw [TensorialAt.mkHom₂_apply _ _ hY hZ] simp only [metricTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] conv => diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 0cf9b549d2e6b0..aa143180b31c05 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -111,7 +111,7 @@ end section -variable [CompleteSpace 𝕜] [CompleteSpace E] [FiniteDimensional 𝕜 E] +variable [CompleteSpace E] -- TODO inline the lemmas that go into this theorem torsionAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) (x : M) @@ -127,9 +127,11 @@ theorem torsionAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) (x : M) smul f Y hf hY := hcov.torsionAux_smul_right_apply X hf hY add Y Y' hY hY' := hcov.torsionAux_add_right_apply X hY hY' +variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] + noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := - TensorialAt.mk2TensorAt (torsionAux cov · · x) + TensorialAt.mkHom₂ (torsionAux cov · · x) (fun τ _ ↦ hcov.torsionAux_tensorial₁ x τ) (fun σ _ ↦ hcov.torsionAux_tensorial₂ x σ) @@ -137,7 +139,7 @@ theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : torsion hcov x (X x) (Y x) = torsionAux cov X Y x := - TensorialAt.mk2TensorAt_apply _ _ hX hY + TensorialAt.mkHom₂_apply _ _ hX hY end @@ -159,7 +161,7 @@ noncomputable def torsion := cov.isCovariantDerivativeOn.torsion lemma torsion_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : cov.torsion x (X x) (Y x) = cov Y x (X x) - cov X x (Y x) - mlieBracket I X Y x := by unfold torsion IsCovariantDerivativeOn.torsion - apply TensorialAt.mk2TensorAt_apply + apply TensorialAt.mkHom₂_apply exacts [hX, hY] lemma torsion_apply_extend (u v : TangentSpace I x) : @@ -167,7 +169,7 @@ lemma torsion_apply_extend (u v : TangentSpace I x) : cov (extend E v) x (extend E u x) - cov (extend E u) x (extend E v x) - mlieBracket I (extend E u) (extend E v) x := by unfold torsion IsCovariantDerivativeOn.torsion - apply TensorialAt.mk2TensorAt_apply_eq_extend + apply TensorialAt.mkHom₂_apply_eq_extend /-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ def IsTorsionFree : Prop := torsion cov = 0 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index e7f24a6e65abb4..77b6cac0383d33 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -40,8 +40,7 @@ variable variable {A : Type*} [AddCommGroup A] [Module 𝕜 A] -structure TensorialAt (Φ : (Π x : M, V x) → A) (x : M) : - Prop where +structure TensorialAt (Φ : (Π x : M, V x) → A) (x : M) : Prop where smul : ∀ f : M → 𝕜, ∀ σ : Π x : M, V x, MDiffAt f x → MDiffAt (T% σ) x → Φ (f • σ) = f x • Φ σ add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → Φ (σ + σ') = Φ σ + Φ σ' @@ -133,12 +132,10 @@ lemma pointwise₂ {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ ·) x) - {σ σ' : Π x : M, V x} - {τ τ' : Π x : M, V' x} + {σ σ' : Π x : M, V x} {τ τ' : Π x : M, V' x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) - (hσσ' : σ x = σ' x) - (hττ' : τ x = τ' x) : + (hσσ' : σ x = σ' x) (hττ' : τ x = τ' x) : Φ σ τ = Φ σ' τ' := by trans Φ σ' τ · exact (hΦ₁ _ hτ).pointwise hσ hσ' hσσ' @@ -150,7 +147,7 @@ variable [IsManifold I 1 M] [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] [TopologicalSpace A] [IsTopologicalAddGroup A] [ContinuousSMul 𝕜 A] -noncomputable def mkTensorAt +noncomputable def mkHom -- `Φ` explicit to make it easier to generate the side conditions at point of use (Φ : (Π x : M, V x) → A) (x) (hΦ : TensorialAt I F (Φ) x) : V x →L[𝕜] A := @@ -182,19 +179,18 @@ noncomputable def mkTensorAt · exact mdifferentiable_const .. · exact mdifferentiableAt_extend .. } -theorem mkTensorAt_apply {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F (Φ ·) x) +theorem mkHom_apply {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F (Φ ·) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : - mkTensorAt Φ x hΦ (σ x) = Φ σ := by + mkHom Φ x hΦ (σ x) = Φ σ := by apply hΦ.pointwise _ hσ · simp · exact mdifferentiableAt_extend .. -theorem mkTensorAt_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F Φ x) - (σ : V x) : - mkTensorAt Φ x hΦ σ = Φ (_root_.extend F σ) := +theorem mkHom_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F Φ x) (σ : V x) : + mkHom Φ x hΦ σ = Φ (_root_.extend F σ) := rfl -noncomputable def mk2TensorAt +noncomputable def mkHom₂ -- `φ` explicit to make it easier to generate the side conditions at point of use (φ : (Π x : M, V x) → (Π x : M, V' x) → A) {x} (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) @@ -266,25 +262,24 @@ noncomputable def mk2TensorAt · exact mdifferentiableAt_extend .. } H.toContinuousLinearMap -theorem mk2TensorAt_apply +theorem mkHom₂_apply {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : - mk2TensorAt φ hφ₁ hφ₂ (σ x) (τ x) = φ σ τ := by + mkHom₂ φ hφ₁ hφ₂ (σ x) (τ x) = φ σ τ := by apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ hσ _ hτ · simp · simp · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. -theorem mk2TensorAt_apply_eq_extend +theorem mkHom₂_apply_eq_extend {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) (σ : V x) (τ : V' x) : - mk2TensorAt φ hφ₁ hφ₂ σ τ - = φ (_root_.extend F σ) (_root_.extend F' τ) := + mkHom₂ φ hφ₁ hφ₂ σ τ = φ (_root_.extend F σ) (_root_.extend F' τ) := rfl variable @@ -302,14 +297,14 @@ variable [∀ x : M, TopologicalSpace (W x)] [∀ x, IsTopologicalAddGroup (W x)] [∀ x, ContinuousSMul 𝕜 (W x)] [TopologicalSpace (TotalSpace G W)] [FiberBundle G W] [VectorBundle 𝕜 G W] -theorem contMDiff_mkTensorAt +theorem contMDiff_mkHom (φ : (Π x : M, V x) → (Π x, W x)) (hφ : ∀ x, TensorialAt I F (φ · x) x) -- hopefully this is the correct smoothness criterion! {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : -- elaborators not working here let T (x : M) : TotalSpace (F →L[𝕜] G) (fun x ↦ V x →L[𝕜] W x) := - ⟨x, mkTensorAt (φ · x) x (hφ x)⟩ + ⟨x, mkHom (φ · x) x (hφ x)⟩ ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] G)) k T := by sorry From 2f60ee68084a62fe97c9a9ca4f1d8f6ed6b32955 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:41:43 +0000 Subject: [PATCH 533/601] merge master --- Mathlib.lean | 1 - .../VectorBundle/IsBilinearPrelim.lean | 75 ------------------- .../Manifold/VectorBundle/Tensoriality.lean | 4 +- 3 files changed, 2 insertions(+), 78 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean diff --git a/Mathlib.lean b/Mathlib.lean index c0aed95d37593a..388ace741a8650 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4434,7 +4434,6 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho public import Mathlib.Geometry.Manifold.VectorBundle.Hom -public import Mathlib.Geometry.Manifold.VectorBundle.IsBilinearPrelim public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame diff --git a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean deleted file mode 100644 index 44589a9386ecfc..00000000000000 --- a/Mathlib/Geometry/Manifold/VectorBundle/IsBilinearPrelim.lean +++ /dev/null @@ -1,75 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ -module - -public import Mathlib.Topology.Algebra.Module.FiniteDimension -public import Mathlib.Topology.Algebra.Module.StrongTopology - -/-! -# Bilinear map pre-requisites for covariant derivatives - -PRed as #36193 - --/ - -@[expose] public section -- TODO: think if we want to expose all definitions! - -section -- Building continuous bilinear maps - -structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] - [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] - [Module R E] [Module R F] [Module R G] (f : E → F → G) : Prop where - add_left : ∀ (x₁ x₂ : E) (y : F), f (x₁ + x₂) y = f x₁ y + f x₂ y - smul_left : ∀ (c : R) (x : E) (y : F), f (c • x) y = c • f x y - add_right : ∀ (x : E) (y₁ y₂ : F), f x (y₁ + y₂) = f x y₁ + f x y₂ - smul_right : ∀ (c : R) (x : E) (y : F), f x (c • y) = c • f x y - -def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] - [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] - [Module R E] [Module R F] [Module R G] {f : E → F → G} (hf : IsBilinearMap R f) : - E →ₗ[R] F →ₗ[R] G := - LinearMap.mk₂ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right - -lemma isBilinearMap_eval (R : Type*) (E F : Type*) [CommSemiring R] - [AddCommMonoid E] [AddCommMonoid F] [Module R E] [Module R F] : - IsBilinearMap R (fun (e : E) (φ : E →ₗ[R] F) ↦ φ e) := by - constructor <;> simp - -def IsBilinearMap.toContinuousLinearMap - {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - {E : Type*} [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - {F : Type*} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] - {G : Type*} [AddCommGroup G] [Module 𝕜 G] [TopologicalSpace G] - [IsTopologicalAddGroup G] [ContinuousSMul 𝕜 G] - {f : E → F → G} (h : IsBilinearMap 𝕜 f) : E →L[𝕜] F →L[𝕜] G := - IsLinearMap.mk' (fun x : E ↦ h.toLinearMap x |>.toContinuousLinearMap) - (by constructor <;> (intros;simp)) |>.toContinuousLinearMap - -def isBilinearMap_evalL - (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] : - IsBilinearMap 𝕜 (fun (e : E) (φ : E →L[𝕜] F) ↦ φ e) := by - constructor <;> simp - -def evalL - (𝕜 : Type*) [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] - (E : Type*) [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E] - [IsTopologicalAddGroup E] [ContinuousSMul 𝕜 E] [FiniteDimensional 𝕜 E] - [T2Space E] - (F : Type*) [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] - [IsTopologicalAddGroup F] [ContinuousSMul 𝕜 F] [FiniteDimensional 𝕜 F] - [T2Space F] : E →L[𝕜] (E →L[𝕜] F) →L[𝕜] F := - (isBilinearMap_evalL 𝕜 E F).toContinuousLinearMap -end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 77b6cac0383d33..9f8ee8bf1c4125 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -7,8 +7,8 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.Extend +public import Mathlib.Topology.Algebra.Module.FiniteDimensionBilinear import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame -public import Mathlib.Geometry.Manifold.VectorBundle.IsBilinearPrelim /-! # The tensoriality criterion @@ -260,7 +260,7 @@ noncomputable def mkHom₂ · exact mdifferentiable_const .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. } - H.toContinuousLinearMap + H.toLinearMap.toContinuousBilinearMap theorem mkHom₂_apply {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} From 075ab0022f75858b35c01301b2ce306adc7b29b1 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:52:40 +0000 Subject: [PATCH 534/601] reorg imports --- .../CovariantDerivative/Basic.lean | 1 + .../Geometry/Manifold/VectorBundle/Hom.lean | 17 ++++++++++++ .../Manifold/VectorBundle/Tensoriality.lean | 27 ------------------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 941639272961fb..bd27316af010ad 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -5,6 +5,7 @@ Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module +public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Geometry.Manifold.MfDerivSMul diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index 090fe8851e7ff6..4ebf660eaece68 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -6,6 +6,7 @@ Authors: Floris van Doorn module public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Topology.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable @@ -307,6 +308,22 @@ lemma ContMDiff.clm_bundle_apply ContMDiff IM (IB.prod 𝓘(𝕜, F₂)) n (fun m ↦ TotalSpace.mk' F₂ (b m) (ϕ m (v m))) := fun x ↦ (hϕ x).clm_bundle_apply (hv x) +/-- Criterion for a section of a Hom-bundle constructed using the tensoriality criterion to be +smooth. -/ +theorem TensorialAt.contMDiff_mkHom [CompleteSpace 𝕜] [IsManifold IB 1 B] + [FiniteDimensional 𝕜 F₁] + [∀ (x : B), IsTopologicalAddGroup (E₁ x)] [∀ (x : B), ContinuousSMul 𝕜 (E₁ x)] + [ContMDiffVectorBundle 1 F₁ E₁ IB] + (φ : (Π x : B, E₁ x) → (Π x, E₂ x)) + (hφ : ∀ x, TensorialAt IB F₁ (φ · x) x) + -- hopefully this is the correct smoothness criterion! + {k} (φ_contMDiff : ∀ (σ : Π x : B, E₁ x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : + -- elaborators not working here + let T (x : B) : TotalSpace (F₁ →L[𝕜] F₂) (fun x ↦ E₁ x →L[𝕜] E₂ x) := + ⟨x, TensorialAt.mkHom (φ · x) x (hφ x)⟩ + ContMDiff IB (IB.prod 𝓘(𝕜, F₁ →L[𝕜] F₂)) k T := by + sorry + end OneVariable section OneVariable' diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 9f8ee8bf1c4125..bb4b45ead291c0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -5,7 +5,6 @@ Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Topology.Algebra.Module.FiniteDimensionBilinear import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame @@ -282,30 +281,4 @@ theorem mkHom₂_apply_eq_extend mkHom₂ φ hφ₁ hφ₂ σ τ = φ (_root_.extend F σ) (_root_.extend F' τ) := rfl -variable - -- TODO can probably remove the next two hypotheses, by transport - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] - -variable - -- TODO can probably remove the next two hypotheses, by transport - [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] - -variable - (G : Type*) [NormedAddCommGroup G] [NormedSpace 𝕜 G] - {W : M → Type*} [∀ x, AddCommGroup (W x)] [∀ x, Module 𝕜 (W x)] - -- TODO can probably remove the next three hypotheses, by transport - [∀ x : M, TopologicalSpace (W x)] [∀ x, IsTopologicalAddGroup (W x)] [∀ x, ContinuousSMul 𝕜 (W x)] - [TopologicalSpace (TotalSpace G W)] [FiberBundle G W] [VectorBundle 𝕜 G W] - -theorem contMDiff_mkHom - (φ : (Π x : M, V x) → (Π x, W x)) - (hφ : ∀ x, TensorialAt I F (φ · x) x) - -- hopefully this is the correct smoothness criterion! - {k} (φ_contMDiff : ∀ (σ : Π x : M, V x), CMDiff k (T% σ) → CMDiff k (T% (φ σ))) : - -- elaborators not working here - let T (x : M) : TotalSpace (F →L[𝕜] G) (fun x ↦ V x →L[𝕜] W x) := - ⟨x, mkHom (φ · x) x (hφ x)⟩ - ContMDiff I (I.prod 𝓘(𝕜, F →L[𝕜] G)) k T := by - sorry - end TensorialAt From ca18f232ab59ed78fc187a2a0e94273e915946aa Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:34:53 +0000 Subject: [PATCH 535/601] clean up and document tensoriality file --- .../CovariantDerivative/Basic.lean | 4 +- .../CovariantDerivative/LeviCivita.lean | 8 +- .../CovariantDerivative/Metric.lean | 10 +- .../CovariantDerivative/Torsion.lean | 10 +- .../Manifold/VectorBundle/Tensoriality.lean | 120 +++++++++--------- 5 files changed, 79 insertions(+), 73 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index bd27316af010ad..b7a0314a9971a7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -269,10 +269,10 @@ variable theorem differenceAux_tensorial (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) (x : M) (hx : x ∈ s) : TensorialAt I F (differenceAux cov cov' · x) x where - smul f σ hf hσ := by + smul hf hσ := by simp [differenceAux, hcov.leibniz hσ hf, hcov'.leibniz hσ hf] module - add σ σ' hσ hσ' := by + add hσ hσ' := by simp [differenceAux, hcov.add hσ hσ', hcov'.add hσ hσ'] abel diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 0e8dbe1b60678b..f97400cacd5fc7 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -587,14 +587,14 @@ noncomputable def lcAux₀' (Y : Π x : M, TangentSpace I x) (x : M) theorem leviCivitaRhs_tensorial₁ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) (Z : Π x, TangentSpace I x) : TensorialAt I E (lcAux₀' I Y x · Z x) x where - smul f X hf hX := by + smul hf hX := by dsimp [lcAux₀'] rw [if_pos hX, if_pos] · split_ifs with hZ · exact leviCivitaRhs_smulX_apply hf hX hY hZ · simp · exact hf.smul_section hX - add X₁ X₂ hX₁ hX₂ := by + add hX₁ hX₂ := by dsimp [lcAux₀'] rw [if_pos hX₁, if_pos hX₂, if_pos] · split_ifs with hZ @@ -606,12 +606,12 @@ theorem leviCivitaRhs_tensorial₂ [FiniteDimensional ℝ E] {Y : Π x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) (X : Π x, TangentSpace I x) (hX : MDiffAt (T% X) x) : TensorialAt I E (lcAux₀' I Y x X · x) x where - smul f Z hf hZ := by + smul hf hZ := by dsimp [lcAux₀'] rw [if_pos hX, if_pos hZ, if_pos, if_pos hX] · exact leviCivitaRhs_smulZ_apply I hf hX hY hZ · exact hf.smul_section hZ - add Z₁ Z₂ hZ₁ hZ₂ := by + add hZ₁ hZ₂ := by dsimp [lcAux₀'] rw [if_pos hZ₁, if_pos hZ₂, if_pos hX, if_pos, if_pos hX, if_pos hX] · exact leviCivitaRhs_addZ_apply I hX hY hZ₁ hZ₂ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index f4e264a3304eda..e04d664e46b086 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -315,20 +315,20 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) theorem metricTensorAux_tensorial₁ (x : M) (τ : Π x, TangentSpace I x) (hτ : MDiffAt (T% τ) x) : TensorialAt I E (metricTensorAux I cov · τ x) x where - smul _ _ hf hσ := aux1 cov hf hσ hτ - add σ σ' hσ hσ' := aux2 cov σ σ' τ hσ hσ' hτ + smul hf hσ := aux1 cov hf hσ hτ + add hσ hσ' := aux2 cov _ _ _ hσ hσ' hτ theorem metricTensorAux_tensorial₂ (x : M) (σ : Π x, TangentSpace I x) (hσ : MDiffAt (T% σ) x) : TensorialAt I E (metricTensorAux I cov σ · x) x where - smul _ _ hf hτ := aux3 cov hf hσ hτ - add τ τ' hτ hτ' := aux4 cov σ τ τ' hσ hτ hτ' + smul hf hτ := aux3 cov hf hσ hτ + add hτ hτ' := aux4 cov _ _ _ hσ hτ hτ' variable {I} in /-- The tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection `∇` on a Riemannian manifold `(M, g)` is compatible with the metric `g`. -/ @[no_expose] noncomputable def metricTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - TensorialAt.mkHom₂ (metricTensorAux I cov · · x) + TensorialAt.mkHom₂ (metricTensorAux I cov · · x) _ (metricTensorAux_tensorial₁ I cov x) (metricTensorAux_tensorial₂ I cov x) variable {I} in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index aa143180b31c05..e3914f85ff30ea 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -117,21 +117,21 @@ variable [CompleteSpace E] theorem torsionAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) (x : M) (Y : Π x, TangentSpace I x) : TensorialAt I E (torsionAux cov · Y x) x where - smul f X hf hX := hcov.torsionAux_smul_left_apply Y hf hX - add X X' hX hX' := hcov.torsionAux_add_left_apply Y hX hX' + smul hf hX := hcov.torsionAux_smul_left_apply Y hf hX + add hX hX' := hcov.torsionAux_add_left_apply Y hX hX' -- TODO inline the lemmas that go into this theorem torsionAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) (x : M) (X : Π x, TangentSpace I x) : TensorialAt I E (torsionAux cov X · x) x where - smul f Y hf hY := hcov.torsionAux_smul_right_apply X hf hY - add Y Y' hY hY' := hcov.torsionAux_add_right_apply X hY hY' + smul hf hY := hcov.torsionAux_smul_right_apply X hf hY + add hY hY' := hcov.torsionAux_add_right_apply X hY hY' variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := - TensorialAt.mkHom₂ (torsionAux cov · · x) + TensorialAt.mkHom₂ (torsionAux cov · · x) _ (fun τ _ ↦ hcov.torsionAux_tensorial₁ x τ) (fun σ _ ↦ hcov.torsionAux_tensorial₂ x σ) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index bb4b45ead291c0..42b360a9def854 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -13,9 +13,9 @@ import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame # The tensoriality criterion -/ -open Bundle Filter Function Topology Module +open Bundle Topology Module -open scoped Bundle Manifold ContDiff +open scoped Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! @@ -39,20 +39,29 @@ variable variable {A : Type*} [AddCommGroup A] [Module 𝕜 A] +/-- An operation `Φ` on sections of a vector bundle `V` over `M` is *tensorial* at `x : M`, if it +respects addition and scalar multiplication by germs of diffentiable functions at `f`. -/ structure TensorialAt (Φ : (Π x : M, V x) → A) (x : M) : Prop where - smul : ∀ f : M → 𝕜, ∀ σ : Π x : M, V x, MDiffAt f x → MDiffAt (T% σ) x → Φ (f • σ) = f x • Φ σ - add : ∀ σ σ', MDiffAt (T% σ) x → MDiffAt (T% σ') x → Φ (σ + σ') = Φ σ + Φ σ' + smul : ∀ {f : M → 𝕜} {σ : Π x : M, V x}, MDiffAt f x → MDiffAt (T% σ) x → Φ (f • σ) = f x • Φ σ + add : ∀ {σ σ'}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → Φ (σ + σ') = Φ σ + Φ σ' variable {Φ : (Π x : M, V x) → A} {x : M} variable {I F F'} namespace TensorialAt -theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} +/-- If the operation `Φ` on sections of a vector bundle `V` is tensorial at `x`, then it depends +only on the germ of the section at `x`. + +This is later superseded by `TensorialAt.pointwise`, showing that `Φ` depends only on the value at +`x` itself. -/ +protected theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : Φ σ = Φ σ' := by classical rw [eventually_nhds_iff] at hσσ' + -- Introduce the indicator function of a neighbourhood `t` of `x` on which equality holds, + -- and cut off the two sections `σ` and `σ'` using this indicator function. obtain ⟨t, htσσ', ht, hxt⟩ := hσσ' let ψ (x' : M) : 𝕜 := if x' ∈ t then 1 else 0 have hψx : ψ x = 1 := by simp [ψ, hxt] @@ -67,12 +76,14 @@ theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} apply eventually_nhds_iff.mpr exact ⟨t, by simp [ψ], ht, hxt⟩ calc Φ σ - _ = Φ (ψ • σ) := by simp [hΦ.smul _ _ hψ' hσ, hψx] + _ = Φ (ψ • σ) := by simp [hΦ.smul hψ' hσ, hψx] _ = Φ (ψ • σ') := by rw [funext this] - _ = Φ σ' := by simp [hΦ.smul _ _ hψ' hσ', hψx] + _ = Φ σ' := by simp [hΦ.smul hψ' hσ', hψx] variable [VectorBundle 𝕜 F V] [VectorBundle 𝕜 F' V'] +/-- A tensorial operation on sections of a vector bundle respects sums (since it respects binary +addition). -/ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι → Π x : M, V x) (hσ : ∀ i, MDiffAt (T% (σ i)) x) : Φ (fun x' ↦ ∑ i ∈ s, σ i x') = ∑ i ∈ s, Φ (σ i) := by @@ -81,20 +92,20 @@ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι | empty => simp only [Finset.sum_empty] have h₁ : MDiffAt (fun x' : M ↦ (0 : 𝕜)) x := mdifferentiableAt_const - rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → 𝕜) • fun x' ↦ 0 by simp;rfl] - rw [hΦ.smul] + rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → 𝕜) • fun x' ↦ 0 by simp; rfl, hΦ.smul] · simp · exact h₁ - -- TODO: add mdifferentiable_zeroSection and/or use it! - apply (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero + · exact mdifferentiable_zeroSection .. | insert a s ha h => change Φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') = _ simp only [Finset.sum_insert ha, ← h] - exact hΦ.add _ _ (hσ a) (.sum_section hσ) + exact hΦ.add (hσ a) (.sum_section hσ) variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 F'] [ContMDiffVectorBundle 1 F V I] [ContMDiffVectorBundle 1 F' V' I] +/-- If the operation `Φ` on sections of a vector bundle `V` is tensorial at `x`, then it depends +only on the value of the section at `x`. -/ lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : σ x = σ' x) : Φ σ = Φ σ' := by @@ -111,22 +122,26 @@ lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} have hc {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) (i) : MDiffAt (LinearMap.piApply (c i) σ) x := mdifferentiableAt_localFrame_coeff b x_mem hσ i - -- By the locality of the operation `(Φ · x)`, its value a + -- By the locality of the operation `(Φ · x)`, its value on `σ` agrees with the value of `Φ` on + -- the expansion of `σ` into coefficients relative to the frame. have hΦ_eq {σ : (x : M) → V x} (hσ : MDiffAt (T% σ) x) : - Φ σ = Φ (fun x' ↦ ∑ i, LinearMap.piApply (c i) σ x' • s i x') := + Φ σ = Φ (fun x' ↦ ∑ i, c i x' (σ x') • s i x') := hΦ.local hσ (.sum_section fun i ↦ (hc hσ i).smul_section (hs i)) (t.eventually_eq_localFrame_sum_coeff_smul b x_mem) + -- Now evaluate using the tensoriality properties. rw [hΦ_eq hσ, hΦ_eq hσ', hΦ.sum, hΦ.sum] · congr! 1 with i calc Φ ((LinearMap.piApply (c i) σ) • (s i)) - = c i x (σ x) • Φ (s i) := hΦ.smul _ _ (hc hσ i) (hs i) + = c i x (σ x) • Φ (s i) := hΦ.smul (hc hσ i) (hs i) _ = c i x (σ' x) • Φ (s i) := by rw [hσσ'] _ = Φ ((LinearMap.piApply (c i) σ') • (s i)) := - hΦ.smul _ _ (hc hσ' i) (hs i) |>.symm + hΦ.smul (hc hσ' i) (hs i) |>.symm · exact fun i ↦ (hc hσ' i).smul_section (hs i) · exact fun i ↦ (hc hσ i).smul_section (hs i) +/-- If the operation `Φ` on sections of vector bundles `V` and `V'` is tensorial in each argument at +`x`, then it depends only on the value of the sections at `x`. -/ lemma pointwise₂ {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) @@ -141,14 +156,19 @@ lemma pointwise₂ · exact (hΦ₂ _ hσ').pointwise hτ hτ' hττ' variable [IsManifold I 1 M] - -- TODO can probably remove the next four hypotheses, by transport + -- TODO prove transport lemmas `ContinuousLinearEquiv.IsTopologicalAddGroup` and + -- `ContinuousLinearEquiv.continuousSMul`, then the next four hypotheses can be removed + -- (and the appropriate instances constructed in the proof of `TensorialAt.mkHom` by transport + -- from the model fibre.) [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] [TopologicalSpace A] [IsTopologicalAddGroup A] [ContinuousSMul 𝕜 A] +/-- Given an `A`-valued operation `Φ` on sections of a vector bundle `V` which is tensorial at `x`, +the construction `TensorialAt.mkHom` provides the associated continuous linear map `V x →L[𝕜] A`. -/ noncomputable def mkHom - -- `Φ` explicit to make it easier to generate the side conditions at point of use - (Φ : (Π x : M, V x) → A) (x) (hΦ : TensorialAt I F (Φ) x) : + -- `Φ` and `x` explicit to make it easier to generate the side condition at point of use + (Φ : (Π x : M, V x) → A) (x : M) (hΦ : TensorialAt I F (Φ) x) : V x →L[𝕜] A := let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x (FiberBundle.mem_baseSet_trivializationAt' x) @@ -157,41 +177,32 @@ noncomputable def mkHom LinearMap.toContinuousLinearMap { toFun v := Φ (_root_.extend F v) map_add' v₁ v₂ := by - rw [← hΦ.add] - · apply hΦ.pointwise - · exact mdifferentiableAt_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + rw [← hΦ.add (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..)] + apply hΦ.pointwise (mdifferentiableAt_extend ..) <| + mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) + simp map_smul' c v := by dsimp - rw [← hΦ.smul (fun _ ↦ c)] - · apply hΦ.pointwise - · exact mdifferentiableAt_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiable_const .. - · exact mdifferentiableAt_extend .. } + rw [← hΦ.smul (f := fun _ ↦ c) (mdifferentiable_const ..) (mdifferentiableAt_extend ..)] + apply hΦ.pointwise (mdifferentiableAt_extend ..) <| + mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..) + simp } theorem mkHom_apply {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F (Φ ·) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : - mkHom Φ x hΦ (σ x) = Φ σ := by - apply hΦ.pointwise _ hσ - · simp - · exact mdifferentiableAt_extend .. + mkHom Φ x hΦ (σ x) = Φ σ := + hΦ.pointwise (mdifferentiableAt_extend ..) hσ (by simp) theorem mkHom_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F Φ x) (σ : V x) : mkHom Φ x hΦ σ = Φ (_root_.extend F σ) := rfl +/-- Given an `A`-valued operation `Φ` on sections of vector bundles `V` and `V'` which is tensorial +at `x`, the construction `TensorialAt.mkHom₂` provides the associated continuous linear map +`V x →L[𝕜] V' x →L[𝕜] A`. -/ noncomputable def mkHom₂ - -- `φ` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x : M, V' x) → A) {x} + -- `φ` and `x` explicit to make it easier to generate the side conditions at point of use + (φ : (Π x : M, V x) → (Π x : M, V' x) → A) (x : M) (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) : V x →L[𝕜] V' x →L[𝕜] A := @@ -206,18 +217,13 @@ noncomputable def mkHom₂ have H : IsBilinearMap 𝕜 (fun (v : V x) (w : V' x) ↦ φ (_root_.extend F v) (_root_.extend F' w)) := { add_left v₁ v₂ w := by - rw [← (hφ₁ _ _).add] - · apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ _ _ _ _ rfl - · exact mdifferentiableAt_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + rw [← (hφ₁ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hφ₁ hφ₂ (mdifferentiableAt_extend ..) _ + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) _ rfl + · exact mdifferentiableAt_add_section (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..) + · simp smul_left c v w := by rw [← (hφ₁ _ _).smul (f := fun _ ↦ c)] · apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ _ _ _ _ rfl @@ -266,7 +272,7 @@ theorem mkHom₂_apply (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : - mkHom₂ φ hφ₁ hφ₂ (σ x) (τ x) = φ σ τ := by + mkHom₂ φ x hφ₁ hφ₂ (σ x) (τ x) = φ σ τ := by apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ hσ _ hτ · simp · simp @@ -278,7 +284,7 @@ theorem mkHom₂_apply_eq_extend (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) (σ : V x) (τ : V' x) : - mkHom₂ φ hφ₁ hφ₂ σ τ = φ (_root_.extend F σ) (_root_.extend F' τ) := + mkHom₂ φ x hφ₁ hφ₂ σ τ = φ (_root_.extend F σ) (_root_.extend F' τ) := rfl end TensorialAt From 0c68f8c340966b98fc1c28d4d6c9ee345b6a745b Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:43:37 +0000 Subject: [PATCH 536/601] more cleanup in tensoriality --- .../Manifold/VectorBundle/Tensoriality.lean | 106 +++++++----------- 1 file changed, 43 insertions(+), 63 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 42b360a9def854..48bc029aadb1fb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -17,7 +17,7 @@ open Bundle Topology Module open scoped Manifold ContDiff -@[expose] public section -- TODO: think if we want to expose all definitions! +@[expose] public section variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] @@ -140,8 +140,8 @@ lemma pointwise (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x} · exact fun i ↦ (hc hσ' i).smul_section (hs i) · exact fun i ↦ (hc hσ i).smul_section (hs i) -/-- If the operation `Φ` on sections of vector bundles `V` and `V'` is tensorial in each argument at -`x`, then it depends only on the value of the sections at `x`. -/ +/-- If the operation `Φ` on sections of vector bundles `V` and `V'` is tensorial at `x` in each +argument, then it depends only on the value of the sections at `x`. -/ lemma pointwise₂ {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) @@ -198,13 +198,13 @@ theorem mkHom_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialA rfl /-- Given an `A`-valued operation `Φ` on sections of vector bundles `V` and `V'` which is tensorial -at `x`, the construction `TensorialAt.mkHom₂` provides the associated continuous linear map -`V x →L[𝕜] V' x →L[𝕜] A`. -/ +at `x` in each argument, the construction `TensorialAt.mkHom₂` provides the associated continuous +linear map `V x →L[𝕜] V' x →L[𝕜] A`. -/ noncomputable def mkHom₂ - -- `φ` and `x` explicit to make it easier to generate the side conditions at point of use - (φ : (Π x : M, V x) → (Π x : M, V' x) → A) (x : M) - (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) - (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) : + -- `Φ` and `x` explicit to make it easier to generate the side conditions at point of use + (Φ : (Π x : M, V x) → (Π x : M, V' x) → A) (x : M) + (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) + (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) : V x →L[𝕜] V' x →L[𝕜] A := let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x (FiberBundle.mem_baseSet_trivializationAt' x) @@ -215,76 +215,56 @@ noncomputable def mkHom₂ have : T2Space (V' x) := Ψ'.symm.toHomeomorph.t2Space have : FiniteDimensional 𝕜 (V' x) := Ψ'.symm.toLinearEquiv.finiteDimensional have H : IsBilinearMap 𝕜 - (fun (v : V x) (w : V' x) ↦ φ (_root_.extend F v) (_root_.extend F' w)) := + (fun (v : V x) (w : V' x) ↦ Φ (_root_.extend F v) (_root_.extend F' w)) := { add_left v₁ v₂ w := by - rw [← (hφ₁ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) + rw [← (hΦ₁ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hφ₁ hφ₂ (mdifferentiableAt_extend ..) _ + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) _ (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) _ rfl · exact mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) · simp smul_left c v w := by - rw [← (hφ₁ _ _).smul (f := fun _ ↦ c)] - · apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ _ _ _ _ rfl - · exact mdifferentiableAt_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · simp - · exact mdifferentiable_const .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + rw [← (hΦ₁ _ (mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) (mdifferentiable_const ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) + (mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..)) + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) + · simp + · rfl add_right v w₁ w₂ := by - rw [← (hφ₂ _ _).add] - · apply TensorialAt.pointwise₂ hφ₁ hφ₂ - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · apply mdifferentiableAt_add_section - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · rfl - · simp - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + rw [← (hΦ₂ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) <| + mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) + · rfl + · simp smul_right c v w := by - rw [← (hφ₂ _ _).smul (f := fun _ ↦ c)] - · apply TensorialAt.pointwise₂ hφ₁ hφ₂ - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · apply MDifferentiableAt.smul_section - · exact mdifferentiableAt_const - · exact mdifferentiableAt_extend .. - · rfl - · simp - · exact mdifferentiable_const .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. } + rw [← (hΦ₂ _ (mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) (mdifferentiable_const ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) <| + mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..) + · rfl + · simp } H.toLinearMap.toContinuousBilinearMap theorem mkHom₂_apply - {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} - (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) - (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) + {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} + (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) + (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : - mkHom₂ φ x hφ₁ hφ₂ (σ x) (τ x) = φ σ τ := by - apply TensorialAt.pointwise₂ hφ₁ hφ₂ _ hσ _ hτ - · simp - · simp - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + mkHom₂ Φ x hΦ₁ hΦ₂ (σ x) (τ x) = Φ σ τ := + TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) hσ (mdifferentiableAt_extend ..) hτ + (by simp) (by simp) theorem mkHom₂_apply_eq_extend - {φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} - (hφ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (φ · τ) x) - (hφ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (φ σ) x) + {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} + (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) + (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) (σ : V x) (τ : V' x) : - mkHom₂ φ x hφ₁ hφ₂ σ τ = φ (_root_.extend F σ) (_root_.extend F' τ) := + mkHom₂ Φ x hΦ₁ hΦ₂ σ τ = Φ (_root_.extend F σ) (_root_.extend F' τ) := rfl end TensorialAt From 821121f3550fc12c8f37f6e8828d9b75027692b6 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:53:04 +0000 Subject: [PATCH 537/601] module docstring for tensoriality --- .../Manifold/VectorBundle/Tensoriality.lean | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 48bc029aadb1fb..3c62b600c76775 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -12,6 +12,25 @@ import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame /-! # The tensoriality criterion +Given vector bundles `V` and `W` over a manifold `M`, one can construct a section of the hom-bundle +`Π x, V x →L[𝕜] W x` from a *tensorial* operation sending sections of `V` to sections of `W`. +This file provides this construction. + +In fact, we define tensoriality, and provide the above criterion, in slightly greater generality: +for operations sending sections of `V` to a vector space `A` (which in the above application is the +fibre `W x`), the construction produces a continuous linear map `V x →L[𝕜] A`. + +## Main definitions + +* `TensorialAt`: Propositional structure stating that an operation on sections of a vector bundle + `V` is tensorial. + +* `TensorialAt.mkHom`: An operation on sections of `V` which is tensorial at `x` defines a + continuous linear map out of `V x`. + +* `TensorialAt.mkHom₂`: An operation on sections of `V` and `V'` which is tensorial at `x` in both + arguments defines a continuous bilinear map out of `V x` and `V' x`. + -/ open Bundle Topology Module From 56e107c2d32d0362b32befa48bbdbfce74f4d5be Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 15:04:20 +0000 Subject: [PATCH 538/601] chore: rename metricTensor -> compatibilityTensor --- .../CovariantDerivative/Metric.lean | 91 ++++++++++--------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index e04d664e46b086..46e6d12eb48ec3 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -17,14 +17,15 @@ vanishes on all differentiable vector fields. ## Main definitions and results -* `CovariantDerivative.metricTensor`: the tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` - defining when a connection `∇` on a Riemannian manifold `(M, g)` is compatible with the metric - `g`. -* `CovariantDerivative.metricTensor_apply` and `CovariantDerivative.metricTensor_apply` give - formulas for applying the metric tensor at `x` to vector fields which are differentiable at `x`, +* `CovariantDerivative.compatibilityTensor`: the tensor + `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection `∇` on a Riemannian + manifold `(M, g)` is compatible with the metric `g`. +* `CovariantDerivative.compatibilityTensor_apply` and + `CovariantDerivative.compatibilityTensor_apply` give formulas for applying the compatibility + tensor at `x` to vector fields which are differentiable at `x`, resp. to extensions of tangent vectors at `x` to differentiable vector fields near `x`. * `CovariantDerivative.IsCompatible`: predicate for a connection to be metric - `∇` is metric iff its `metricTensor` vanishes + `∇` is metric iff its `compatibilityTensor` vanishes ## TODO * when mathlib has a notion of parallel transport, define metric connections on general @@ -33,10 +34,10 @@ vanishes on all differentiable vector fields. -/ -open Bundle Filter Function Module NormedSpace Topology +open Bundle Function NormedSpace open scoped Manifold ContDiff -@[expose] public section -- TODO: think if we want to expose all definitions! +@[expose] public section -- TODO: revisit and fix this once the dust has settled set_option backward.isDefEq.respectTransparency false @@ -180,20 +181,20 @@ variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) /-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) -/-- The function defining the metric or compatibility tensor `∇ g`: -prefer using `metricTensor` instead -/ -noncomputable def metricTensorAux (Y Z : Π x : M, TangentSpace I x) : +/-- The function defining the compatibility tensor for `∇` w.r.t. `g`: +prefer using `compatibilityTensor` instead -/ +noncomputable def compatibilityTensorAux (Y Z : Π x : M, TangentSpace I x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x : M} variable {I} in -private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} +private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - metricTensorAux I cov (f • σ) τ x = f x • metricTensorAux I cov σ τ x := by - unfold metricTensorAux + compatibilityTensorAux I cov (f • σ) τ x = f x • compatibilityTensorAux I cov σ τ x := by + unfold compatibilityTensorAux rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] ext X simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, @@ -221,11 +222,11 @@ private lemma aux1 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x ring variable {I} in -private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) +private lemma aux2 (σ σ' τ : (x : M) → TangentSpace I x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : - metricTensorAux I cov (σ + σ') τ x = - metricTensorAux I cov σ τ x + metricTensorAux I cov σ' τ x := by - simp only [metricTensorAux] + compatibilityTensorAux I cov (σ + σ') τ x = + compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ' τ x := by + simp only [compatibilityTensorAux] ext X simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] @@ -249,10 +250,10 @@ private lemma aux2 {x : M} (σ σ' τ : (x : M) → TangentSpace I x) module variable {I} in -private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} +private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - metricTensorAux I cov σ (f • τ) x = f x • metricTensorAux I cov σ τ x := by - unfold metricTensorAux + compatibilityTensorAux I cov σ (f • τ) x = f x • compatibilityTensorAux I cov σ τ x := by + unfold compatibilityTensorAux rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] ext X simp only [smul_eq_mul, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, @@ -282,11 +283,11 @@ private lemma aux3 {x : M} {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x match_scalars <;> all_goals simp variable {I} in -private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) +private lemma aux4 (σ τ τ' : (x : M) → TangentSpace I x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : - metricTensorAux I cov σ (τ + τ') x = - metricTensorAux I cov σ τ x + metricTensorAux I cov σ τ' x := by - unfold metricTensorAux + compatibilityTensorAux I cov σ (τ + τ') x = + compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ τ' x := by + unfold compatibilityTensorAux ext X simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, @@ -313,32 +314,32 @@ private lemma aux4 {x : M} (σ τ τ' : (x : M) → TangentSpace I x) -- set C' := inner ℝ (σ x) ((cov τ' x) X) -- set D := (cov σ x) X -theorem metricTensorAux_tensorial₁ (x : M) (τ : Π x, TangentSpace I x) (hτ : MDiffAt (T% τ) x) : - TensorialAt I E (metricTensorAux I cov · τ x) x where +theorem compatibilityTensorAux_tensorial₁ (τ : Π x, TangentSpace I x) (hτ : MDiffAt (T% τ) x) : + TensorialAt I E (compatibilityTensorAux I cov · τ x) x where smul hf hσ := aux1 cov hf hσ hτ add hσ hσ' := aux2 cov _ _ _ hσ hσ' hτ -theorem metricTensorAux_tensorial₂ (x : M) (σ : Π x, TangentSpace I x) (hσ : MDiffAt (T% σ) x) : - TensorialAt I E (metricTensorAux I cov σ · x) x where +theorem compatibilityTensorAux_tensorial₂ (σ : Π x, TangentSpace I x) (hσ : MDiffAt (T% σ) x) : + TensorialAt I E (compatibilityTensorAux I cov σ · x) x where smul hf hτ := aux3 cov hf hσ hτ add hτ hτ' := aux4 cov _ _ _ hσ hτ hτ' variable {I} in /-- The tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection `∇` on a Riemannian manifold `(M, g)` is compatible with the metric `g`. -/ -@[no_expose] noncomputable def metricTensor [FiniteDimensional ℝ E] (x : M) : +@[no_expose] noncomputable def compatibilityTensor [FiniteDimensional ℝ E] (x : M) : TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := - TensorialAt.mkHom₂ (metricTensorAux I cov · · x) _ - (metricTensorAux_tensorial₁ I cov x) (metricTensorAux_tensorial₂ I cov x) + TensorialAt.mkHom₂ (compatibilityTensorAux I cov · · x) _ + (compatibilityTensorAux_tensorial₁ I cov) (compatibilityTensorAux_tensorial₂ I cov) variable {I} in -theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) +theorem compatibilityTensor_apply [FiniteDimensional ℝ E] (x : M) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - metricTensor cov x (Y x) (Z x) (X x) = + compatibilityTensor cov x (Y x) (Z x) (X x) = fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by - unfold metricTensor + unfold compatibilityTensor rw [TensorialAt.mkHom₂_apply _ _ hY hZ] - simp only [metricTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', + simp only [compatibilityTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] conv => enter [1, 1] @@ -349,18 +350,18 @@ theorem metricTensor_apply [FiniteDimensional ℝ E] (x : M) simp [product, real_inner_comm, fromTangentSpace] variable {I} in -theorem metricTensor_apply_extend [FiniteDimensional ℝ E] (x : M) (X₀ Y₀ Z₀ : TangentSpace I x) : - metricTensor cov x Y₀ Z₀ X₀ = +theorem compatibilityTensor_apply_extend [FiniteDimensional ℝ E] (X₀ Y₀ Z₀ : TangentSpace I x) : + compatibilityTensor cov x Y₀ Z₀ X₀ = fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x - ⟪extend E Y₀, ∇ extend E Z₀, (extend E X₀)⟫ x := by - simpa [extend_apply_self] using metricTensor_apply cov x + simpa [extend_apply_self] using compatibilityTensor_apply cov x (X := extend E X₀) (mdifferentiableAt_extend I E Y₀) (mdifferentiableAt_extend I E Z₀) /-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ -def IsCompatible [FiniteDimensional ℝ E] : Prop := metricTensor cov = 0 +def IsCompatible [FiniteDimensional ℝ E] : Prop := compatibilityTensor cov = 0 -- Auxiliary computation for `IsCompatible_apply`. -- TODO: inlining this lemma does not work @@ -368,12 +369,12 @@ private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + -- TODO: give a better name; maybe inline? variable {I} in -lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) {x : M} +lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by rw [IsCompatible] at hcov - have : metricTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] - rw [metricTensor_apply cov x hY hZ] at this + have : compatibilityTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] + rw [compatibilityTensor_apply cov x hY hZ] at this change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ exact isCompatible_apply_aux this @@ -384,7 +385,7 @@ lemma isCompatible_iff [FiniteDimensional ℝ E] : refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ unfold IsCompatible ext x X₀ Y₀ Z₀ - rw [metricTensor_apply_extend, sub_sub, sub_eq_iff_eq_add'] + rw [compatibilityTensor_apply_extend, sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] convert h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I E Y₀) From 93f3000fb23acb458d9ab2d5cf89d26c60c19c4e Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 6 Mar 2026 16:07:47 +0100 Subject: [PATCH 539/601] More documentation in CovariantDerivative.Basic --- .../CovariantDerivative/Basic.lean | 51 +++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index b7a0314a9971a7..681f2e72db34e6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -14,10 +14,54 @@ public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators /-! # Covariant derivatives -TODO: add a more complete doc-string +This file defines covariant derivatives (aka Koszul connections) on vector bundles over manifolds. + +There are versions of the story: a local unbundled one and a global bundled one. +The local version is used by the global version but also (in other files) when +seeing a global objetct in a local trivialization. In the whole file `M` is manifold over any nontrivially normed field `𝕜` and `V` is a vector bundle over `M` with model fiber `F`. + +## Main definitions and constructions + +* `IsCovariantDerivativeOn`: A function from sections of a vector bundle $V$ over a manifold $M$ to + sections of $Hom(TM, E)$ is a covariant derivative over a set $s$ in $M$ if it is additive and + satisfies the Leibniz rule when applied to sections that are differentiable at a point of $s$. +* `ContMDiffCovariantDerivativeOn`: A covariant derivative ∇ on some set is called of class `C^k` + iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` + section. This is a class so typeclass inference can deduce this automatically. +* `IsCovariantDerivativeOn.add_one_form`: Adding a one form taking values into endomorphisms of the + vector bundle to a covariant derivative on a set gives a covariant derivative on that set. +* `IsCovariantDerivativeOn.difference`: The difference of two covariant derivatives on a set, + as a one-form taking values in the endomorphism bundle. +* `CovariantDerivative`: a globally defined covariant derivative on a vector bundled, as a bundled + object. +* `ContMDiffCovariantDerivative`: A covariant derivative ∇ is called of class `C^k` + iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` + section. This is a class so typeclass inference can deduce this automatically. +* `CovariantDerivative.add_one_form`: Adding a one form taking values into endomorphisms of the + vector bundle to a covariant derivative gives a covariant derivative. +* `CovariantDerivative.difference`: The difference of two covariant derivatives, as a one-form + taking values in the endomorphism bundle. + +## Implementation notes + +On paper there are several equivalent ways to define covariant derivatives on a vector bundle +`V → M`. The most common one starts with a function `∇` taking as input a global smooth vector field +`X` and a global smooth section `σ` and giving as output a global smooth section `∇_X σ`, before +proving the result `(∇_X σ) x` at a point `x` only depends on the value of the vector field at that +point and the first jet of the section at that point. + +Here we ask for a map sending end global section `σ` to a section `∇ σ` of `Hom(TM, End(V))`. +So the fact that `(∇_X σ) x` depends only on `X x` is baked into the definition. +Note also that we don’t put any differentiability restriction on `σ` and `X`, the type of +the covariant derivative map is simply `(Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x))`. +But the conditions on this map involve differentiability, see the definition of +`IsCovariantDerivativeOn`. + +This file proves that `(∇_X σ) x` depends only on the germ of `σ` at `x`, but not the stronger +statement that it depends only the 1-jet of `σ` at `x`. This will be proved in a later file. -/ open Bundle Filter Module Topology Set NormedSpace @@ -43,8 +87,8 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] [FiberBundle F V] /-- A function from sections of a vector bundle $V$ over a manifold $M$ to sections of $Hom(TM, E)$ -is a covariant derivative over a set $s$ in $M$ if it is additive and satisfies the Leibniz when -applied to sections that are differentiable at a point of $s$. -/ +is a covariant derivative over a set $s$ in $M$ if it is additive and satisfies the Leibniz rule +when applied to sections that are differentiable at a point of $s$. -/ structure IsCovariantDerivativeOn (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (s : Set M := Set.univ) : Prop where @@ -118,6 +162,7 @@ lemma congr_of_eqOn simp section changing_set + /-! ### Changing set In this section, we change `s` in `IsCovariantDerivativeOn F cov s`, proving the condition is From 15d3c73212f4bb87b9df6ab7c5fe0de71a5b035e Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 6 Mar 2026 17:01:29 +0100 Subject: [PATCH 540/601] Better doc --- .../CovariantDerivative/Basic.lean | 200 +++++++++--------- 1 file changed, 97 insertions(+), 103 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 681f2e72db34e6..bc04b7cb18f8dc 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -18,29 +18,29 @@ This file defines covariant derivatives (aka Koszul connections) on vector bundl There are versions of the story: a local unbundled one and a global bundled one. The local version is used by the global version but also (in other files) when -seeing a global objetct in a local trivialization. +seeing a global object in a local trivialization. -In the whole file `M` is manifold over any nontrivially normed field `𝕜` and `V` is +In the whole file `M` is a manifold over any nontrivially normed field `𝕜` and `V` is a vector bundle over `M` with model fiber `F`. ## Main definitions and constructions * `IsCovariantDerivativeOn`: A function from sections of a vector bundle $V$ over a manifold $M$ to - sections of $Hom(TM, E)$ is a covariant derivative over a set $s$ in $M$ if it is additive and + sections of $Hom(TM, V)$ is a *covariant derivative* on a set $s$ in $M$ if it is additive and satisfies the Leibniz rule when applied to sections that are differentiable at a point of $s$. -* `ContMDiffCovariantDerivativeOn`: A covariant derivative ∇ on some set is called of class `C^k` - iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` +* `ContMDiffCovariantDerivativeOn`: A covariant derivative ∇ on some set is called *of class* `C^k` + iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇_X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -* `IsCovariantDerivativeOn.add_one_form`: Adding a one form taking values into endomorphisms of the - vector bundle to a covariant derivative on a set gives a covariant derivative on that set. +* `IsCovariantDerivativeOn.add_one_form`: Adding a one-form taking values in the endomorphisms of + the vector bundle to a covariant derivative on a set gives a covariant derivative on that set. * `IsCovariantDerivativeOn.difference`: The difference of two covariant derivatives on a set, as a one-form taking values in the endomorphism bundle. -* `CovariantDerivative`: a globally defined covariant derivative on a vector bundled, as a bundled +* `CovariantDerivative`: a globally defined covariant derivative on a vector bundle, as a bundled object. -* `ContMDiffCovariantDerivative`: A covariant derivative ∇ is called of class `C^k` - iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` +* `ContMDiffCovariantDerivative`: A covariant derivative ∇ is called *of class* `C^k` + iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇_X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -* `CovariantDerivative.add_one_form`: Adding a one form taking values into endomorphisms of the +* `CovariantDerivative.addOneForm`: Adding a one-form taking values in the endomorphisms of the vector bundle to a covariant derivative gives a covariant derivative. * `CovariantDerivative.difference`: The difference of two covariant derivatives, as a one-form taking values in the endomorphism bundle. @@ -51,9 +51,9 @@ On paper there are several equivalent ways to define covariant derivatives on a `V → M`. The most common one starts with a function `∇` taking as input a global smooth vector field `X` and a global smooth section `σ` and giving as output a global smooth section `∇_X σ`, before proving the result `(∇_X σ) x` at a point `x` only depends on the value of the vector field at that -point and the first jet of the section at that point. +point and the 1-jet of the section at that point. -Here we ask for a map sending end global section `σ` to a section `∇ σ` of `Hom(TM, End(V))`. +Here we ask for a map sending a global section `σ` to a section `∇ σ` of `Hom(TM, End(V))`. So the fact that `(∇_X σ) x` depends only on `X x` is baked into the definition. Note also that we don’t put any differentiability restriction on `σ` and `X`, the type of the covariant derivative map is simply `(Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x))`. @@ -64,17 +64,14 @@ This file proves that `(∇_X σ) x` depends only on the germ of `σ` at `x`, bu statement that it depends only the 1-jet of `σ` at `x`. This will be proved in a later file. -/ -open Bundle Filter Module Topology Set NormedSpace -open scoped Bundle Manifold ContDiff +open Bundle NormedSpace +open scoped Manifold ContDiff Topology variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -@[expose] public section -- TODO: think if we want to expose all definitions! +@[expose] public section -/-! -## Local unbundled theory - --/ +/-! ## Local unbundled theory -/ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} @@ -86,9 +83,12 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [FiberBundle F V] -/-- A function from sections of a vector bundle $V$ over a manifold $M$ to sections of $Hom(TM, E)$ -is a covariant derivative over a set $s$ in $M$ if it is additive and satisfies the Leibniz rule -when applied to sections that are differentiable at a point of $s$. -/ +/-- A function from sections of a vector bundle $V$ on a manifold $M$ to sections of $Hom(TM, E)$ +is a *covariant derivative* over a set $s$ in $M$ if it is additive and satisfies the Leibniz rule +when applied to sections that are differentiable at a point of $s$. + +Caution, the argument order is nonstandard: `cov σ x (X x)` corresponds to `∇_X σ x` on paper. +-/ structure IsCovariantDerivativeOn (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (s : Set M := Set.univ) : Prop where @@ -101,9 +101,9 @@ structure IsCovariantDerivativeOn + .toSpanSingleton 𝕜 (σ x) ∘L (fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv% g x) /-- -A covariant derivative ∇ is called of class `C^k` iff, -whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. -This is a class so typeclass inference can deduce this automatically. +A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a +`C^{k+1}` section, the result `∇_X σ` is a `C^k` section. This is a class so typeclass inference can +deduce this automatically. -/ class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle 𝕜 F V] (k : ℕ∞) (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) @@ -117,20 +117,19 @@ variable {F} namespace IsCovariantDerivativeOn --- TODO: prove that `cov X σ x` depends on σ only via σ(X) and the 1-jet of σ at x --- this should be easy using the projection formula in `CovariantDerivative.Ehresmann`. +-- TODO: prove that `cov σ x` depends on `σ` only via the 1-jet of `σ` at `x`. +-- This should be easy using the projection formula in `CovariantDerivative.Ehresmann`. -- In the mean time we use the following weaker result (which is convenient to apply anyway). +set_option backward.isDefEq.respectTransparency false in /-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and - `σ'` agree at `x` and are differentiable there, then `cov σ x = cov σ x'`. -/ +`σ'` agree on `s` and are differentiable at `x`, then `cov σ x = cov σ x'`. -/ lemma congr_of_eqOn {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {σ σ' : Π x : M, V x} {x : M} - (hσ : MDiffAt (T% σ) x) - (hσ' : MDiffAt (T% σ') x) - (hxs : s ∈ 𝓝 x) - (hσσ' : ∀ x ∈ s, σ x = σ' x) : + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) + (hxs : s ∈ 𝓝 x) (hσσ' : ∀ x ∈ s, σ x = σ' x) : cov σ x = cov σ' x := by classical have hxs' : x ∈ s := mem_of_mem_nhds hxs @@ -152,16 +151,10 @@ lemma congr_of_eqOn -- Then, it's a chain of (dependent) equalities. calc cov σ x _ = cov ((ψ : M → 𝕜) • σ) x := by - rw [hcov.leibniz hσ hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] - erw [ContinuousLinearMap.comp_zero] - simp + simp [hcov.leibniz hσ hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] _ = cov ((ψ : M → 𝕜) • σ') x := by rw [funext H] _ = cov σ' x := by - rw [hcov.leibniz hσ' hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] - erw [ContinuousLinearMap.comp_zero] - simp - -section changing_set + simp [hcov.leibniz hσ' hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] /-! ### Changing set @@ -169,27 +162,29 @@ In this section, we change `s` in `IsCovariantDerivativeOn F cov s`, proving the monotone and local. -/ +section changing_set + lemma mono {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s t : Set M} (hcov : IsCovariantDerivativeOn F cov t) (hst : s ⊆ t) : IsCovariantDerivativeOn F cov s where - add {_σ _σ' _x} hσ hσ' hx := hcov.add hσ hσ' (hst hx) - leibniz {_σ _cov _x} hσ hcov' hx := hcov.leibniz hσ hcov' (hst hx) + add hσ hσ' hx := hcov.add hσ hσ' (hst hx) + leibniz hσ hcov' hx := hcov.leibniz hσ hcov' (hst hx) lemma iUnion {ι : Type*} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : ι → Set M} (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) : IsCovariantDerivativeOn F cov (⋃ i, s i) where - add {_σ _σ' _x} hσ hσ' hx := by + add hσ hσ' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hcov i).add hσ hσ' - leibniz {σ f x} hσ hf' hx := by + leibniz hσ hf' hx := by obtain ⟨si, ⟨i, rfl⟩, hxsi⟩ := hx exact (hcov i).leibniz hσ hf' end changing_set +/-! ### Computational properties -/ section computational_properties -/-! ### Computation properties -/ variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} @@ -208,38 +203,38 @@ theorem smul_const (hcov : IsCovariantDerivativeOn F cov s) end computational_properties -section operations - /-! ### Operations In this section we prove that: * affine combinations of covariant derivatives are covariant derivatives -* adding a one form taking values into endomorphisms of the vector bundle to a covariant - derivative gives a covariant derivative. See `add_on_form`. -* subtracting two covariant derivatives on some set gives a one form taking values into - endomorphisms of the vector bundle. See `difference`. +* adding a one-form taking values in the endomorphisms of the vector bundle to a covariant + derivative gives a covariant derivative. See `IsCovariantDerivativeOn.add_one_form`. +* subtracting two covariant derivatives on some set gives a one-form taking values in + the endomorphisms of the vector bundle. See `IsCovariantDerivativeOn.difference`. Note: morally this means covariant derivatives form an affine space over the vector space of -one-forms taking values in endomorphisms of the bundle, but we don’t package it that way yet. +one-forms taking values in the endomorphisms of the bundle, but we don’t package it that way yet. -/ +section operations + variable {s : Set M} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} /-- An affine combination of covariant derivatives is a covariant derivative. -/ @[simps] -def affineCombination (hcov : IsCovariantDerivativeOn F cov s) +lemma affine_combination (hcov : IsCovariantDerivativeOn F cov s) {cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov' : IsCovariantDerivativeOn F cov' s) (g : M → 𝕜) : IsCovariantDerivativeOn F (fun σ ↦ (g • (cov σ)) + (1 - g) • (cov' σ)) s where - add {_σ _σ' x} hσ hσ' hx := by + add hσ hσ' hx := by simp [hcov.add hσ hσ', hcov'.add hσ hσ'] module - leibniz {σ φ x} hσ hφ hx := by + leibniz hσ hφ hx := by simp [hcov.leibniz hσ hφ, hcov'.leibniz hσ hφ] module /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination [IsManifold I 1 M] +lemma _root_.ContMDiffCovariantDerivativeOn.affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) @@ -252,11 +247,11 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination [IsManifold I 1 M] · exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hσ /-- A finite affine combination of covariant derivatives is a covariant derivative. -/ -def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +lemma finite_affine_combination {ι : Type*} {s : Finset ι} [Nonempty s] {u : Set M} {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (h : ∀ i, IsCovariantDerivativeOn F (cov i) u) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : IsCovariantDerivativeOn F (fun σ x ↦ ∑ i ∈ s, (f i x) • (cov i) σ x) u where - add {_σ _σ' _x} hσ hσ' hx := by + add hσ hσ' hx := by rw [← Finset.sum_add_distrib] congr ext i @@ -274,7 +269,7 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] _ = g x • ∑ i ∈ s, f i x • cov i σ x + B := by rw [hf]; simp /-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' [IsManifold I 1 M] {n : ℕ∞} +lemma _root_.ContMDiffCovariantDerivativeOn.finite_affine_combination [IsManifold I 1 M] {n : ℕ∞} [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) @@ -284,32 +279,32 @@ lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' [IsManifold I 1 M simpa using ContMDiffOn.sum_section (fun i hi ↦ (hf i hi).smul_section <| (hcov i hi).contMDiff hσ) -/-- Adding a one form taking values into endomorphisms of the vector bundle to a covariant +/-- Adding a one-form taking values in the endomorphisms of the vector bundle to a covariant derivative gives a covariant derivative. -/ lemma add_one_form (hcov : IsCovariantDerivativeOn F cov s) (A : Π x : M, V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : IsCovariantDerivativeOn F (fun σ x ↦ cov σ x + A x (σ x)) s where - add {_σ _σ' _x} hσ hσ' hx := by + add hσ hσ' hx := by simp [hcov.add hσ hσ'] abel - leibniz {σ g x} hσ hg hx := by + leibniz hσ hg hx := by simp [hcov.leibniz hσ hg] module section difference -/-- The difference of two covariant derivatives, as a function `Γ(TM) × Γ(V) → Γ(V)`. -Future lemmas will upgrade this to a one-forme taking values in endomorphisms of `V`. -/ +/-- The difference of two covariant derivatives, as a function `Γ(V) → Γ(Hom(TM, V))`. +Future lemmas will upgrade this to a one-form taking values in the endomorphisms of `V`. -/ noncomputable def differenceAux (cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x) := fun σ ↦ cov σ - cov' σ variable - {cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - {s : Set M} - (hcov : IsCovariantDerivativeOn F cov s) - (hcov' : IsCovariantDerivativeOn F cov' s) + {cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) theorem differenceAux_tensorial (hcov : IsCovariantDerivativeOn F cov s) (hcov' : IsCovariantDerivativeOn F cov' s) @@ -323,13 +318,12 @@ theorem differenceAux_tensorial (hcov : IsCovariantDerivativeOn F cov s) -- We need more assumptions to use the tensoriality criterion in order to build the difference -- operation. -variable [CompleteSpace 𝕜] - [IsManifold I 1 M] - [FiniteDimensional 𝕜 F] - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] +variable [CompleteSpace 𝕜] [IsManifold I 1 M] [FiniteDimensional 𝕜 F] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] open scoped Classical in -/-- The difference of two covariant derivatives, as a tensorial map. -/ +/-- The difference of two covariant derivatives, as a one-form taking values in the +endomorphisms of `V`. -/ noncomputable def difference (x : M) : V x →L[𝕜] TangentSpace I x →L[𝕜] V x := if hxs : x ∈ s then TensorialAt.mkHom _ x (differenceAux_tensorial hcov hcov' _ hxs) @@ -354,7 +348,7 @@ end IsCovariantDerivativeOn variable (I F V) in /-- Bundled global covariant derivative on a vector bundle. -Caution: the argument order is slightly tricky: `cov Y x (X x)` corresponds to `∇ X Y x` on paper. +Caution, the argument order is nonstandard: `cov σ x (X x)` corresponds to `∇_X σ x` on paper. -/ @[ext] structure CovariantDerivative where @@ -379,8 +373,8 @@ lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 ext1 x simp [cov.isCovariantDerivativeOnUniv.zero] -/-- If `f : Vec(M) × Γ(V) → Vec(M)` is a covariant derivative on each set in an open cover, -it is a covariant derivative. -/ +/-- If `cov` is a covariant derivative on each set in an open cover, it is a covariant derivative. +-/ def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i, IsCovariantDerivativeOn F cov (s i)) (hs : ⋃ i, s i = Set.univ) : @@ -394,8 +388,8 @@ lemma of_isCovariantDerivativeOn_of_open_cover_coe {ι : Type*} {s : ι → Set of_isCovariantDerivativeOn_of_open_cover hcov hs = cov := rfl /-- -A covariant derivative ∇ is called of class `C^k` iff, -whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇ X σ` is a `C^k` section. +A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` section and `σ` a +`C^{k+1}` section, the result `∇_X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ class ContMDiffCovariantDerivative [IsManifold I 1 M] [VectorBundle 𝕜 F V] @@ -415,70 +409,70 @@ section operations In this section we prove that: * affine combinations of covariant derivatives are covariant derivatives -* adding a one form taking values into endomorphisms of the vector bundle to a covariant - derivative gives a covariant derivative. See `add_on_form`. -* subtracting two covariant derivatives on some set gives a one form taking values into - endomorphisms of the vector bundle. See `difference`. +* adding a one-form taking values in the endomorphisms of the vector bundle to a covariant + derivative gives a covariant derivative. See `CovariantDerivative.addOneForm`. +* subtracting two covariant derivatives on some set gives a one-form taking values in the + endomorphisms of the vector bundle. See `CovariantDerivative.difference`. Note: morally this means covariant derivatives form an affine space over the vector space of -one-forms taking values in endomorphisms of the bundle, but we don’t package it that way yet. +one-forms taking values in the endomorphisms of the bundle, but we don’t package it that way yet. -/ -/-- An affine combination of covariant derivatives is a covariant derivative. -/ +/-- An affine combination of covariant derivatives as a covariant derivative. -/ @[simps] -def affineCombination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : +def affine_combination (cov cov' : CovariantDerivative I F V) (g : M → 𝕜) : CovariantDerivative I F V where toFun := fun σ ↦ (g • (cov σ)) + (1 - g) • (cov' σ) isCovariantDerivativeOnUniv := - cov.isCovariantDerivativeOn.affineCombination cov'.isCovariantDerivativeOn _ + cov.isCovariantDerivativeOn.affine_combination cov'.isCovariantDerivativeOn _ -/-- A finite affine combination of covariant derivatives is a covariant derivative. -/ -def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] +/-- A finite affine combination of covariant derivatives as a covariant derivative. -/ +def finite_affine_combination {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) : CovariantDerivative I F V where toFun t x := ∑ i ∈ s, (f i x) • (cov i) t x - isCovariantDerivativeOnUniv := IsCovariantDerivativeOn.affineCombination' + isCovariantDerivativeOnUniv := IsCovariantDerivativeOn.finite_affine_combination (fun i ↦ (cov i).isCovariantDerivativeOn) hf /-- An affine combination of two `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.affineCombination [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] (cov cov' : CovariantDerivative I F V) {f : M → 𝕜} {n : ℕ∞} (hf : ContMDiff I 𝓘(𝕜) n f) (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : - ContMDiffCovariantDerivative (affineCombination cov cov' f) n where + ContMDiffCovariantDerivative (affine_combination cov cov' f) n where contMDiff := - ContMDiffCovariantDerivativeOn.affineCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff + ContMDiffCovariantDerivativeOn.affine_combination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff /-- An affine combination of finitely many `C^k` connections is a `C^k` connection. -/ -lemma ContMDiffCovariantDerivative.affineCombination' [IsManifold I 1 M] [VectorBundle 𝕜 F V] +lemma ContMDiffCovariantDerivative.finite_affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : - ContMDiffCovariantDerivative (affineCombination' cov hf) n where + ContMDiffCovariantDerivative (finite_affine_combination cov hf) n where contMDiff := - ContMDiffCovariantDerivativeOn.affineCombination' + ContMDiffCovariantDerivativeOn.finite_affine_combination (fun i hi ↦ (hcov i hi).contMDiff) (fun i hi ↦ (hf' i hi).contMDiffOn) -- TODO: prove a version with a locally finite sum, and deduce that C^k connections always -- exist (using a partition of unity argument) -/-- Adding a one form taking values into endomorphisms of the vector bundle to a covariant +/-- Adding a one-form taking values in the endomorphisms of the vector bundle to a covariant derivative gives a covariant derivative. -/ -def add_one_form (cov : CovariantDerivative I F V) +def addOneForm (cov : CovariantDerivative I F V) (A : Π (x : M), V x →L[𝕜] TangentSpace I x →L[𝕜] V x) : CovariantDerivative I F V where - toFun := fun σ x ↦ cov σ x + (A x) (σ x) + toFun := fun σ x ↦ cov σ x + A x (σ x) isCovariantDerivativeOnUniv := cov.isCovariantDerivativeOnUniv.add_one_form A section difference -- We need more assumptions to use the tensoriality criterion in order to build the difference -- operation. -variable [CompleteSpace 𝕜] - [IsManifold I 1 M] - [FiniteDimensional 𝕜 F] - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] +variable [CompleteSpace 𝕜] [IsManifold I 1 M] [FiniteDimensional 𝕜 F] + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] +/-- The difference of two covariant derivatives, as a one-form taking values in the +endomorphisms of `V`. -/ noncomputable def difference (cov cov' : CovariantDerivative I F V) : Π (x : M), V x →L[𝕜] TangentSpace I x →L[𝕜] V x := cov.isCovariantDerivativeOnUniv.difference cov'.isCovariantDerivativeOnUniv From dc9ba965858006fa0b925ccc99a4d4fe66c4ba9e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 15:18:53 +0000 Subject: [PATCH 541/601] wip(LeviCivita): extend documentation --- .../CovariantDerivative/LeviCivita.lean | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index f97400cacd5fc7..5509eeb0e32517 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -13,9 +13,27 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion # The Levi-Civita connection on a Riemannian manifold This file defines the Levi-Civita connection on a (finite-dimensional) Riemannian manifold `(M, g)`. +connection `∇` on the tangent bundle of a Riemannian manifold `(M, g)` is called a +*Levi-Civita connection* if and only if it is both compatible with the metric `g` and torsion-free. +Any two such connections are equal (on differentiable vector fields), which is why one speaks of +*the* Levi-Civita connection on `TM`. +We construct a Levi-Civita connection (using a tensoriality argument), and proves that is defines +a metric and torsion-free connection. + ## Main definitions and results +* `CovariantDerivative.IsLeviCivitaConnection`: a covariant derivative `∇` on `(M, g)` is a + Levi-Civita connection if and only if it is both torsion-free and compatible with `g` + +* `CovariantDerivative.IsLeviCivitaConnection.uniqueness`: a Levi-Civita connection on `(M, g)` is + uniquely determined on differentiable vector fields. + +To be continued! + +We prove the existence and uniqueness of the Levi-Civita connection + + ## Implementation notes From 0c586f309cfafc78a4515c62ee23225d23b7771e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 16:04:20 +0000 Subject: [PATCH 542/601] chore(Basic): fewer dollars --- .../VectorBundle/CovariantDerivative/Basic.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index bc04b7cb18f8dc..2df656c3970000 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -25,9 +25,9 @@ a vector bundle over `M` with model fiber `F`. ## Main definitions and constructions -* `IsCovariantDerivativeOn`: A function from sections of a vector bundle $V$ over a manifold $M$ to - sections of $Hom(TM, V)$ is a *covariant derivative* on a set $s$ in $M$ if it is additive and - satisfies the Leibniz rule when applied to sections that are differentiable at a point of $s$. +* `IsCovariantDerivativeOn`: A function from sections of a vector bundle `V` over a manifold `M` to + sections of $Hom(TM, V)$ is a *covariant derivative* on a set `s` in `M` if it is additive and + satisfies the Leibniz rule when applied to sections that are differentiable at a point of `s`. * `ContMDiffCovariantDerivativeOn`: A covariant derivative ∇ on some set is called *of class* `C^k` iff, whenever `X` is a `C^k` section and `σ` a `C^{k+1}` section, the result `∇_X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. @@ -83,9 +83,9 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [FiberBundle F V] -/-- A function from sections of a vector bundle $V$ on a manifold $M$ to sections of $Hom(TM, E)$ -is a *covariant derivative* over a set $s$ in $M$ if it is additive and satisfies the Leibniz rule -when applied to sections that are differentiable at a point of $s$. +/-- A function from sections of a vector bundle `V` on a manifold `M` to sections of $Hom(TM, E)$ +is a *covariant derivative* over a set `s` in `M` if it is additive and satisfies the Leibniz rule +when applied to sections that are differentiable at a point of `s`. Caution, the argument order is nonstandard: `cov σ x (X x)` corresponds to `∇_X σ x` on paper. -/ From 2317efd74d99a8bf29cb64f03681a76eb5db8595 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 16:06:02 +0000 Subject: [PATCH 543/601] chore(Torsion): a few tweaks --- .../VectorBundle/CovariantDerivative/Torsion.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index e3914f85ff30ea..df33235c7a67f5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -23,7 +23,7 @@ manifold `M` and derive a criterion for torsion-freeness. -/ -@[expose] public section -- TODO: think if we want to expose all definitions! +@[expose] public section open Bundle Filter Module Topology Set NormedSpace @@ -49,7 +49,7 @@ variable {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)} {X X' Y : Π x : M, TangentSpace I x} -variable (f X) in +variable (X) in lemma torsionAux_self : IsCovariantDerivativeOn.torsionAux cov X X = 0 := by ext simp [torsionAux] @@ -99,11 +99,11 @@ lemma torsionAux_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivative module lemma torsionAux_smul_right_apply [CompleteSpace E] - {F : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} - (hF : IsCovariantDerivativeOn E F U) + {cov : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} + (hcov : IsCovariantDerivativeOn E cov U) {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : - torsionAux F Y (f • X) x = f x • torsionAux F Y X x := by - rw [torsionAux_antisymm, Pi.neg_apply, hF.torsionAux_smul_left_apply Y hf hX, + torsionAux cov Y (f • X) x = f x • torsionAux cov Y X x := by + rw [torsionAux_antisymm, Pi.neg_apply, hcov.torsionAux_smul_left_apply Y hf hX, torsionAux_antisymm X] simp From 4410c907fefed124fb251a7d2ab238bdeade19c8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 16:44:32 +0000 Subject: [PATCH 544/601] chore: add more bar! --- Mathlib/Geometry/Manifold/VectorField/LieBracket.lean | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index c5ba9c17cd84b1..79fd6cdac7dbbb 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -360,6 +360,7 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDiffAt[s] f x) (hW : MDiffAt[s] (fun x ↦ (W x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : + -- TODO: add fromTangentSpace mlieBracketWithin I V (f • W) s x = (mfderivWithin I 𝓘(𝕜) f s x) (V x) • (W x) + (f x) • mlieBracketWithin I V W s x := by simp only [mlieBracketWithin, mpullbackWithin_smul] @@ -390,7 +391,9 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a -/ lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDiffAt f x) (hW : MDiffAt (fun x ↦ (W x : TangentBundle I M)) x) : - mlieBracket I V (f • W) x = (mfderiv% f x) (V x) • (W x) + (f x) • mlieBracket I V W x := by + mlieBracket I V (f • W) x = + NormedSpace.fromTangentSpace (f x) (mfderiv% f x (V x)) • (W x) + + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hW rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I) @@ -404,6 +407,7 @@ lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDiffAt[s] f x) (hV : MDiffAt[s] (fun x ↦ (V x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (f • V) W s x = + -- TODO: add fromTangentSpace! -(mfderivWithin I 𝓘(𝕜) f s x) (W x) • (V x) + (f x) • mlieBracketWithin I V W s x := by rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_smul_right hf hV (V := W) hs, mlieBracketWithin_swap] @@ -417,7 +421,8 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDiffAt f x) (hV : MDiffAt (fun x ↦ (V x : TangentBundle I M)) x) : mlieBracket I (f • V) W x = - -(mfderiv% f x) (W x) • (V x) + (f x) • mlieBracket I V W x := by + - (NormedSpace.fromTangentSpace (f x) (mfderiv% f x (W x))) • (V x) + + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hV rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I) From 9beac340df4b21a7e3eb397984a0af619594c8f2 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 17:00:04 +0000 Subject: [PATCH 545/601] Reviewed Torsion together --- .../CovariantDerivative/Torsion.lean | 160 +++++++----------- 1 file changed, 63 insertions(+), 97 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index df33235c7a67f5..7de77b1bff7dcb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -8,127 +8,69 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorField.LieBracket -/-! # Torsion of a covariant derivative +/-! # Torsion of an affine connection -We define the torsion tensor of a covariant derivative on the tangent bundle `TM` of some -manifold `M` and derive a criterion for torsion-freeness. +We define the torsion tensor of an affine connection, i.e. a covariant derivative on the tangent +bundle `TM` of some manifold `M`. ## Main definitions and results * `IsCovariantDerivativeOn.torsion`: the torsion tensor of an unbundled covariant derivative - on `TM` on some set `s ⊆ M` + on `TM` on some set `s` in `M` * `CovariantDerivative.torsion`: the torsion tensor of a bundled covariant derivative on `TM` -* `CovariantDerivative.IsTorsionFree`: predicate for a bundled covariant derivative `∇` - to be torsion-free: `∇` is torsion free if and only if its torsion tensor vanishes +* `CovariantDerivative.torsion_eq_zero_iff`: the torsion tensor of a bundled covariant derivative + `∇` vanishes if and only if `∇_X Y - ∇_Y X = [X, Y]` for all differentiable vector fields + `X` and `Y`. -/ @[expose] public section -open Bundle Filter Module Topology Set NormedSpace - -open scoped Bundle Manifold ContDiff +open Bundle Set NormedSpace +open scoped Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] - {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} - {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] (n : WithTop ℕ∞) {V : M → Type*} - [TopologicalSpace (TotalSpace F V)] [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] - [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} +/-! ## Torsion tensor of an unbundled covariant derivative on `TM` on a set `s` -/ namespace IsCovariantDerivativeOn /-- The torsion of a covariant derivative on the tangent bundle `TM`, as a bare function. -Prefer to use `torsion` (which is a two-tensor) instead. -/ +Prefer to use `IsCovariantDerivativeOn.torsion` (which is a 2-tensor) instead. -/ noncomputable def torsionAux (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := fun X Y x ↦ cov Y x (X x) - cov X x (Y x) - VectorField.mlieBracket I X Y x -variable +variable [IsManifold I 2 M] [CompleteSpace E] {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)} {X X' Y : Π x : M, TangentSpace I x} -variable (X) in -lemma torsionAux_self : IsCovariantDerivativeOn.torsionAux cov X X = 0 := by - ext - simp [torsionAux] - -variable (X Y) in -lemma torsionAux_antisymm : torsionAux cov X Y = - torsionAux cov Y X := by - ext x - unfold torsionAux - rw [VectorField.mlieBracket_swap] - dsimp - module - -variable [IsManifold I 2 M] {U : Set M} - -section - -variable (Y) - -lemma torsionAux_add_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : - torsionAux cov (X + X') Y x = torsionAux cov X Y x + torsionAux cov X' Y x := by - simp [torsionAux, hcov.add hX hX', VectorField.mlieBracket_add_left hX hX'] - module - -lemma torsionAux_add_right_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) - (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hx : x ∈ U := by trivial) : - torsionAux cov Y (X + X') x = torsionAux cov Y X x + torsionAux cov Y X' x := by - rw [torsionAux_antisymm, Pi.neg_apply, - hcov.torsionAux_add_left_apply _ hX hX', torsionAux_antisymm Y, torsionAux_antisymm Y] - simp; abel - -lemma torsionAux_smul_left_apply [CompleteSpace E] (hcov : IsCovariantDerivativeOn E cov U) - {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : - torsionAux cov (f • X) Y x = f x • torsionAux cov X Y x := by - simp only [torsionAux] - rw [hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] - simp? [smul_sub] says - simp only [Pi.smul_apply', map_smul, ContinuousLinearMap.add_apply, - ContinuousLinearMap.coe_smul', Pi.smul_apply, ContinuousLinearMap.coe_comp', - ContinuousLinearEquiv.coe_coe, Function.comp_apply, ContinuousLinearMap.toSpanSingleton_apply, - smul_sub] - set A := f x • (cov X x) (Y x) - set B := f x • (cov Y x) (X x) - set C := f x • VectorField.mlieBracket I X Y x - set D := mfderiv% f x (Y x) - change B - (A + (fromTangentSpace _ D) • X x) - (-(fromTangentSpace _ D) • X x + C) = B - A - C - module - -lemma torsionAux_smul_right_apply [CompleteSpace E] - {cov : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} - (hcov : IsCovariantDerivativeOn E cov U) - {f : M → 𝕜} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hx : x ∈ U := by trivial) : - torsionAux cov Y (f • X) x = f x • torsionAux cov Y X x := by - rw [torsionAux_antisymm, Pi.neg_apply, hcov.torsionAux_smul_left_apply Y hf hX, - torsionAux_antisymm X] - simp - -end - -section - -variable [CompleteSpace E] - --- TODO inline the lemmas that go into this theorem torsionAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) (x : M) (Y : Π x, TangentSpace I x) : TensorialAt I E (torsionAux cov · Y x) x where - smul hf hX := hcov.torsionAux_smul_left_apply Y hf hX - add hX hX' := hcov.torsionAux_add_left_apply Y hX hX' + smul hf hX := by + simp [torsionAux, hcov.leibniz hX hf, VectorField.mlieBracket_smul_left hf hX] + module + add hX hX' := by + simp [torsionAux, hcov.add hX hX', VectorField.mlieBracket_add_left hX hX'] + module --- TODO inline the lemmas that go into this theorem torsionAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) (x : M) (X : Π x, TangentSpace I x) : TensorialAt I E (torsionAux cov X · x) x where - smul hf hY := hcov.torsionAux_smul_right_apply X hf hY - add hY hY' := hcov.torsionAux_add_right_apply X hY hY' + smul hf hY := by + simp [torsionAux, hcov.leibniz hY hf, VectorField.mlieBracket_smul_right hf hY] + module + add hY hY' := by + simp [torsionAux, hcov.add hY hY', VectorField.mlieBracket_add_right hY hY'] + module variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 E] +/-- The torsion tensor of an unbundled covariant derivative on `TM`. -/ noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := TensorialAt.mkHom₂ (torsionAux cov · · x) _ @@ -138,14 +80,35 @@ noncomputable def torsion (hcov : IsCovariantDerivativeOn E cov univ) (x : M) : theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} {X : Π x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) {Y : Π x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) : - torsion hcov x (X x) (Y x) = torsionAux cov X Y x := + torsion hcov x (X x) (Y x) = cov Y x (X x) - cov X x (Y x) - VectorField.mlieBracket I X Y x := TensorialAt.mkHom₂_apply _ _ hX hY -end +theorem torsion_apply_eq_extend (hcov : IsCovariantDerivativeOn E cov univ) {x} + (X₀ Y₀ : TangentSpace I x) : + torsion hcov x X₀ Y₀ = + cov (extend E Y₀) x X₀ - cov (extend E X₀) x Y₀ + - VectorField.mlieBracket I (extend E X₀) (extend E Y₀) x := by + simp [torsion, torsionAux, TensorialAt.mkHom₂_apply_eq_extend] + +variable (X) in +@[simp] +lemma torsion_self (hcov : IsCovariantDerivativeOn E cov univ) (X₀ : TangentSpace I x) : + hcov.torsion x X₀ X₀ = 0 := by + simp [torsion_apply_eq_extend] + +variable (X Y) in +lemma torsion_antisymm (hcov : IsCovariantDerivativeOn E cov univ) (X₀ Y₀ : TangentSpace I x) : + hcov.torsion x X₀ Y₀ = - hcov.torsion x Y₀ X₀ := by + simp only [torsion_apply_eq_extend, neg_sub] + rw [VectorField.mlieBracket_swap] + dsimp + module end IsCovariantDerivativeOn +/-! ## Torsion tensor of a bundled covariant derivative on `TM` -/ namespace CovariantDerivative + open VectorField variable @@ -164,20 +127,23 @@ lemma torsion_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : apply TensorialAt.mkHom₂_apply exacts [hX, hY] -lemma torsion_apply_extend (u v : TangentSpace I x) : - cov.torsion x u v = - cov (extend E v) x (extend E u x) - cov (extend E u) x (extend E v x) - - mlieBracket I (extend E u) (extend E v) x := by +lemma torsion_apply_eq_extend (X₀ Y₀ : TangentSpace I x) : + cov.torsion x X₀ Y₀ = + cov (extend E Y₀) x (extend E X₀ x) - cov (extend E X₀) x (extend E Y₀ x) + - mlieBracket I (extend E X₀) (extend E Y₀) x := by unfold torsion IsCovariantDerivativeOn.torsion apply TensorialAt.mkHom₂_apply_eq_extend -/-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ -def IsTorsionFree : Prop := torsion cov = 0 +@[simp] +lemma torsion_self (X₀ : TangentSpace I x) : cov.torsion x X₀ X₀ = 0 := + cov.isCovariantDerivativeOn.torsion_self .. + +lemma torsion_antisymm (X₀ Y₀ : TangentSpace I x) : cov.torsion x X₀ Y₀ = - cov.torsion x Y₀ X₀ := + cov.isCovariantDerivativeOn.torsion_antisymm .. -lemma isTorsionFree_iff : IsTorsionFree cov ↔ +lemma torsion_eq_zero_iff : cov.torsion = 0 ↔ ∀ {X Y x}, MDiffAt (T% X) x → MDiffAt (T% Y) x → cov Y x (X x) - cov X x (Y x) = mlieBracket I X Y x := by - unfold IsTorsionFree constructor · intro h X Y x hX hY replace h := congr($h x (X x) (Y x)) @@ -185,7 +151,7 @@ lemma isTorsionFree_iff : IsTorsionFree cov ↔ simpa [sub_eq_iff_eq_add'] using h · intro h ext x u v - rw [torsion_apply_extend, h] + rw [torsion_apply_eq_extend, h] · simp · apply mdifferentiableAt_extend · apply mdifferentiableAt_extend From 65dc2aaf250d2d7dd09d932d14b6bc7f9363f348 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 18:24:00 +0000 Subject: [PATCH 546/601] wip: metric changes --- .../CovariantDerivative/Metric.lean | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 46e6d12eb48ec3..104f6563311919 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -188,6 +188,23 @@ noncomputable def compatibilityTensorAux (Y Z : Π x : M, TangentSpace I x) : letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) +lemma compatibilityTensorAux_apply (Y Z : Π x : M, TangentSpace I x) {x : M} (X₀ : TangentSpace I x) : + compatibilityTensorAux I cov Y Z x X₀ = + NormedSpace.fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x X₀) + + inner ℝ (Z x) (cov Y x X₀) - inner ℝ (Y x) (cov Z x X₀) := by + unfold compatibilityTensorAux + simp + -- change mfderiv% ⟪Y, Z⟫ x X₀ - (innerSL ℝ) (Z x) (cov Y x) X₀ = _ + congr + --let A := mfderiv% ⟪Y, Z⟫ x + rw [Pi.sub_apply] + rw [ContinuousLinearMap.comp_apply] + + simp + + sorry + +#exit variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x : M} variable {I} in @@ -339,8 +356,10 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ E] (x : M) fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by unfold compatibilityTensor rw [TensorialAt.mkHom₂_apply _ _ hY hZ] + --rw [compatibilityTensorAux_apply] simp only [compatibilityTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] + conv => enter [1, 1] erw [ContinuousLinearMap.sub_apply] @@ -350,7 +369,7 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ E] (x : M) simp [product, real_inner_comm, fromTangentSpace] variable {I} in -theorem compatibilityTensor_apply_extend [FiniteDimensional ℝ E] (X₀ Y₀ Z₀ : TangentSpace I x) : +theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ E] (X₀ Y₀ Z₀ : TangentSpace I x) : compatibilityTensor cov x Y₀ Z₀ X₀ = fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x @@ -385,10 +404,10 @@ lemma isCompatible_iff [FiniteDimensional ℝ E] : refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ unfold IsCompatible ext x X₀ Y₀ Z₀ - rw [compatibilityTensor_apply_extend, sub_sub, sub_eq_iff_eq_add'] + rw [compatibilityTensor_apply_eq_extend, sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] - convert h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) + have h' := h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I E Y₀) - simp [fromTangentSpace, extend_apply_self] + simpa [fromTangentSpace, extend_apply_self] using h' end CovariantDerivative From 5aa3e1a41a99306e1ac0406f78463a5741c826ae Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 18:35:07 +0000 Subject: [PATCH 547/601] chore: don't need mfderiv_smul and friends just yet --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 3 +-- .../Manifold/VectorBundle/CovariantDerivative/Metric.lean | 1 + .../Manifold/VectorBundle/CovariantDerivative/Trivial.lean | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 2df656c3970000..091dc28fbbf7b9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -7,9 +7,8 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality -public import Mathlib.Geometry.Manifold.MfDerivSMul -public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators /-! # Covariant derivatives diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 104f6563311919..cbaebb45d5c839 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -7,6 +7,7 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Geometry.Manifold.MfDerivSMul /-! # Metric connections diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index a5b5aa98d3e4e4..0802d293100b36 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -5,6 +5,7 @@ Authors: Patrick Massot, Michael Rothgang -/ module +public import Mathlib.Geometry.Manifold.MfDerivSMul public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim From fa6e61e0611a93e339626dc512c4fdaaa026e5be Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 18:49:27 +0000 Subject: [PATCH 548/601] Fixup for torsion changes --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 5509eeb0e32517..d94fedc0fc47fd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -72,7 +72,7 @@ iff it is torsion-free and compatible with `g`. Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a version depending on a choice of Riemannian metric on `M`. -/ -def IsLeviCivitaConnection [FiniteDimensional ℝ E] : Prop := cov.IsCompatible ∧ cov.IsTorsionFree +def IsLeviCivitaConnection [FiniteDimensional ℝ E] : Prop := cov.IsCompatible ∧ cov.torsion = 0 local notation "⟪" X ", " Y "⟫" => product I X Y @@ -533,7 +533,7 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by trans ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x · exact cov.isCompatible_apply h.1 hY hZ - · simp [← cov.isTorsionFree_iff.mp h.2 hX hZ, product, inner_sub_right] + · simp [← cov.torsion_eq_zero_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in /-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term @@ -794,10 +794,10 @@ lemma leviCivitaConnection_isCompatible [FiniteDimensional ℝ E] : rw [leviCivitaConnection_apply I hX hZ hY] rw [leviCivitaConnection_apply I hX hZ hY, leviCivitaConnection_isCompatible_aux] -lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : - (LeviCivitaConnection I M).IsTorsionFree := by +lemma leviCivitaConnection_torsion_eq_zero [FiniteDimensional ℝ E] : + (LeviCivitaConnection I M).torsion = 0 := by have a := (LeviCivitaConnection I M).isCovariantDerivativeOnUniv - rw [CovariantDerivative.isTorsionFree_iff] + rw [CovariantDerivative.torsion_eq_zero_iff] intro X Y x hX hY apply congr_of_forall_product_apply intro Z @@ -831,6 +831,6 @@ lemma leviCivitaConnection_isTorsionFree [FiniteDimensional ℝ E] : lemma leviCivitaConnection_isLeviCivitaConnection [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := - ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_isTorsionFree I⟩ + ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_torsion_eq_zero I⟩ end CovariantDerivative From 4cc7969bbc9158fafce8bd5df9188ccf0dca922d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 19:01:04 +0000 Subject: [PATCH 549/601] wip: try to fix errors in Metric.lean --- .../CovariantDerivative/LeviCivita.lean | 26 +++++++------ .../CovariantDerivative/Metric.lean | 39 ++++++++++--------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index d94fedc0fc47fd..5a1e50c36ebe00 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -261,7 +261,7 @@ lemma leviCivitaRhs_addX [CompleteSpace E] ext x simp [leviCivitaRhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] -open VectorField +open VectorField NormedSpace variable {I} in lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} @@ -276,24 +276,27 @@ lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} -- Combining this line with the previous one fails. simp only [← product_apply, neg_smul, inner_neg_right] have h1 : - letI dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x); - inner ℝ (Y x) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) • X x) = dfZ * ⟪X, Y⟫ x := by + inner ℝ (Y x) ((fromTangentSpace _ (mfderiv% f x (Z x))) • X x) = + fromTangentSpace (f x) (mfderiv% f x (Z x)) * ⟪X, Y⟫ x := by simp only [product] rw [← real_inner_smul_left, real_inner_smul_right, real_inner_smul_left, real_inner_comm] have h2 : - letI dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x); - inner ℝ (Z x) ((mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) • X x) = dfZ * ⟪Z, X⟫ x := by + inner ℝ (Z x) (fromTangentSpace (f x) ((mfderiv% f x (Y x))) • X x) = + (fromTangentSpace (f x) (mfderiv% f x (Y x))) * ⟪Z, X⟫ x := by simp only [product] rw [← real_inner_smul_left, real_inner_smul_right, real_inner_smul_left] - simp only [h1, h2] - set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - set dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) + rw [h1, h2] + --set dfY := fromTangentSpace (f x) ((mfderiv% f x (Y x)))--(mfderiv% f x) (Y x) + --set dfZ : ℝ := (mfderiv% f x) (Z x) have h3 : ⟪f • X, mlieBracket I Z Y⟫ x = f x * ⟪X, mlieBracket I Z Y⟫ x := by rw [product_apply, Pi.smul_apply', real_inner_smul_left] have h4 : inner ℝ (Z x) (f x • mlieBracket I Y X x) = f x * ⟪Z, mlieBracket I Y X⟫ x := by rw [product_apply, real_inner_smul_right] - rw [real_inner_smul_right (Y x), h3]--, h4] - -- set A := ⟪Y, mlieBracket I X Z⟫ with hA + rw [real_inner_smul_right (Y x), h3, h4] + + -- Push all applications of `x` inwards, then it's indeed obvious. + simp + set A := ⟪Y, mlieBracket I X Z⟫ with hA -- set B := ⟪Z, mlieBracket I X Y⟫ -- set C := ⟪X, mlieBracket I Z Y⟫ -- set R := dfZ * ⟪X, Y⟫ x with hR @@ -301,11 +304,10 @@ lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} -- set E := rhs_aux I X Y Z x -- set F := rhs_aux I Y Z X x -- set G := rhs_aux I Z X Y x - -- Push all applications of `x` inwards, then it's indeed obvious. - simp ring_nf congr +#exit variable {I} in lemma leviCivitaRhs_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index cbaebb45d5c839..c88a629b5f5d28 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -196,18 +196,18 @@ lemma compatibilityTensorAux_apply (Y Z : Π x : M, TangentSpace I x) {x : M} (X unfold compatibilityTensorAux simp -- change mfderiv% ⟪Y, Z⟫ x X₀ - (innerSL ℝ) (Z x) (cov Y x) X₀ = _ - congr + --congr --let A := mfderiv% ⟪Y, Z⟫ x - rw [Pi.sub_apply] - rw [ContinuousLinearMap.comp_apply] + --rw [Pi.sub_apply] + --rw [ContinuousLinearMap.comp_apply] - simp + --simp sorry -#exit variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x : M} +set_option backward.isDefEq.respectTransparency false in variable {I} in private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : @@ -215,20 +215,21 @@ private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} unfold compatibilityTensorAux rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] ext X - simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, - RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, - ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', - coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] - erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.add_apply] - conv => - enter [1, 1, 2, 1] - erw [ContinuousLinearMap.smul_apply] - rw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, - ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, - innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, + simp + -- simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, + -- RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, + -- ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', + -- coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] + --erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] + -- conv => + -- enter [1, 1, 2] + -- --erw [ContinuousLinearMap.add_apply] + -- conv => + -- enter [1, 1, 2, 1] + -- --erw [ContinuousLinearMap.smul_apply] + rw [--ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, + --ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, + --innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, inner_smul_right, mfderiv_smul (hσ.inner_bundle' hτ) hf] simp only [smul_eq_mul, Pi.mul_apply, fromTangentSpace, ContinuousLinearEquiv.coe_coe, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] From f4cf244416f8433139db906890a2b3abf5ac6790 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:13:37 +0000 Subject: [PATCH 550/601] fix LeviCivita after defeq abuse adjustments earlier --- .../CovariantDerivative/LeviCivita.lean | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 5a1e50c36ebe00..27c1aa8e362148 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -147,13 +147,14 @@ lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I variable (X) in lemma rhs_aux_smulY_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - letI A (x) : ℝ := (mfderiv% f x) (X x) + letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X (f • Y) Z x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by rw [rhs_aux, product_smul_left, mfderiv_smul (hY.inner_bundle' hZ) hf] + rfl variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI A (x) : ℝ := (mfderiv% f x) (X x) + letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by ext x simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] @@ -175,14 +176,14 @@ lemma rhs_aux_smulY_const {a : ℝ} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : variable (X) in lemma rhs_aux_smulZ_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - letI A (x) : ℝ := (mfderiv% f x) (X x) + letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X Y (f • Z) x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by rw [rhs_aux_swap, rhs_aux_smulY_apply, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] variable (X) in lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI A (x) : ℝ := (mfderiv% f x) (X x) + letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] @@ -296,7 +297,7 @@ lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} -- Push all applications of `x` inwards, then it's indeed obvious. simp - set A := ⟪Y, mlieBracket I X Z⟫ with hA + -- set A := ⟪Y, mlieBracket I X Z⟫ with hA -- set B := ⟪Z, mlieBracket I X Y⟫ -- set C := ⟪X, mlieBracket I Z Y⟫ -- set R := dfZ * ⟪X, Y⟫ x with hR @@ -305,9 +306,7 @@ lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} -- set F := rhs_aux I Y Z X x -- set G := rhs_aux I Z X Y x ring_nf - congr -#exit variable {I} in lemma leviCivitaRhs_smulX_apply [CompleteSpace E] {f : M → ℝ} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : @@ -407,6 +406,7 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} · simp only [neg_smul, inner_neg_right, fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul, neg_mul, neg_inj] rw [real_inner_smul_right] + rfl · rw [inner_smul_right_eq_smul] have h2 : ⟪X, mlieBracket I Z (f • Y)⟫ x = (fromTangentSpace _).toFun (((mfderiv% f x) (Z x))) • ⟪X, Y⟫ x @@ -415,6 +415,7 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} congr · simp only [fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul] rw [real_inner_smul_right] + rfl · rw [inner_smul_right_eq_smul] rw [h1, h2, product_swap I Y Z] set A := rhs_aux I X Y Z x @@ -485,11 +486,11 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} -- Apply the product rule for the lie bracket. -- Let's encapsulate the going into the product and back out again. have h1 : ⟪Y, mlieBracket I X (f • Z)⟫ x = - f x • ⟪Y, mlieBracket I X Z⟫ x + ⟪Y, mfderiv% f x (X x) • Z⟫ x := by + f x • ⟪Y, mlieBracket I X Z⟫ x + ⟪Y, fromTangentSpace _ (mfderiv% f x (X x)) • Z⟫ x := by rw [product_apply, VectorField.mlieBracket_smul_right hf hZ, inner_add_right, add_comm, inner_smul_right] congr - have h2 : letI dfY : ℝ := (mfderiv% f x) (Y x); + have h2 : letI dfY : ℝ := fromTangentSpace _ ((mfderiv% f x) (Y x)); ⟪X, mlieBracket I (f • Z) Y⟫ x = - dfY • ⟪X, Z⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by rw [product_apply, VectorField.mlieBracket_smul_left hf hZ, inner_add_right, inner_smul_right, inner_smul_right] From 604f71dd0a5356a7950a223c2849b5c1c99f257d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 21:12:24 +0000 Subject: [PATCH 551/601] chore(LeviCivita): remove a few no longer needed type ascriptions --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 27c1aa8e362148..ff9c357b7ed1ef 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -147,14 +147,14 @@ lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I variable (X) in lemma rhs_aux_smulY_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X (f • Y) Z x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by rw [rhs_aux, product_smul_left, mfderiv_smul (hY.inner_bundle' hZ) hf] rfl variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by ext x simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] @@ -176,14 +176,14 @@ lemma rhs_aux_smulY_const {a : ℝ} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : variable (X) in lemma rhs_aux_smulZ_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X Y (f • Z) x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by rw [rhs_aux_swap, rhs_aux_smulY_apply, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] variable (X) in lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : - letI A (x) : ℝ := fromTangentSpace _ ((mfderiv% f x) (X x)) + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] @@ -294,7 +294,6 @@ lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M → ℝ} have h4 : inner ℝ (Z x) (f x • mlieBracket I Y X x) = f x * ⟪Z, mlieBracket I Y X⟫ x := by rw [product_apply, real_inner_smul_right] rw [real_inner_smul_right (Y x), h3, h4] - -- Push all applications of `x` inwards, then it's indeed obvious. simp -- set A := ⟪Y, mlieBracket I X Z⟫ with hA @@ -490,7 +489,7 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} rw [product_apply, VectorField.mlieBracket_smul_right hf hZ, inner_add_right, add_comm, inner_smul_right] congr - have h2 : letI dfY : ℝ := fromTangentSpace _ ((mfderiv% f x) (Y x)); + have h2 : letI dfY := fromTangentSpace _ ((mfderiv% f x) (Y x)); ⟪X, mlieBracket I (f • Z) Y⟫ x = - dfY • ⟪X, Z⟫ x + f x • ⟪X, mlieBracket I Z Y⟫ x := by rw [product_apply, VectorField.mlieBracket_smul_left hf hZ, inner_add_right, inner_smul_right, inner_smul_right] From 05b22d63715264a560a1a1ce57e45aab0e8023bb Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 19:20:38 +0000 Subject: [PATCH 552/601] aux1 in Metric.lean is sorry-free again: mfderiv_smul has too much defeq abuse --- Mathlib/Geometry/Manifold/MfDerivSMul.lean | 4 +- .../CovariantDerivative/Metric.lean | 53 +++++-------------- 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MfDerivSMul.lean b/Mathlib/Geometry/Manifold/MfDerivSMul.lean index 5c21e2705c6d62..e2d4a52ac8b2ff 100644 --- a/Mathlib/Geometry/Manifold/MfDerivSMul.lean +++ b/Mathlib/Geometry/Manifold/MfDerivSMul.lean @@ -53,8 +53,8 @@ lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) set_option linter.flexible false in -- FIXME lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) (hs : MDiffAt s x) (v : TangentSpace I x) : - letI dsxv : 𝕜 := mfderiv% s x v - letI dfxv : F := mfderiv% f x v + letI dsxv := NormedSpace.fromTangentSpace (s x) (mfderiv% s x v) + letI dfxv := NormedSpace.fromTangentSpace (f x) (mfderiv% f x v) mfderiv% (s • f) x v = (s x) • dfxv + dsxv • f x := by set φ := chartAt H x -- TODO: the next two have should be special cases of the same lemma diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index c88a629b5f5d28..07756f1af210ae 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -189,56 +189,32 @@ noncomputable def compatibilityTensorAux (Y Z : Π x : M, TangentSpace I x) : letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) -lemma compatibilityTensorAux_apply (Y Z : Π x : M, TangentSpace I x) {x : M} (X₀ : TangentSpace I x) : +lemma compatibilityTensorAux_apply (Y Z : Π x : M, TangentSpace I x) + {x : M} (X₀ : TangentSpace I x) : compatibilityTensorAux I cov Y Z x X₀ = NormedSpace.fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x X₀) - + inner ℝ (Z x) (cov Y x X₀) - inner ℝ (Y x) (cov Z x X₀) := by + - innerSL ℝ (Z x) (cov Y x X₀) - innerSL ℝ (Y x) (cov Z x X₀) := by unfold compatibilityTensorAux simp - -- change mfderiv% ⟪Y, Z⟫ x X₀ - (innerSL ℝ) (Z x) (cov Y x) X₀ = _ - --congr - --let A := mfderiv% ⟪Y, Z⟫ x - --rw [Pi.sub_apply] - --rw [ContinuousLinearMap.comp_apply] - - --simp - - sorry + congr 1 variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x : M} -set_option backward.isDefEq.respectTransparency false in variable {I} in private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov (f • σ) τ x = f x • compatibilityTensorAux I cov σ τ x := by - unfold compatibilityTensorAux + ext X₀ + rw [compatibilityTensorAux_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, + compatibilityTensorAux_apply] rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] - ext X - simp - -- simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, - -- RingHom.id_apply, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, - -- ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', - -- coe_innerSL_apply, Pi.sub_apply, Pi.smul_apply, comp_apply] - --erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] - -- conv => - -- enter [1, 1, 2] - -- --erw [ContinuousLinearMap.add_apply] - -- conv => - -- enter [1, 1, 2, 1] - -- --erw [ContinuousLinearMap.smul_apply] - rw [--ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, - --ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply, - --innerSL_apply_apply, innerSL_apply_apply, ContinuousLinearMap.toSpanSingleton_apply, - inner_smul_right, mfderiv_smul (hσ.inner_bundle' hτ) hf] - simp only [smul_eq_mul, Pi.mul_apply, fromTangentSpace, ContinuousLinearEquiv.coe_coe, - ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] - conv => - enter [1, 1, 1, 2, 2] - dsimp [product] - rw [real_inner_comm] - rw [← sub_eq_zero] - ring + simp only [Pi.smul_apply', ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', + Pi.smul_apply, ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, comp_apply, + ContinuousLinearMap.toSpanSingleton_apply, coe_innerSL_apply, map_smul] + erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] -- identifying different tangent spaces + rw [inner_add_right, inner_smul_right, inner_smul_right, real_inner_comm (σ x) (τ x)] + simp only [← smul_eq_mul] + module variable {I} in private lemma aux2 (σ σ' τ : (x : M) → TangentSpace I x) @@ -361,7 +337,6 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ E] (x : M) --rw [compatibilityTensorAux_apply] simp only [compatibilityTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] - conv => enter [1, 1] erw [ContinuousLinearMap.sub_apply] From 95f5ea3a7d4416963a91e1920179d94f6a38b281 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 21:51:20 +0000 Subject: [PATCH 553/601] Fix aux4 --- .../CovariantDerivative/Metric.lean | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 07756f1af210ae..b867ac7aafff7d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -282,32 +282,16 @@ private lemma aux4 (σ τ τ' : (x : M) → TangentSpace I x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : compatibilityTensorAux I cov σ (τ + τ') x = compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ τ' x := by - unfold compatibilityTensorAux - ext X - simp only [Pi.add_apply, map_add, ContinuousLinearMap.add_comp, ContinuousLinearMap.coe_sub', - ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply, - ContinuousLinearMap.add_apply] + ext X₀ + rw [compatibilityTensorAux_apply]; dsimp + rw [compatibilityTensorAux_apply, compatibilityTensorAux_apply]; dsimp rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), cov.isCovariantDerivativeOn.add hτ hτ'] - dsimp - rw [inner_add_right] - erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, - ContinuousLinearMap.add_apply, ContinuousLinearMap.comp_apply] - /- TODO: proof used to be done before merging rc4; was: - conv => - enter [2, 2, 1, 2] - erw [ContinuousLinearMap.comp_apply] - rw [innerSL_apply_apply] - conv => - enter [2, 2, 1, 2] - erw [innerSL_apply_apply] - module -/ - sorry - -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ'⟫ x - -- set C := inner ℝ (σ x) ((cov τ x) X) - -- set C' := inner ℝ (σ x) ((cov τ' x) X) - -- set D := (cov σ x) X + simp only [Pi.add_apply, ContinuousLinearMap.add_apply, inner_add_left, inner_add_right, + fromTangentSpace, -- this line is slightly fishy + ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] + erw [ContinuousLinearMap.add_apply] + module theorem compatibilityTensorAux_tensorial₁ (τ : Π x, TangentSpace I x) (hτ : MDiffAt (T% τ) x) : TensorialAt I E (compatibilityTensorAux I cov · τ x) x where From 99544933219ca8c0534a7e42820d6dd5f5c67d6c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 21:54:09 +0000 Subject: [PATCH 554/601] Minor polish --- .../Manifold/VectorBundle/CovariantDerivative/Trivial.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index 0802d293100b36..0f7a471547fd45 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -16,12 +16,12 @@ Don't be afraid to ask. TODO! -/ -open Bundle Filter Module Topology Set -open scoped Bundle Manifold ContDiff +open Bundle +open scoped Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -@[expose] public section -- TODO: think if we want to expose all definitions! +@[expose] public section open Bundle Filter Module Topology Set @@ -84,7 +84,6 @@ noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial end trivial_bundle - variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] -- TODO: does it make sense to speak of analytic connections? if so, change the definition of From db5c01d647cbdf9df9319e6767629a917f0181b8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 17:29:23 +0000 Subject: [PATCH 555/601] chore: add missing bar; and use mfderiv% and mfderiv[s] slightly more --- .../Geometry/Manifold/VectorField/LieBracket.lean | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 79fd6cdac7dbbb..5e94cd34d8716b 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -29,7 +29,7 @@ The main results are the following: @[expose] public section -open Set Function Filter +open Set Function Filter NormedSpace open scoped Topology Manifold ContDiff noncomputable section @@ -360,9 +360,9 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDiffAt[s] f x) (hW : MDiffAt[s] (fun x ↦ (W x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : - -- TODO: add fromTangentSpace mlieBracketWithin I V (f • W) s x = - (mfderivWithin I 𝓘(𝕜) f s x) (V x) • (W x) + (f x) • mlieBracketWithin I V W s x := by + (fromTangentSpace (f x) (mfderiv[s] f x (V x))) • (W x) + + (f x) • mlieBracketWithin I V W s x := by simp only [mlieBracketWithin, mpullbackWithin_smul] -- Simplify local notation a bit. set V' := mpullbackWithin 𝓘(𝕜, E) I (extChartAt I x).symm V (range I) @@ -392,7 +392,7 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDiffAt f x) (hW : MDiffAt (fun x ↦ (W x : TangentBundle I M)) x) : mlieBracket I V (f • W) x = - NormedSpace.fromTangentSpace (f x) (mfderiv% f x (V x)) • (W x) + (fromTangentSpace (f x) (mfderiv% f x (V x))) • (W x) + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hW rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] @@ -407,8 +407,8 @@ lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDiffAt[s] f x) (hV : MDiffAt[s] (fun x ↦ (V x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (f • V) W s x = - -- TODO: add fromTangentSpace! - -(mfderivWithin I 𝓘(𝕜) f s x) (W x) • (V x) + (f x) • mlieBracketWithin I V W s x := by + -(fromTangentSpace (f x) (mfderiv[s] f x (W x))) • (V x) + + (f x) • mlieBracketWithin I V W s x := by rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_smul_right hf hV (V := W) hs, mlieBracketWithin_swap] simp; abel @@ -421,7 +421,7 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracket_smul_left {f : M → 𝕜} (hf : MDiffAt f x) (hV : MDiffAt (fun x ↦ (V x : TangentBundle I M)) x) : mlieBracket I (f • V) W x = - - (NormedSpace.fromTangentSpace (f x) (mfderiv% f x (W x))) • (V x) + - (fromTangentSpace (f x) (mfderiv% f x (W x))) • (V x) + (f x) • mlieBracket I V W x := by rw [← mdifferentiableWithinAt_univ] at hf hV rw [← mlieBracketWithin_univ, ← mfderivWithin_univ] From e8a2882b846970eefd524e4a18518a1eeea22e9d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 22:41:34 +0000 Subject: [PATCH 556/601] Fix build --- Mathlib.lean | 1 - .../Manifold/MFDeriv/NormedSpace.lean | 21 --- .../CovariantDerivative/TrivPrelim.lean | 2 +- .../Manifold/VectorBundle/Delaborators.lean | 138 ------------------ 4 files changed, 1 insertion(+), 161 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean diff --git a/Mathlib.lean b/Mathlib.lean index a78c926e78f319..6f5e87778bef20 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4440,7 +4440,6 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial -public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 08a444f150020f..05eeb1a323317f 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -104,27 +104,6 @@ end extChartAt end Module -section ExtChartAt - -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {f : M → F} - --- TODO: add pre-composition version also -theorem MDifferentiableWithinAt.differentiableWithinAt_comp_extChartAt_symm - (hf : MDifferentiableWithinAt I 𝓘(𝕜, F) f s x) : - letI φ := extChartAt I x - DifferentiableWithinAt 𝕜 (f ∘ φ.symm) (φ.symm ⁻¹' s ∩ range I) (φ x) := by - simpa [extChartAt_self_eq] using (mdifferentiableWithinAt_iff.1 hf).2 - --- TODO: the `IsManifold I 1 M` assumption can probably be removed -theorem DifferentiableWithinAt.mdifferentiableWithinAt_of_comp_extChartAt_symm [IsManifold I 1 M] - (hf : letI φ := extChartAt I x - DifferentiableWithinAt 𝕜 (f ∘ φ.symm) (φ.symm ⁻¹' s ∩ range I) (φ x)) : - MDifferentiableWithinAt I 𝓘(𝕜, F) f s x := by - refine (mdifferentiableWithinAt_iff_source_of_mem_source (mem_chart_source H x)).2 ?_ - simpa [extChartAt_self_eq] using hf.mdifferentiableWithinAt - -end ExtChartAt - /-! ### Linear maps between normed spaces are differentiable -/ theorem MDifferentiableWithinAt.clm_precomp {f : M → F₁ →L[𝕜] F₂} {s : Set M} {x : M} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index e173dc7a7fd39c..719ba680b00d5f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -8,7 +8,7 @@ module public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary public import Mathlib.Geometry.Manifold.MFDeriv.Atlas public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable -public import Mathlib.Geometry.Manifold.VectorBundle.Delaborators +public import Mathlib.Geometry.Manifold.Notation /-! # Supporting lemmas for CovariantDerivative.Basic trivialization stuff diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean b/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean deleted file mode 100644 index 1187c35fa8f95b..00000000000000 --- a/Mathlib/Geometry/Manifold/VectorBundle/Delaborators.lean +++ /dev/null @@ -1,138 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ -module - -public import Mathlib.Geometry.Manifold.MFDeriv.Atlas -public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable - -/-! -# Delaborators for the custom elaborators - --/ - -open Bundle Filter Module Topology Set - -open scoped Bundle Manifold ContDiff - -@[expose] public section - -section delaborators - -open Lean PrettyPrinter Delaborator SubExpr - -open scoped Bundle Manifold ContDiff - -@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do - whenPPOption getPPNotation do - withOverApp 5 do - let bd ← withNaryArg 3 <| delab - let vd ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - -@[app_delab Bundle.TotalSpace.mk'] meta def delabTotalSpace_mk' : Delab := do - whenPPOption getPPNotation do - withOverApp 5 do - let bd ← withNaryArg 3 <| delab - let vd ← withNaryArg 4 <| delab - `(⟨$bd, $vd⟩) - -@[app_delab mfderiv] meta def delab_mfderiv : Delab := do - whenPPOption getPPNotation do - withOverApp 21 do - try - let fe := (← getExpr).appArg! - let .lam n _ b _ := fe | failure - guard <| b.isAppOf ``Bundle.TotalSpace.mk' - let σe := b.getAppArgs[4]!.getAppFn - guard <| σe.isFVar - let Tσs ← withAppArg do - let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab - `(T% $σs) >>= annotateGoToSyntaxDef - `(mfderiv% ($Tσs)) >>= annotateGoToSyntaxDef - catch _ => - let fs ← withAppArg delab - `(mfderiv% $fs) >>= annotateGoToSyntaxDef - -@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do - whenPPOption getPPNotation do - withOverApp 21 do - try - let fe := (← getExpr).appArg! - let .lam n _ b _ := fe | failure - guard <| b.isAppOf ``Bundle.TotalSpace.mk' - let σe := b.getAppArgs[4]!.getAppFn - guard <| σe.isFVar - let Tσs ← withAppArg do - let σs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab - `((T% $σs)) >>= annotateGoToSyntaxDef - `(MDiffAt $Tσs) >>= annotateGoToSyntaxDef - catch _ => - let fs ← withAppArg delab - `(MDiffAt $fs) >>= annotateGoToSyntaxDef - -@[app_delab MDifferentiableWithinAt] meta def delabMDifferentiableWithinAt : Delab := do - whenPPOption getPPNotation do - withOverApp 22 do - let ss ← withAppArg delab - try - let f := (← getExpr).getAppArgs[20]! - let .lam n _ b _ := f | failure - guard <| b.isAppOf ``Bundle.TotalSpace.mk' - let s := b.getAppArgs[4]!.getAppFn - guard <| s.isFVar - let fs ← withNaryArg 20 do - let fs ← withBindingBody n <| withNaryArg 4 <| withNaryFn delab - `((T% $fs)) >>= annotateGoToSyntaxDef - `(MDiffAt[$ss] $fs) >>= annotateGoToSyntaxDef - catch _ => - let fs ← withNaryArg 20 <| delab - `(MDiffAt[$ss] $fs) >>= annotateGoToSyntaxDef - -section - -open Bundle -open scoped Bundle Manifold ContDiff - -variable - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] - [ChartedSpace H M] [IsManifold I ∞ M] - (f : M → M) (x : M) (s : Set M) - (v : (x : M) → TangentSpace I x) - -/-- info: MDiffAt f x : Prop -/ -#guard_msgs in -#check MDiffAt f x - -/-- info: MDiffAt[s] f x : Prop -/ -#guard_msgs in -#check MDiffAt[s] f x - -/-- info: MDiffAt (T% v) x : Prop -/ -#guard_msgs in -#check MDiffAt (T% v) x - -/-- info: MDiffAt[s] (T% v) x : Prop -/ -#guard_msgs in -#check MDiffAt[s] (T% v) x - -/-- info: mfderiv% f x : TangentSpace I x →L[ℝ] TangentSpace I (f x) -/ -#guard_msgs in -#check mfderiv% f x - -/-- info: mfderiv% (T% v) x : TangentSpace I x →L[ℝ] TangentSpace (I.prod 𝓘(ℝ, E)) ⟨x, v x⟩ -/ -#guard_msgs in -#check mfderiv% (T% v) x - -/-- info: ⟨x, v x⟩ : TotalSpace E (TangentSpace I) -/ -#guard_msgs in -#check TotalSpace.mk' E x (v x) - -/-- info: ⟨x, v x⟩ : TotalSpace E (TangentSpace I) -/ -#guard_msgs in -#check TotalSpace.mk (F := E) x (v x) -end -end delaborators From 078e3d51783401422825da8ccc4cff45dfd437d8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 22:46:26 +0000 Subject: [PATCH 557/601] doc(LeviCivita): extend the module doc-string a bit; removed unused arguments --- .../CovariantDerivative/LeviCivita.lean | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ff9c357b7ed1ef..e8de5d92a9f9e2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -12,13 +12,15 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion /-! # The Levi-Civita connection on a Riemannian manifold +To be continued and polished! + This file defines the Levi-Civita connection on a (finite-dimensional) Riemannian manifold `(M, g)`. connection `∇` on the tangent bundle of a Riemannian manifold `(M, g)` is called a *Levi-Civita connection* if and only if it is both compatible with the metric `g` and torsion-free. Any two such connections are equal (on differentiable vector fields), which is why one speaks of *the* Levi-Civita connection on `TM`. -We construct a Levi-Civita connection (using a tensoriality argument), and proves that is defines -a metric and torsion-free connection. +We construct a Levi-Civita connection and prove that is defines a compatible torsion-free +connection. ## Main definitions and results @@ -29,14 +31,16 @@ a metric and torsion-free connection. * `CovariantDerivative.IsLeviCivitaConnection.uniqueness`: a Levi-Civita connection on `(M, g)` is uniquely determined on differentiable vector fields. -To be continued! - -We prove the existence and uniqueness of the Levi-Civita connection - - +* `CovariantDerivative.LeviCivitaConnection`: a choice of Levi-Civita connection on the tangent + bundle `TM` of a Riemannian manifold `(M, g)`: this is unique up to the value on + non-differentiable vector fields. + If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. +* `CovariantDerivative.leviCivitaConnection_isLeviCivitaConnection`: + `LeviCivitaConnection` is a Levi-Civita connection (i.e., compatible and torsion-free) ## Implementation notes - +* construction of LC using a tensoriality argument, and the musical isomorphism + (avoids the use of local frames and trivialisations) -/ @@ -760,7 +764,8 @@ theorem leviCivitaConnection_apply [FiniteDimensional ℝ E] {x : M} lcAux_apply _ hX hY hZ -- Side computation for `leviCivitaConnection_isCompatible`. -lemma leviCivitaConnection_isCompatible_aux [FiniteDimensional ℝ E] +omit [IsManifold I 2 M] in +lemma leviCivitaConnection_isCompatible_aux {x : M} {X Y Z : (x : M) → TangentSpace I x} : leviCivitaRhs I X Y Z x + leviCivitaRhs I X Z Y x = ((mfderiv% fun x ↦ inner ℝ (Y x) (Z x)) x) (X x) := by @@ -831,6 +836,7 @@ lemma leviCivitaConnection_torsion_eq_zero [FiniteDimensional ℝ E] : match_scalars <;> simp norm_num +/-- `LeviCivitaConnection` is a Levi-Civita connection (i.e., compatible and torsion-free) -/ lemma leviCivitaConnection_isLeviCivitaConnection [FiniteDimensional ℝ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := ⟨leviCivitaConnection_isCompatible I, leviCivitaConnection_torsion_eq_zero I⟩ From 6a21dcc09d187fd828a2a1e4a4990e55ac645516 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 22:52:10 +0000 Subject: [PATCH 558/601] chore(LeviCivita): small polish and golf --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e8de5d92a9f9e2..e5679e90173193 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -702,8 +702,8 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : ext X₀ Y₀ simp only [TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, lcAux₀'] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] - · apply leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) hY hY' - exact mdifferentiableAt_extend .. + · exact leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) + hY hY' (mdifferentiableAt_extend ..) · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. @@ -731,13 +731,10 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : simp only [lcAux₀, lcAux₀', TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] - · have key := leviCivitaRhs_smulY_apply I (X := _root_.extend E X₀) (Y := Y) - (Z := _root_.extend E Z₀) (x := x) (f := f) - convert key hf ?_ hY ?_ + · convert leviCivitaRhs_smulY_apply I (Z := _root_.extend E Z₀) (x := x) + hf (mdifferentiableAt_extend I E X₀) hY (mdifferentiableAt_extend I E Z₀) · simp · simp [Φ, product] - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. · exact mdifferentiableAt_extend .. From 0f48d2d10811e74470bba9213e05c1e85c3b6315 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Fri, 6 Mar 2026 22:08:26 +0000 Subject: [PATCH 559/601] chore: transplant improvements from PR --- Mathlib/Geometry/Manifold/MfDerivSMul.lean | 89 +++++++++------------- 1 file changed, 34 insertions(+), 55 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MfDerivSMul.lean b/Mathlib/Geometry/Manifold/MfDerivSMul.lean index e2d4a52ac8b2ff..0e0da7381379b8 100644 --- a/Mathlib/Geometry/Manifold/MfDerivSMul.lean +++ b/Mathlib/Geometry/Manifold/MfDerivSMul.lean @@ -7,75 +7,54 @@ module public import Mathlib.Geometry.Manifold.MFDeriv.Atlas public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace -public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.Notation -/-! -# Auxiliary lemmas about mfderiv and scalar multiplication +/-! # `mfderiv` and scalar multiplication -/ --/ - -open Bundle Filter Module Topology Set -open scoped Bundle Manifold ContDiff +open Set +open scoped Manifold ContDiff @[expose] public section mfderiv variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M] {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] - -set_option backward.isDefEq.respectTransparency false in --- cleaned up and PRed in #34262 -lemma mfderiv_const_smul (s : M → F) {x : M} (a : 𝕜) (v : TangentSpace I x) : - mfderiv% (a • s) x v = a • mfderiv% s x v := by - by_cases hs : MDiffAt s x - · have hs' := hs.const_smul a - suffices - (fderivWithin 𝕜 ((a • s) ∘ (chartAt H x).symm ∘ I.symm) (range I) (I ((chartAt H x) x))) v = - a • (fderivWithin 𝕜 (s ∘ (chartAt H x).symm ∘ I.symm) (range I) - (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] - change fderivWithin 𝕜 (a • (s ∘ ↑(chartAt H x).symm ∘ ↑I.symm)) _ _ _ = _ - rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] - rfl - · by_cases ha : a = 0 - · have : a • s = 0 := by ext; simp [ha] - rw [this, ha] - change (mfderiv I 𝓘(𝕜, F) (fun _ ↦ 0) x) v = _ - simp - have hs' : ¬ MDiffAt (a • s) x := - fun h ↦ hs (by simpa [ha] using h.const_smul a⁻¹) - rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] - simp - rfl - --- PRed and cleaned up in #34263 -set_option linter.flexible false in -- FIXME -lemma mfderiv_smul [IsManifold I 1 M] {f : M → F} {s : M → 𝕜} {x : M} (hf : MDiffAt f x) + {f : M → F} {s : M → 𝕜} {x : M} + +theorem MDifferentiableAt.differentiableAt_comp_chartAt_symm + (hs : MDiffAt f x) : + letI φ := chartAt H x; + DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by + have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + rw [← extChartAt_to_inv x (I := I)] at hs + have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + +lemma mfderiv_smul (hf : MDiffAt f x) (hs : MDiffAt s x) (v : TangentSpace I x) : letI dsxv := NormedSpace.fromTangentSpace (s x) (mfderiv% s x v) letI dfxv := NormedSpace.fromTangentSpace (f x) (mfderiv% f x v) mfderiv% (s • f) x v = (s x) • dfxv + dsxv • f x := by set φ := chartAt H x - -- TODO: the next two have should be special cases of the same lemma - have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x - rw [← this] at hs - have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this - have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x - rw [← this] at hf - have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + -- TODO: inlining hs' or hf' breaks the proof, why? + have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := + hs.differentiableAt_comp_chartAt_symm + have aux := hs.differentiableAt_comp_chartAt_symm + have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := + hf.differentiableAt_comp_chartAt_symm + -- `have := hs.differentiableAt_comp_chartAt_symm` looks identical apart from unfolding φ have hsf : MDiffAt (s • f) x := hs.smul hf - simp [mfderiv, hsf, hs, hf] - have uniq : UniqueDiffWithinAt 𝕜 (range I) (I (φ x)) := - ModelWithCorners.uniqueDiffWithinAt_image I - erw [fderivWithin_smul uniq hs' hf'] + simp? [mfderiv, hsf, hs, hf] says + simp only [Pi.smul_apply', mfderiv, hsf, ↓reduceIte, writtenInExtChartAt, extChartAt, + OpenPartialHomeomorph.extend, modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, + PartialEquiv.coe_trans_symm, OpenPartialHomeomorph.coe_coe_symm, + ModelWithCorners.toPartialEquiv_coe_symm, PartialEquiv.coe_trans, + ModelWithCorners.toPartialEquiv_coe, OpenPartialHomeomorph.toFun_eq_coe, Function.comp_apply, + hf, hs] + -- Use the defeq that `chartAt (s x)` and `chartAt (f x)` are the identity. + erw [fderivWithin_smul I.uniqueDiffWithinAt_image hs' hf'] simp [φ.left_inv (ChartedSpace.mem_chart_source x)] rfl - -end mfderiv From 0643f0c81a06ea5e15da94b845f034c82e0d3c10 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 10:49:32 +0000 Subject: [PATCH 560/601] generalize to a riemannian bundle --- .../CovariantDerivative/Metric.lean | 169 ++++++++++-------- 1 file changed, 95 insertions(+), 74 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index b867ac7aafff7d..c308e08ea9a841 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -11,27 +11,30 @@ public import Mathlib.Geometry.Manifold.MfDerivSMul /-! # Metric connections -This file defines connections on a Riemannian manifold which are compatible with the ambient metric. -A bundled connection `∇` on `(M, g)` is compatible with the metric `g` if and only if the metric -tensor `∇ g` (defined by `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)`) -vanishes on all differentiable vector fields. +This file defines connections on a Riemannian vector bundle which are compatible with the ambient +metric. A bundled connection `∇` on a Riemannian vector bundle `(V, g)` is compatible with the +metric `g` if and only if the differentiated metric tensor `∇ g` (defined by +`(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)`) vanishes on all differentiable vector fields `X` +and differentiable sections `Y`, `Z`. ## Main definitions and results * `CovariantDerivative.compatibilityTensor`: the tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection `∇` on a Riemannian - manifold `(M, g)` is compatible with the metric `g`. + vector bundle `(V, g)` is compatible with the metric `g`. * `CovariantDerivative.compatibilityTensor_apply` and `CovariantDerivative.compatibilityTensor_apply` give formulas for applying the compatibility - tensor at `x` to vector fields which are differentiable at `x`, - resp. to extensions of tangent vectors at `x` to differentiable vector fields near `x`. -* `CovariantDerivative.IsCompatible`: predicate for a connection to be metric + tensor at `x` to vector fields and sections which are differentiable at `x`, + resp. to extensions of tangent vectors and sections at `x` to differentiable vector fields and + sections near `x`. +* `CovariantDerivative.IsCompatible`: predicate for a connection to be metric, namely that `∇` is metric iff its `compatibilityTensor` vanishes ## TODO -* when mathlib has a notion of parallel transport, define metric connections on general - Riemannian bundles (characterised by parallel transport being an isometry) and prove the - equivalence to this definition + +* when mathlib has a notion of parallel transport, prove the equivalence of + `CovariantDerivative.IsCompatible` with the characterisation that parallel transport be an + isometry. -/ @@ -43,36 +46,43 @@ open scoped Manifold ContDiff -- TODO: revisit and fix this once the dust has settled set_option backward.isDefEq.respectTransparency false --- Let `M` be a `C^k` real manifold modeled on `(E, H)`, endowed with a Riemannian metric. -variable {n : WithTop ℕ∞} +variable + -- Let `M` be a `C^k` real manifold modeled on `(E, H)` {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] - [RiemannianBundle (fun (x : M) ↦ TangentSpace I x)] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 2 M] + -- Let `V` be a bundle over `M`, endowed with a Riemannian metric. + (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module ℝ (V x)] + [∀ x : M, TopologicalSpace (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] + [FiberBundle F V] [RiemannianBundle V] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] -/-! Compatible connections: a connection on `TM` is compatible with the metric on `M` iff -`∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all sufficiently nice vector fields `X`, `Y` and -`Z` on `M`. In our definition, we ask for this identity to at each `x : M`, whenever `X`, `Y` and -`Z` are differentiable at `x`. +/-! Compatible connections: a connection on `V` is compatible with the metric on `M` iff +`∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all sufficiently nice vector fields `X` on `M` and +sections `Y`, `Z` of `V`. In our definition, we ask for this identity to at each `x : M`, whenever +`X`, `Y` and `Z` are differentiable at `x`. The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: the left hand side at `x` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ -variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, TangentSpace I x} +variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, V x} /-- The scalar product of two vector fields -/ -noncomputable abbrev product (X Y : Π x : M, TangentSpace I x) : M → ℝ := +noncomputable abbrev product (X Y : Π x : M, V x) : M → ℝ := fun x ↦ inner ℝ (X x) (Y x) -- `product` is C^k if X and Y are: this is shown in `Riemannian.lean` -local notation "⟪" X ", " Y "⟫" => product I X Y +local notation "⟪" X ", " Y "⟫" => product X Y -- Basic API for the product of two vector fields. section product -omit [IsManifold I 2 M] +omit [TopologicalSpace M] [IsManifold I 2 M] + lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl variable (X X' Y) @@ -98,11 +108,11 @@ lemma product_add_left_apply (x) : ⟪X + X', Y⟫ x = ⟪X, Y⟫ x + ⟪X', Y simp [product, InnerProductSpace.add_left] lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by - rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] + rw [product_swap, product_swap Y, product_swap Y', product_add_left] @[simp] lemma product_add_right_apply (x) : ⟪X, Y + Y'⟫ x = ⟪X, Y⟫ x + ⟪X, Y'⟫ x := by - rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left_apply] + rw [product_swap, product_swap Y, product_swap Y', product_add_left_apply] @[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] @@ -116,21 +126,21 @@ lemma product_sub_right : ⟪X, Y - Y'⟫ = ⟪X, Y⟫ - ⟪X, Y'⟫ := by ext x simp [product, inner_sub_right] -lemma product_smul_left (f : M → ℝ) : product I (f • X) Y = f • product I X Y := by +lemma product_smul_left (f : M → ℝ) : product (f • X) Y = f • product X Y := by ext x simp [product, real_inner_smul_left] @[simp] -lemma product_smul_const_left (a : ℝ) : product I (a • X) Y = a • product I X Y := by +lemma product_smul_const_left (a : ℝ) : product (a • X) Y = a • product X Y := by ext x simp [product, real_inner_smul_left] -lemma product_smul_right (f : M → ℝ) : product I X (f • Y) = f • product I X Y := by +lemma product_smul_right (f : M → ℝ) : product X (f • Y) = f • product X Y := by ext x simp [product, real_inner_smul_right] @[simp] -lemma product_smul_const_right (a : ℝ) : product I X (a • Y) = a • product I X Y := by +lemma product_smul_const_right (a : ℝ) : product X (a • Y) = a • product X Y := by ext x simp [product, real_inner_smul_right] @@ -138,21 +148,21 @@ end product -- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) -- only hold point-wise. They abstract the expanding and unexpanding of `product`. -omit [IsManifold I 2 M] in -lemma product_congr_left {x} (h : X x = X' x) : product I X Y x = product I X' Y x := by +omit [TopologicalSpace M] [IsManifold I 2 M] in +lemma product_congr_left {x} (h : X x = X' x) : product X Y x = product X' Y x := by rw [product_apply, h, ← product_apply] -omit [IsManifold I 2 M] in +omit [TopologicalSpace M] [IsManifold I 2 M] in lemma product_congr_left₂ {x} (h : X x = X' x + X'' x) : - product I X Y x = product I X' Y x + product I X'' Y x := by + product X Y x = product X' Y x + product X'' Y x := by rw [product_apply, h, inner_add_left, ← product_apply] -omit [IsManifold I 2 M] in -lemma product_congr_right {x} (h : Y x = Y' x) : product I X Y x = product I X Y' x := by +omit [TopologicalSpace M] [IsManifold I 2 M] in +lemma product_congr_right {x} (h : Y x = Y' x) : product X Y x = product X Y' x := by rw [product_apply, h, ← product_apply] -omit [IsManifold I 2 M] in +omit [TopologicalSpace M] [IsManifold I 2 M] in lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : - product I X Y x = product I X Y' x + product I X Y'' x := by + product X Y x = product X Y' x + product X Y'' x := by rw [product_apply, h, inner_add_right, ← product_apply] /- TODO: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` @@ -164,32 +174,34 @@ inferred fun b ↦ inst✝⁷ Diagnose and fix this, and then replace the below by `MDifferentiable(At).inner_bundle! -/ -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable {F} [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {I} in lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := MDifferentiable.inner_bundle hY hZ -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {I} in +variable {F} [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {I} in lemma MDifferentiableAt.inner_bundle' {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : MDiffAt ⟪Y, Z⟫ x := MDifferentiableAt.inner_bundle hY hZ namespace CovariantDerivative --- Let `cov` be a covariant derivative on `TM`. +-- Let `cov` be a covariant derivative on `V`. -- TODO: include in cheat sheet! -variable (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) +variable (cov : CovariantDerivative I F V) /-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) +variable {F} + /-- The function defining the compatibility tensor for `∇` w.r.t. `g`: prefer using `compatibilityTensor` instead -/ -noncomputable def compatibilityTensorAux (Y Z : Π x : M, TangentSpace I x) : +noncomputable def compatibilityTensorAux (Y Z : Π x : M, V x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) -lemma compatibilityTensorAux_apply (Y Z : Π x : M, TangentSpace I x) +lemma compatibilityTensorAux_apply (Y Z : Π x : M, V x) {x : M} (X₀ : TangentSpace I x) : compatibilityTensorAux I cov Y Z x X₀ = NormedSpace.fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x X₀) @@ -198,10 +210,10 @@ lemma compatibilityTensorAux_apply (Y Z : Π x : M, TangentSpace I x) simp congr 1 -variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) ↦ TangentSpace I x)] {x : M} +variable [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {x : M} variable {I} in -private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} +private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → V x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov (f • σ) τ x = f x • compatibilityTensorAux I cov σ τ x := by ext X₀ @@ -217,7 +229,7 @@ private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} module variable {I} in -private lemma aux2 (σ σ' τ : (x : M) → TangentSpace I x) +private lemma aux2 (σ σ' τ : (x : M) → V x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov (σ + σ') τ x = compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ' τ x := by @@ -245,7 +257,7 @@ private lemma aux2 (σ σ' τ : (x : M) → TangentSpace I x) module variable {I} in -private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} +private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → V x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov σ (f • τ) x = f x • compatibilityTensorAux I cov σ τ x := by unfold compatibilityTensorAux @@ -278,7 +290,7 @@ private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → TangentSpace I x} match_scalars <;> all_goals simp variable {I} in -private lemma aux4 (σ τ τ' : (x : M) → TangentSpace I x) +private lemma aux4 (σ τ τ' : (x : M) → V x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : compatibilityTensorAux I cov σ (τ + τ') x = compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ τ' x := by @@ -293,26 +305,28 @@ private lemma aux4 (σ τ τ' : (x : M) → TangentSpace I x) erw [ContinuousLinearMap.add_apply] module -theorem compatibilityTensorAux_tensorial₁ (τ : Π x, TangentSpace I x) (hτ : MDiffAt (T% τ) x) : - TensorialAt I E (compatibilityTensorAux I cov · τ x) x where +theorem compatibilityTensorAux_tensorial₁ (τ : Π x, V x) (hτ : MDiffAt (T% τ) x) : + TensorialAt I F (compatibilityTensorAux I cov · τ x) x where smul hf hσ := aux1 cov hf hσ hτ add hσ hσ' := aux2 cov _ _ _ hσ hσ' hτ -theorem compatibilityTensorAux_tensorial₂ (σ : Π x, TangentSpace I x) (hσ : MDiffAt (T% σ) x) : - TensorialAt I E (compatibilityTensorAux I cov σ · x) x where +theorem compatibilityTensorAux_tensorial₂ (σ : Π x, V x) (hσ : MDiffAt (T% σ) x) : + TensorialAt I F (compatibilityTensorAux I cov σ · x) x where smul hf hτ := aux3 cov hf hσ hτ add hτ hτ' := aux4 cov _ _ _ hσ hτ hτ' -variable {I} in +variable {I} [ContMDiffVectorBundle 1 F V I] in /-- The tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection -`∇` on a Riemannian manifold `(M, g)` is compatible with the metric `g`. -/ -@[no_expose] noncomputable def compatibilityTensor [FiniteDimensional ℝ E] (x : M) : - TangentSpace I x →L[ℝ] TangentSpace I x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := +`∇` on a Riemannian bundle `(M, V)` is compatible with the metric `g`. -/ +@[no_expose] noncomputable def compatibilityTensor [FiniteDimensional ℝ F] (x : M) : + V x →L[ℝ] V x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := TensorialAt.mkHom₂ (compatibilityTensorAux I cov · · x) _ (compatibilityTensorAux_tensorial₁ I cov) (compatibilityTensorAux_tensorial₂ I cov) -variable {I} in -theorem compatibilityTensor_apply [FiniteDimensional ℝ E] (x : M) +variable {X : Π x : M, TangentSpace I x} + +variable {I} [ContMDiffVectorBundle 1 F V I] in +theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : compatibilityTensor cov x (Y x) (Z x) (X x) = fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by @@ -329,27 +343,32 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ E] (x : M) erw [ContinuousLinearMap.comp_apply] simp [product, real_inner_comm, fromTangentSpace] -variable {I} in -theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ E] (X₀ Y₀ Z₀ : TangentSpace I x) : +open FiberBundle in +variable {I} [ContMDiffVectorBundle 1 F V I] in +theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ F] (X₀ : TangentSpace I x) + (Y₀ Z₀ : V x) : compatibilityTensor cov x Y₀ Z₀ X₀ = - fromTangentSpace _ (mfderiv% ⟪(extend E Y₀), (extend E Z₀)⟫ x X₀) - - ⟪∇ extend E Y₀, (extend E X₀), extend E Z₀⟫ x - - ⟪extend E Y₀, ∇ extend E Z₀, (extend E X₀)⟫ x := by + fromTangentSpace _ (mfderiv% ⟪(extend F Y₀), (extend F Z₀)⟫ x X₀) + - ⟪∇ extend F Y₀, (extend E X₀), extend F Z₀⟫ x + - ⟪extend F Y₀, ∇ extend F Z₀, (extend E X₀)⟫ x := by simpa [extend_apply_self] using compatibilityTensor_apply cov x - (X := extend E X₀) (mdifferentiableAt_extend I E Y₀) (mdifferentiableAt_extend I E Z₀) + (X := extend E X₀) (mdifferentiableAt_extend I F Y₀) (mdifferentiableAt_extend I F Z₀) -/-- Predicate saying for a connection `∇` on a Riemannian manifold `(M, g)` to be compatible with -the ambient metric, i.e. for all differentiable` vector fields `X`, `Y` and `Z` on `M`, we have +variable {I} [ContMDiffVectorBundle 1 F V I] in +/-- Predicate saying for a connection `∇` on a Riemannian bundle `(V, g)` to be compatible with +the ambient metric, i.e. for all differentiable vector fields `X` on `M` and sections `Y` and `Z` +of `V`, we have `X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ -def IsCompatible [FiniteDimensional ℝ E] : Prop := compatibilityTensor cov = 0 +def IsCompatible [FiniteDimensional ℝ F] : Prop := compatibilityTensor cov = 0 -- Auxiliary computation for `IsCompatible_apply`. -- TODO: inlining this lemma does not work private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + C := by grind +variable {I} [ContMDiffVectorBundle 1 F V I] in -- TODO: give a better name; maybe inline? -variable {I} in -lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) +-- variable {I} in +lemma isCompatible_apply [FiniteDimensional ℝ F] (hcov : cov.IsCompatible) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by rw [IsCompatible] at hcov @@ -358,17 +377,19 @@ lemma isCompatible_apply [FiniteDimensional ℝ E] (hcov : cov.IsCompatible) change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ exact isCompatible_apply_aux this -lemma isCompatible_iff [FiniteDimensional ℝ E] : - cov.IsCompatible ↔ ∀ {x : M} {X Y Z : (x : M) → TangentSpace I x} +open FiberBundle in +variable {I} [ContMDiffVectorBundle 1 F V I] in +lemma isCompatible_iff [FiniteDimensional ℝ F] : + cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {Y Z : (x : M) → V x} (_hX : MDiffAt (T% X) x) (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ unfold IsCompatible - ext x X₀ Y₀ Z₀ + ext x Y₀ Z₀ X₀ rw [compatibilityTensor_apply_eq_extend, sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] - have h' := h (mdifferentiableAt_extend I E Z₀) (mdifferentiableAt_extend I E X₀) - (mdifferentiableAt_extend I E Y₀) + have h' := h (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I F Y₀) + (mdifferentiableAt_extend I F Z₀) simpa [fromTangentSpace, extend_apply_self] using h' end CovariantDerivative From 6977518c3d16cca9ca8cc081f2770d2f57eeae1e Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 10:59:09 +0000 Subject: [PATCH 561/601] update notation after generalisation --- .../CovariantDerivative/Metric.lean | 167 +++++++++--------- 1 file changed, 82 insertions(+), 85 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index c308e08ea9a841..84edd402ac5a33 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -14,13 +14,13 @@ public import Mathlib.Geometry.Manifold.MfDerivSMul This file defines connections on a Riemannian vector bundle which are compatible with the ambient metric. A bundled connection `∇` on a Riemannian vector bundle `(V, g)` is compatible with the metric `g` if and only if the differentiated metric tensor `∇ g` (defined by -`(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)`) vanishes on all differentiable vector fields `X` -and differentiable sections `Y`, `Z`. +`(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)`) vanishes on all differentiable vector fields `X` +and differentiable sections `σ`, `τ`. ## Main definitions and results * `CovariantDerivative.compatibilityTensor`: the tensor - `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection `∇` on a Riemannian + `(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)` defining when a connection `∇` on a Riemannian vector bundle `(V, g)` is compatible with the metric `g`. * `CovariantDerivative.compatibilityTensor_apply` and `CovariantDerivative.compatibilityTensor_apply` give formulas for applying the compatibility @@ -59,88 +59,86 @@ variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] [FiberBundle F V] [RiemannianBundle V] -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] +/-! Compatible connections: a connection on `V` is compatible with the metric on `V` iff +`∇ X ⟨σ, τ⟩ = ⟨∇ X σ, τ⟩ + ⟨σ, ∇ X τ⟩` holds for all sufficiently nice vector fields `X` on `M` and +sections `σ`, `τ` of `V`. In our definition, we ask for this identity to at each `x : M`, whenever +`X`, `σ` and `τ` are differentiable at `x`. +The left hand side is the pushforward of the function `⟨σ, τ⟩` along the vector field `X`: +the left hand side at `x` is `df(X x)`, where `f := ⟨σ, τ⟩`. -/ -/-! Compatible connections: a connection on `V` is compatible with the metric on `M` iff -`∇ X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩` holds for all sufficiently nice vector fields `X` on `M` and -sections `Y`, `Z` of `V`. In our definition, we ask for this identity to at each `x : M`, whenever -`X`, `Y` and `Z` are differentiable at `x`. -The left hand side is the pushforward of the function `⟨Y, Z⟩` along the vector field `X`: -the left hand side at `x` is `df(X x)`, where `f := ⟨Y, Z⟩`. -/ +variable {σ σ' σ'' τ τ' τ'' : Π x : M, V x} -variable {X X' X'' Y Y' Y'' Z Z' : Π x : M, V x} +/-- The scalar product of two sections. -/ +noncomputable abbrev product (σ τ : Π x : M, V x) : M → ℝ := + fun x ↦ inner ℝ (σ x) (τ x) -/-- The scalar product of two vector fields -/ -noncomputable abbrev product (X Y : Π x : M, V x) : M → ℝ := - fun x ↦ inner ℝ (X x) (Y x) +-- `product` is C^k if σ and τ are: this is shown in `Riemannian.lean` --- `product` is C^k if X and Y are: this is shown in `Riemannian.lean` +local notation "⟪" σ ", " τ "⟫" => product σ τ -local notation "⟪" X ", " Y "⟫" => product X Y - --- Basic API for the product of two vector fields. +-- Basic API for the product of two sections. section product omit [TopologicalSpace M] [IsManifold I 2 M] -lemma product_apply (x) : ⟪X, Y⟫ x = inner ℝ (X x) (Y x) := rfl +lemma product_apply (x) : ⟪σ, τ⟫ x = inner ℝ (σ x) (τ x) := rfl -variable (X X' Y) +variable (σ σ' τ) -lemma product_swap : ⟪Y, X⟫ = ⟪X, Y⟫ := by +lemma product_swap : ⟪τ, σ⟫ = ⟪σ, τ⟫ := by ext x apply real_inner_comm @[simp] -lemma product_zero_left : ⟪0, X⟫ = 0 := by +lemma product_zero_left : ⟪0, σ⟫ = 0 := by ext x simp [product] @[simp] -lemma product_zero_right : ⟪X, 0⟫ = 0 := by rw [product_swap, product_zero_left] +lemma product_zero_right : ⟪σ, 0⟫ = 0 := by rw [product_swap, product_zero_left] -lemma product_add_left : ⟪X + X', Y⟫ = ⟪X, Y⟫ + ⟪X', Y⟫ := by +lemma product_add_left : ⟪σ + σ', τ⟫ = ⟪σ, τ⟫ + ⟪σ', τ⟫ := by ext x simp [product, InnerProductSpace.add_left] @[simp] -lemma product_add_left_apply (x) : ⟪X + X', Y⟫ x = ⟪X, Y⟫ x + ⟪X', Y⟫ x := by +lemma product_add_left_apply (x) : ⟪σ + σ', τ⟫ x = ⟪σ, τ⟫ x + ⟪σ', τ⟫ x := by simp [product, InnerProductSpace.add_left] -lemma product_add_right : ⟪X, Y + Y'⟫ = ⟪X, Y⟫ + ⟪X, Y'⟫ := by - rw [product_swap, product_swap Y, product_swap Y', product_add_left] +lemma product_add_right : ⟪σ, τ + τ'⟫ = ⟪σ, τ⟫ + ⟪σ, τ'⟫ := by + rw [product_swap, product_swap τ, product_swap τ', product_add_left] @[simp] -lemma product_add_right_apply (x) : ⟪X, Y + Y'⟫ x = ⟪X, Y⟫ x + ⟪X, Y'⟫ x := by - rw [product_swap, product_swap Y, product_swap Y', product_add_left_apply] +lemma product_add_right_apply (x) : ⟪σ, τ + τ'⟫ x = ⟪σ, τ⟫ x + ⟪σ, τ'⟫ x := by + rw [product_swap, product_swap τ, product_swap τ', product_add_left_apply] -@[simp] lemma product_neg_left : ⟪-X, Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] +@[simp] lemma product_neg_left : ⟪-σ, τ⟫ = -⟪σ, τ⟫ := by ext x; simp [product] -@[simp] lemma product_neg_right : ⟪X, -Y⟫ = -⟪X, Y⟫ := by ext x; simp [product] +@[simp] lemma product_neg_right : ⟪σ, -τ⟫ = -⟪σ, τ⟫ := by ext x; simp [product] -lemma product_sub_left : ⟪X - X', Y⟫ = ⟪X, Y⟫ - ⟪X', Y⟫ := by +lemma product_sub_left : ⟪σ - σ', τ⟫ = ⟪σ, τ⟫ - ⟪σ', τ⟫ := by ext x simp [product, inner_sub_left] -lemma product_sub_right : ⟪X, Y - Y'⟫ = ⟪X, Y⟫ - ⟪X, Y'⟫ := by +lemma product_sub_right : ⟪σ, τ - τ'⟫ = ⟪σ, τ⟫ - ⟪σ, τ'⟫ := by ext x simp [product, inner_sub_right] -lemma product_smul_left (f : M → ℝ) : product (f • X) Y = f • product X Y := by +lemma product_smul_left (f : M → ℝ) : product (f • σ) τ = f • product σ τ := by ext x simp [product, real_inner_smul_left] @[simp] -lemma product_smul_const_left (a : ℝ) : product (a • X) Y = a • product X Y := by +lemma product_smul_const_left (a : ℝ) : product (a • σ) τ = a • product σ τ := by ext x simp [product, real_inner_smul_left] -lemma product_smul_right (f : M → ℝ) : product X (f • Y) = f • product X Y := by +lemma product_smul_right (f : M → ℝ) : product σ (f • τ) = f • product σ τ := by ext x simp [product, real_inner_smul_right] @[simp] -lemma product_smul_const_right (a : ℝ) : product X (a • Y) = a • product X Y := by +lemma product_smul_const_right (a : ℝ) : product σ (a • τ) = a • product σ τ := by ext x simp [product, real_inner_smul_right] @@ -149,23 +147,23 @@ end product -- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) -- only hold point-wise. They abstract the expanding and unexpanding of `product`. omit [TopologicalSpace M] [IsManifold I 2 M] in -lemma product_congr_left {x} (h : X x = X' x) : product X Y x = product X' Y x := by +lemma product_congr_left {x} (h : σ x = σ' x) : product σ τ x = product σ' τ x := by rw [product_apply, h, ← product_apply] omit [TopologicalSpace M] [IsManifold I 2 M] in -lemma product_congr_left₂ {x} (h : X x = X' x + X'' x) : - product X Y x = product X' Y x + product X'' Y x := by +lemma product_congr_left₂ {x} (h : σ x = σ' x + σ'' x) : + product σ τ x = product σ' τ x + product σ'' τ x := by rw [product_apply, h, inner_add_left, ← product_apply] omit [TopologicalSpace M] [IsManifold I 2 M] in -lemma product_congr_right {x} (h : Y x = Y' x) : product X Y x = product X Y' x := by +lemma product_congr_right {x} (h : τ x = τ' x) : product σ τ x = product σ τ' x := by rw [product_apply, h, ← product_apply] omit [TopologicalSpace M] [IsManifold I 2 M] in -lemma product_congr_right₂ {x} (h : Y x = Y' x + Y'' x) : - product X Y x = product X Y' x + product X Y'' x := by +lemma product_congr_right₂ {x} (h : τ x = τ' x + τ'' x) : + product σ τ x = product σ τ' x + product σ τ'' x := by rw [product_apply, h, inner_add_right, ← product_apply] -/- TODO: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` +/- TODO: writing `hσ.inner_bundle hτ` or writing `by apply MDifferentiable.inner_bundle hσ hτ` yields an error synthesized type class instance is not definitionally equal to expression inferred by typing rules, synthesized @@ -175,13 +173,13 @@ inferred Diagnose and fix this, and then replace the below by `MDifferentiable(At).inner_bundle! -/ variable {F} [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {I} in -lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff ⟪Y, Z⟫ := - MDifferentiable.inner_bundle hY hZ +lemma MDifferentiable.inner_bundle' (hσ : MDiff (T% σ)) (hτ : MDiff (T% τ)) : MDiff ⟪σ, τ⟫ := + MDifferentiable.inner_bundle hσ hτ variable {F} [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {I} in -lemma MDifferentiableAt.inner_bundle' {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - MDiffAt ⟪Y, Z⟫ x := - MDifferentiableAt.inner_bundle hY hZ +lemma MDifferentiableAt.inner_bundle' {x} (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + MDiffAt ⟪σ, τ⟫ x := + MDifferentiableAt.inner_bundle hσ hτ namespace CovariantDerivative @@ -189,23 +187,23 @@ namespace CovariantDerivative -- TODO: include in cheat sheet! variable (cov : CovariantDerivative I F V) -/-- Local notation for a connection. Caution: `∇ Y, X` corresponds to `∇ₓ Y` in textbooks -/ -local notation "∇" Y "," X => fun (x:M) ↦ cov Y x (X x) +/-- Local notation for a connection. Caution: `∇ σ, X` corresponds to `∇ₓ σ` in textbooks -/ +local notation "∇" σ "," X => fun (x:M) ↦ cov σ x (X x) variable {F} /-- The function defining the compatibility tensor for `∇` w.r.t. `g`: prefer using `compatibilityTensor` instead -/ -noncomputable def compatibilityTensorAux (Y Z : Π x : M, V x) : +noncomputable def compatibilityTensorAux (σ τ : Π x : M, V x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ - letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪Y, Z⟫ x - b - ((innerSL ℝ (Z x)) ∘L (cov Y x)) - ((innerSL ℝ (Y x)) ∘L (cov Z x)) + letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪σ, τ⟫ x + b - ((innerSL ℝ (τ x)) ∘L (cov σ x)) - ((innerSL ℝ (σ x)) ∘L (cov τ x)) -lemma compatibilityTensorAux_apply (Y Z : Π x : M, V x) +lemma compatibilityTensorAux_apply (σ τ : Π x : M, V x) {x : M} (X₀ : TangentSpace I x) : - compatibilityTensorAux I cov Y Z x X₀ = - NormedSpace.fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x X₀) - - innerSL ℝ (Z x) (cov Y x X₀) - innerSL ℝ (Y x) (cov Z x X₀) := by + compatibilityTensorAux I cov σ τ x X₀ = + NormedSpace.fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x X₀) + - innerSL ℝ (τ x) (cov σ x X₀) - innerSL ℝ (σ x) (cov τ x X₀) := by unfold compatibilityTensorAux simp congr 1 @@ -316,7 +314,7 @@ theorem compatibilityTensorAux_tensorial₂ (σ : Π x, V x) (hσ : MDiffAt (T% add hτ hτ' := aux4 cov _ _ _ hσ hτ hτ' variable {I} [ContMDiffVectorBundle 1 F V I] in -/-- The tensor `(X, Y, Z) ↦ ∇ₓ g(Y, Z) - g(∇ₓ Y, Z) - g(Y, ∇ₓ Z)` defining when a connection +/-- The tensor `(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)` defining when a connection `∇` on a Riemannian bundle `(M, V)` is compatible with the metric `g`. -/ @[no_expose] noncomputable def compatibilityTensor [FiniteDimensional ℝ F] (x : M) : V x →L[ℝ] V x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := @@ -327,11 +325,11 @@ variable {X : Π x : M, TangentSpace I x} variable {I} [ContMDiffVectorBundle 1 F V I] in theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) - (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - compatibilityTensor cov x (Y x) (Z x) (X x) = - fromTangentSpace _ (mfderiv% ⟪Y, Z⟫ x (X x)) - ⟪∇ Y, X, Z⟫ x - ⟪Y, ∇ Z, X⟫ x := by + (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + compatibilityTensor cov x (σ x) (τ x) (X x) = + fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) - ⟪∇ σ, X, τ⟫ x - ⟪σ, ∇ τ, X⟫ x := by unfold compatibilityTensor - rw [TensorialAt.mkHom₂_apply _ _ hY hZ] + rw [TensorialAt.mkHom₂_apply _ _ hσ hτ] --rw [compatibilityTensorAux_apply] simp only [compatibilityTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] @@ -346,19 +344,18 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) open FiberBundle in variable {I} [ContMDiffVectorBundle 1 F V I] in theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ F] (X₀ : TangentSpace I x) - (Y₀ Z₀ : V x) : - compatibilityTensor cov x Y₀ Z₀ X₀ = - fromTangentSpace _ (mfderiv% ⟪(extend F Y₀), (extend F Z₀)⟫ x X₀) - - ⟪∇ extend F Y₀, (extend E X₀), extend F Z₀⟫ x - - ⟪extend F Y₀, ∇ extend F Z₀, (extend E X₀)⟫ x := by + (σ₀ τ₀ : V x) : + compatibilityTensor cov x σ₀ τ₀ X₀ = + fromTangentSpace _ (mfderiv% ⟪(extend F σ₀), (extend F τ₀)⟫ x X₀) + - ⟪∇ extend F σ₀, (extend E X₀), extend F τ₀⟫ x + - ⟪extend F σ₀, ∇ extend F τ₀, (extend E X₀)⟫ x := by simpa [extend_apply_self] using compatibilityTensor_apply cov x - (X := extend E X₀) (mdifferentiableAt_extend I F Y₀) (mdifferentiableAt_extend I F Z₀) + (X := extend E X₀) (mdifferentiableAt_extend I F σ₀) (mdifferentiableAt_extend I F τ₀) variable {I} [ContMDiffVectorBundle 1 F V I] in -/-- Predicate saying for a connection `∇` on a Riemannian bundle `(V, g)` to be compatible with -the ambient metric, i.e. for all differentiable vector fields `X` on `M` and sections `Y` and `Z` -of `V`, we have -`X ⟨Y, Z⟩ = ⟨∇ X Y, Z⟩ + ⟨Y, ∇ X Z⟩`. -/ +/-- Predicate saying that a connection `∇` on a Riemannian bundle `(V, g)` is compatible with the +ambient metric, i.e. for all differentiable vector fields `X` on `M` and sections `σ` and `τ` of +`V`, we have `X ⟨σ, τ⟩ = ⟨∇ X σ, τ⟩ + ⟨σ, ∇ X τ⟩`. -/ def IsCompatible [FiniteDimensional ℝ F] : Prop := compatibilityTensor cov = 0 -- Auxiliary computation for `IsCompatible_apply`. @@ -369,27 +366,27 @@ variable {I} [ContMDiffVectorBundle 1 F V I] in -- TODO: give a better name; maybe inline? -- variable {I} in lemma isCompatible_apply [FiniteDimensional ℝ F] (hcov : cov.IsCompatible) - (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by + (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : + mfderiv% ⟪σ, τ⟫ x (X x) = ⟪∇ σ, X, τ⟫ x + ⟪σ, ∇ τ, X⟫ x := by rw [IsCompatible] at hcov - have : compatibilityTensor cov x (Y x) (Z x) (X x) = 0 := by simp [hcov] - rw [compatibilityTensor_apply cov x hY hZ] at this - change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪Y, Z⟫ x) (X x))) = _ + have : compatibilityTensor cov x (σ x) (τ x) (X x) = 0 := by simp [hcov] + rw [compatibilityTensor_apply cov x hσ hτ] at this + change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) (X x))) = _ exact isCompatible_apply_aux this open FiberBundle in variable {I} [ContMDiffVectorBundle 1 F V I] in lemma isCompatible_iff [FiniteDimensional ℝ F] : - cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {Y Z : (x : M) → V x} - (_hX : MDiffAt (T% X) x) (_hY : MDiffAt (T% Y) x) (_hZ : MDiffAt (T% Z) x), - mfderiv% ⟪Y, Z⟫ x (X x) = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x := by - refine ⟨fun hcov x X Y Z hX hY hZ ↦ cov.isCompatible_apply hcov hY hZ, fun h ↦ ?_⟩ + cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {σ τ : (x : M) → V x} + (_hX : MDiffAt (T% X) x) (_hσ : MDiffAt (T% σ) x) (_hτ : MDiffAt (T% τ) x), + mfderiv% ⟪σ, τ⟫ x (X x) = ⟪∇ σ, X, τ⟫ x + ⟪σ, ∇ τ, X⟫ x := by + refine ⟨fun hcov x X σ τ hX hσ hτ ↦ cov.isCompatible_apply hcov hσ hτ, fun h ↦ ?_⟩ unfold IsCompatible - ext x Y₀ Z₀ X₀ + ext x σ₀ τ₀ X₀ rw [compatibilityTensor_apply_eq_extend, sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] - have h' := h (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I F Y₀) - (mdifferentiableAt_extend I F Z₀) + have h' := h (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I F σ₀) + (mdifferentiableAt_extend I F τ₀) simpa [fromTangentSpace, extend_apply_self] using h' end CovariantDerivative From 8a8f4a7f41d85160558fb8924dc5dec8b14d61ab Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 11:20:23 +0000 Subject: [PATCH 562/601] fixes after cherry-pick --- .../CovariantDerivative/LeviCivita.lean | 20 +++++++++---------- .../CovariantDerivative/Metric.lean | 15 +++++++------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e5679e90173193..52d2379eb4aabb 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -78,7 +78,7 @@ version depending on a choice of Riemannian metric on `M`. -/ def IsLeviCivitaConnection [FiniteDimensional ℝ E] : Prop := cov.IsCompatible ∧ cov.torsion = 0 -local notation "⟪" X ", " Y "⟫" => product I X Y +local notation "⟪" X ", " Y "⟫" => product X Y variable (X Y Z) in /-- The first term in the definition of the candidate Levi-Civita connection: @@ -100,7 +100,7 @@ lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by ext x simp only [rhs_aux] congr 2 - exact product_swap I Z Y + exact product_swap Z Y omit [IsManifold I 2 M] in variable (X X' Y Z) in @@ -242,8 +242,8 @@ lemma leviCivitaRhs'_addX_apply [CompleteSpace E] -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. -- Fortunately, the `product_congr_right₂` lemma abstracts this very well. - rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := Y) hX hX'), - product_congr_right₂ I (VectorField.mlieBracket_add_left (W := Z) hX hX'), + rw [product_congr_right₂ (VectorField.mlieBracket_add_right (V := Y) hX hX'), + product_congr_right₂ (VectorField.mlieBracket_add_left (W := Z) hX hX'), product_add_left_apply, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel @@ -334,8 +334,8 @@ lemma leviCivitaRhs'_addY_apply [CompleteSpace E] rw [rhs_aux_addX, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption -- We have to rewrite back and forth: the Lie bracket is only additive at x, -- as we are only asking for differentiability at x. - rw [product_congr_right₂ I (mlieBracket_add_left (W := X) hY hY')] - rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := Z) hY hY')] + rw [product_congr_right₂ (mlieBracket_add_left (W := X) hY hY')] + rw [product_congr_right₂ (VectorField.mlieBracket_add_right (V := Z) hY hY')] simp only [Pi.add_apply] abel @@ -420,7 +420,7 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} rw [real_inner_smul_right] rfl · rw [inner_smul_right_eq_smul] - rw [h1, h2, product_swap I Y Z] + rw [h1, h2, product_swap Y Z] set A := rhs_aux I X Y Z x set B := rhs_aux I Y Z X x set C := rhs_aux I Z X Y x @@ -457,8 +457,8 @@ lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] leviCivitaRhs' I X Y (Z + Z') x = leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y Z' x := by simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] - rw [product_congr_right₂ I (VectorField.mlieBracket_add_right (V := X) hZ hZ'), - product_congr_right₂ I (VectorField.mlieBracket_add_left (W := Y) hZ hZ'), + rw [product_congr_right₂ (VectorField.mlieBracket_add_right (V := X) hZ hZ'), + product_congr_right₂ (VectorField.mlieBracket_add_left (W := Y) hZ hZ'), rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption abel @@ -498,7 +498,7 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} rw [product_apply, VectorField.mlieBracket_smul_left hf hZ, inner_add_right, inner_smul_right, inner_smul_right] congr - rw [h1, h2, product_smul_left, product_swap I X Z] + rw [h1, h2, product_smul_left, product_swap X Z] erw [product_smul_right] simp -- set A := rhs_aux I X Y Z x diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 84edd402ac5a33..000603cf4ed6f6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -341,16 +341,15 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) erw [ContinuousLinearMap.comp_apply] simp [product, real_inner_comm, fromTangentSpace] -open FiberBundle in variable {I} [ContMDiffVectorBundle 1 F V I] in theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ F] (X₀ : TangentSpace I x) (σ₀ τ₀ : V x) : compatibilityTensor cov x σ₀ τ₀ X₀ = - fromTangentSpace _ (mfderiv% ⟪(extend F σ₀), (extend F τ₀)⟫ x X₀) - - ⟪∇ extend F σ₀, (extend E X₀), extend F τ₀⟫ x - - ⟪extend F σ₀, ∇ extend F τ₀, (extend E X₀)⟫ x := by - simpa [extend_apply_self] using compatibilityTensor_apply cov x - (X := extend E X₀) (mdifferentiableAt_extend I F σ₀) (mdifferentiableAt_extend I F τ₀) + fromTangentSpace _ (mfderiv% ⟪(FiberBundle.extend F σ₀), (FiberBundle.extend F τ₀)⟫ x X₀) + - ⟪∇ FiberBundle.extend F σ₀, (FiberBundle.extend E X₀), FiberBundle.extend F τ₀⟫ x + - ⟪FiberBundle.extend F σ₀, ∇ FiberBundle.extend F τ₀, (FiberBundle.extend E X₀)⟫ x := by + simpa [extend_apply_self] using compatibilityTensor_apply cov x (X := FiberBundle.extend E X₀) + (FiberBundle.mdifferentiableAt_extend I F σ₀) (FiberBundle.mdifferentiableAt_extend I F τ₀) variable {I} [ContMDiffVectorBundle 1 F V I] in /-- Predicate saying that a connection `∇` on a Riemannian bundle `(V, g)` is compatible with the @@ -385,8 +384,8 @@ lemma isCompatible_iff [FiniteDimensional ℝ F] : ext x σ₀ τ₀ X₀ rw [compatibilityTensor_apply_eq_extend, sub_sub, sub_eq_iff_eq_add'] simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] - have h' := h (mdifferentiableAt_extend I E X₀) (mdifferentiableAt_extend I F σ₀) - (mdifferentiableAt_extend I F τ₀) + have h' := h (FiberBundle.mdifferentiableAt_extend I E X₀) + (FiberBundle.mdifferentiableAt_extend I F σ₀) (FiberBundle.mdifferentiableAt_extend I F τ₀) simpa [fromTangentSpace, extend_apply_self] using h' end CovariantDerivative From 7a6d61bf89b66a3a82b8d5be16f2e974d8ab4eeb Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 15:18:20 +0000 Subject: [PATCH 563/601] move mfderiv_smul --- Mathlib.lean | 1 - .../Manifold/MFDeriv/NormedSpace.lean | 139 +++++++++++++++++- Mathlib/Geometry/Manifold/MfDerivSMul.lean | 60 -------- .../CovariantDerivative/LeviCivita.lean | 2 +- .../CovariantDerivative/Metric.lean | 51 ++----- .../CovariantDerivative/Trivial.lean | 5 +- 6 files changed, 149 insertions(+), 109 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/MfDerivSMul.lean diff --git a/Mathlib.lean b/Mathlib.lean index 6f5e87778bef20..fc474e354ac402 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4415,7 +4415,6 @@ public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions public import Mathlib.Geometry.Manifold.MFDeriv.Tangent public import Mathlib.Geometry.Manifold.MFDeriv.UniqueDifferential public import Mathlib.Geometry.Manifold.Metrizable -public import Mathlib.Geometry.Manifold.MfDerivSMul public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.PartitionOfUnity public import Mathlib.Geometry.Manifold.PoincareConjecture diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 05eeb1a323317f..9f79892fdd77ff 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -283,22 +283,151 @@ theorem MDifferentiable.clm_prodMap {g : M → F₁ →L[𝕜] F₃} {f : M → /-! ### Differentiability of scalar multiplication -/ -variable {V : Type*} [NormedAddCommGroup V] [NormedSpace 𝕜 V] +section smul + +open NormedSpace ContinuousLinearMap -theorem MDifferentiableWithinAt.smul {f : M → 𝕜} {g : M → V} +variable {V : Type*} [NormedAddCommGroup V] [NormedSpace 𝕜 V] +variable {f : M → 𝕜} {g : M → V} + +/-- Given maps `f`, `g` from a manifold into a field `𝕜` and `𝕜`-vector space `V`, respectively, if +at some point `x`, `f` has differential `f' : TangentSpace I x →L[𝕜] 𝕜` and `g` has differential +`g' : TangentSpace I x →L[𝕜] V` (both phrased using the predicate `HasMFDerivAt`), it follows that +their scalar multiplication `f • g` has differential `f x • g' + toSpanSingleton 𝕜 (g x) ∘L f'`. + +In fact, the statement above is not literally true, because, for example, the differential of `g` +really takes values in the tangent space to `V` at `g x`, rather than in `V` itself. Of course, this +tangent space can be canonically identified with `V`. + +This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, which provides this +canonical identification. (It would also be possible to phrase the formula without this equiv, +instead using casting and definitional abuse.) -/ +lemma HasMFDerivAt.smul + {f' : TangentSpace I x →L[𝕜] 𝕜} + (hs : HasMFDerivAt I 𝓘(𝕜, 𝕜) f x ((fromTangentSpace _).symm.toContinuousLinearMap ∘L f')) + {g' : TangentSpace I x →L[𝕜] V} + (hg : HasMFDerivAt I 𝓘(𝕜, V) g x ((fromTangentSpace _).symm.toContinuousLinearMap ∘L g')) : + -- canonically identify `g'` with a linear map into the tangent space at `(f • g) x` + letI g'_ : TangentSpace I x →L[𝕜] TangentSpace 𝓘(𝕜, V) ((f • g) x) := + (fromTangentSpace _).symm.toContinuousLinearMap ∘L g' + -- canonically identify `g x` with a linear map into a tangent space at `(f • g) x` + letI gx : 𝕜 →L[𝕜] TangentSpace 𝓘(𝕜, V) ((f • g) x) := + toSpanSingleton 𝕜 ((fromTangentSpace _).symm (g x)) + -- now the main statement typechecks + HasMFDerivAt I 𝓘(𝕜, V) (f • g) x (f x • g'_ + gx ∘L f') := by + constructor + · exact hs.1.smul hg.1 + · simpa using hs.2.smul hg.2 + +theorem MDifferentiableWithinAt.smul (hf : MDifferentiableWithinAt I 𝓘(𝕜) f s x) (hg : MDifferentiableWithinAt I 𝓘(𝕜, V) g s x) : MDifferentiableWithinAt I 𝓘(𝕜, V) (fun p => f p • g p) s x := ((contMDiff_smul.of_le le_top).mdifferentiable one_ne_zero _).comp_mdifferentiableWithinAt x (hf.prodMk hg) -theorem MDifferentiableAt.smul {f : M → 𝕜} {g : M → V} (hf : MDifferentiableAt I 𝓘(𝕜) f x) +theorem MDifferentiableAt.smul (hf : MDifferentiableAt I 𝓘(𝕜) f x) (hg : MDifferentiableAt I 𝓘(𝕜, V) g x) : MDifferentiableAt I 𝓘(𝕜, V) (fun p => f p • g p) x := ((contMDiff_smul.of_le le_top).mdifferentiable one_ne_zero _).comp x (hf.prodMk hg) -theorem MDifferentiableOn.smul {f : M → 𝕜} {g : M → V} (hf : MDifferentiableOn I 𝓘(𝕜) f s) +theorem MDifferentiableOn.smul (hf : MDifferentiableOn I 𝓘(𝕜) f s) (hg : MDifferentiableOn I 𝓘(𝕜, V) g s) : MDifferentiableOn I 𝓘(𝕜, V) (fun p => f p • g p) s := fun x hx => (hf x hx).smul (hg x hx) -theorem MDifferentiable.smul {f : M → 𝕜} {g : M → V} (hf : MDifferentiable I 𝓘(𝕜) f) +theorem MDifferentiable.smul (hf : MDifferentiable I 𝓘(𝕜) f) (hg : MDifferentiable I 𝓘(𝕜, V) g) : MDifferentiable I 𝓘(𝕜, V) fun p => f p • g p := fun x => (hf x).smul (hg x) + +/-- Given maps `f`, `g` from a manifold into a field `𝕜` and `𝕜`-vector space `V`, respectively, the +formula for the `mfderiv` (differential) of their scalar multiplication `f • g`. + +Mathematically speaking the formula is `d(f • g) = f • dg + df ⊗ g`, i.e. +`mfderiv% (f • g) x = f x • mfderiv% g x + toSpanSingleton 𝕜 (g x) ∘L mfderiv% f x`, +but this doesn't typecheck because `mfderiv% (f • g) x` and `mfderiv% g x` take values in different +tangent spaces -- respectively the tangent spaces to `V` at `(f • g) x` and `g x`. Of course, both +these tangent spaces can be canonically identified with `V`. + +This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, which provides this +canonical identification. (It would also be possible to phrase the formula without this equiv, +instead using casting and definitional abuse.) + +It is good practice to use the equiv `NormedSpace.fromTangentSpace` throughout a computation. If +this is done, typically `mfderiv% (f • g) x` will only turn up paired with this equiv (i.e., in an +expression `(fromTangentSpace _) ∘L mfderiv% (f • g) x`), and the more convenient lemma +`fromTangentSpace_mfderiv_smul` (see below) can be used instead. -/ +lemma mfderiv_smul (hf : MDiffAt f x) (hg : MDiffAt g x) : + mfderiv% (f • g) x + = f x • (fromTangentSpace _).symm.toContinuousLinearMap ∘L + ((fromTangentSpace (g x)).toContinuousLinearMap ∘L mfderiv% g x) + + toSpanSingleton 𝕜 ((fromTangentSpace _).symm (g x)) ∘L + ((fromTangentSpace (f x)).toContinuousLinearMap ∘L mfderiv% f x) := + (hf.hasMFDerivAt.smul hg.hasMFDerivAt).mfderiv + +/-- Given maps `f`, `g` from a manifold into a field `𝕜` and `𝕜`-vector space `V`, respectively, the +formula for the `mfderiv` (differential) of their scalar multiplication `f • g`. + +Mathematically speaking the formula is `d(f • g) = f • dg + df ⊗ g`, i.e. +`mfderiv% (f • g) x = f x • mfderiv% g x + toSpanSingleton 𝕜 (g x) ∘L mfderiv% f x`, +but this doesn't typecheck because `mfderiv% (f • g) x` and `mfderiv% g x` take values in different +tangent spaces -- respectively the tangent spaces to `V` at `(f • g) x` and `g x`. Of course, both +these tangent spaces can be canonically identified with `V`. + +This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, which provides this +canonical identification. (It would also be possible to phrase the formula without this equiv, +instead using casting and definitional abuse.) -/ +lemma fromTangentSpace_mfderiv_smul (hf : MDiffAt f x) (hg : MDiffAt g x) : + (fromTangentSpace ((f • g) x)).toContinuousLinearMap ∘L mfderiv% (f • g) x + = f x • (fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% g x + + toSpanSingleton 𝕜 (g x) ∘L (fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% f x := by + rw [mfderiv_smul hf hg] + rfl + +/-- Given maps `f`, `g` from a manifold into a field `𝕜` and `𝕜`-vector space `V`, respectively, the +formula for the `mfderiv` (differential) of their scalar multiplication `f • g`. + +Mathematically speaking the formula is `d(f • g) = f • dg + df ⊗ g`, but to get it to typecheck +we need a phrasing involving the canonical identification `NormedSpace.fromTangentSpace` between +the vector space `V` and the tangent space to this vector space at any point. This is because two +different tangent spaces (at `(f • g) x` and `g x`) appear in the equation. + +This is a defeq variant of the main lemma `fromTangentSpace_mfderiv_smul`, in which we work in the +tangent space at `f x • g x` (the simp-normal form) rather than at `(f • g) x`. -/ +lemma fromTangentSpace_mfderiv_smul' (hf : MDiffAt f x) (hg : MDiffAt g x) : + (fromTangentSpace (f x • g x)).toContinuousLinearMap ∘L mfderiv% (f • g) x + = f x • (fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% g x + + toSpanSingleton 𝕜 (g x) ∘L (fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% f x := + fromTangentSpace_mfderiv_smul hf hg + +/-- Given maps `f`, `g` from a manifold into a field `𝕜` and `𝕜`-vector space `V`, respectively, the +formula for the `mfderiv` (differential) of their scalar multiplication `f • g` in the direction of +the tangent vector `v`. + +Mathematically speaking the formula is `d(f • g)(v) = f • dg(v) + df(v) • g`, but to get it to +typecheck we need a phrasing involving the canonical identification `NormedSpace.fromTangentSpace` +between the vector space `V` and the tangent space to this vector space at any point. This is +because two different tangent spaces (at `(f • g) x` and `g x`) appear in the equation. -/ +lemma fromTangentSpace_mfderiv_smul_apply (hf : MDiffAt f x) (hg : MDiffAt g x) + (v : TangentSpace I x) : + fromTangentSpace _ (mfderiv% (f • g) x v) + = f x • fromTangentSpace _ (mfderiv% g x v) + + fromTangentSpace _ (mfderiv% f x v) • g x := by + simpa using congr($(fromTangentSpace_mfderiv_smul hf hg) v) + +/-- Given maps `f`, `g` from a manifold into a field `𝕜` and `𝕜`-vector space `V`, respectively, the +formula for the `mfderiv` (differential) of their scalar multiplication `f • g` in the direction of +the tangent vector `v`. + +Mathematically speaking the formula is `d(f • g)(v) = f • dg(v) + df(v) • g`, but to get it to +typecheck we need a phrasing involving the canonical identification `NormedSpace.fromTangentSpace` +between the vector space `V` and the tangent space to this vector space at any point. This is +because two different tangent spaces (at `(f • g) x` and `g x`) appear in the equation. + +This is a defeq variant of the main lemma `fromTangentSpace_mfderiv_smul_apply`, in which we work in +the tangent space at `f x • g x` (the simp-normal form) rather than at `(f • g) x`. -/ +lemma fromTangentSpace_mfderiv_smul_apply' (hf : MDiffAt f x) (hg : MDiffAt g x) + (v : TangentSpace I x) : + fromTangentSpace (f x • g x) (mfderiv% (f • g) x v) + = f x • fromTangentSpace _ (mfderiv% g x v) + + fromTangentSpace _ (mfderiv% f x v) • g x := + fromTangentSpace_mfderiv_smul_apply hf hg v + +end smul diff --git a/Mathlib/Geometry/Manifold/MfDerivSMul.lean b/Mathlib/Geometry/Manifold/MfDerivSMul.lean deleted file mode 100644 index 0e0da7381379b8..00000000000000 --- a/Mathlib/Geometry/Manifold/MfDerivSMul.lean +++ /dev/null @@ -1,60 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ -module - -public import Mathlib.Geometry.Manifold.MFDeriv.Atlas -public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace -public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions -import Mathlib.Geometry.Manifold.Notation - -/-! # `mfderiv` and scalar multiplication -/ - -open Set -open scoped Manifold ContDiff - -@[expose] public section mfderiv - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M] - {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] - {f : M → F} {s : M → 𝕜} {x : M} - -theorem MDifferentiableAt.differentiableAt_comp_chartAt_symm - (hs : MDiffAt f x) : - letI φ := chartAt H x; - DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := by - have hφ := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) - rw [← extChartAt_to_inv x (I := I)] at hs - have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hφ - exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this - -lemma mfderiv_smul (hf : MDiffAt f x) - (hs : MDiffAt s x) (v : TangentSpace I x) : - letI dsxv := NormedSpace.fromTangentSpace (s x) (mfderiv% s x v) - letI dfxv := NormedSpace.fromTangentSpace (f x) (mfderiv% f x v) - mfderiv% (s • f) x v = (s x) • dfxv + dsxv • f x := by - set φ := chartAt H x - -- TODO: inlining hs' or hf' breaks the proof, why? - have hs' : DifferentiableWithinAt 𝕜 (s ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := - hs.differentiableAt_comp_chartAt_symm - have aux := hs.differentiableAt_comp_chartAt_symm - have hf' : DifferentiableWithinAt 𝕜 (f ∘ φ.symm ∘ I.symm) (range I) (I (φ x)) := - hf.differentiableAt_comp_chartAt_symm - -- `have := hs.differentiableAt_comp_chartAt_symm` looks identical apart from unfolding φ - have hsf : MDiffAt (s • f) x := hs.smul hf - simp? [mfderiv, hsf, hs, hf] says - simp only [Pi.smul_apply', mfderiv, hsf, ↓reduceIte, writtenInExtChartAt, extChartAt, - OpenPartialHomeomorph.extend, modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, - PartialEquiv.coe_trans_symm, OpenPartialHomeomorph.coe_coe_symm, - ModelWithCorners.toPartialEquiv_coe_symm, PartialEquiv.coe_trans, - ModelWithCorners.toPartialEquiv_coe, OpenPartialHomeomorph.toFun_eq_coe, Function.comp_apply, - hf, hs] - -- Use the defeq that `chartAt (s x)` and `chartAt (f x)` are the identity. - erw [fderivWithin_smul I.uniqueDiffWithinAt_image hs' hf'] - simp [φ.left_inv (ChartedSpace.mem_chart_source x)] - rfl diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 52d2379eb4aabb..ddcd88710746ce 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -153,7 +153,7 @@ lemma rhs_aux_smulY_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) rhs_aux I X (f • Y) Z x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by - rw [rhs_aux, product_smul_left, mfderiv_smul (hY.inner_bundle' hZ) hf] + rw [rhs_aux, product_smul_left, mfderiv_smul hf (hY.inner_bundle' hZ)] rfl variable (X) in diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 000603cf4ed6f6..1ae1a62800bcc0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -7,7 +7,7 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian -public import Mathlib.Geometry.Manifold.MfDerivSMul +public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace /-! # Metric connections @@ -215,16 +215,11 @@ private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → V x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov (f • σ) τ x = f x • compatibilityTensorAux I cov σ τ x := by ext X₀ - rw [compatibilityTensorAux_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, - compatibilityTensorAux_apply] - rw [product_smul_left, cov.isCovariantDerivativeOn.leibniz hσ hf] - simp only [Pi.smul_apply', ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', - Pi.smul_apply, ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, comp_apply, - ContinuousLinearMap.toSpanSingleton_apply, coe_innerSL_apply, map_smul] - erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] -- identifying different tangent spaces - rw [inner_add_right, inner_smul_right, inner_smul_right, real_inner_comm (σ x) (τ x)] - simp only [← smul_eq_mul] - module + rw [compatibilityTensorAux_apply, product_smul_left, + fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_right, + inner_smul_right, real_inner_comm] + ring variable {I} in private lemma aux2 (σ σ' τ : (x : M) → V x) @@ -258,34 +253,12 @@ variable {I} in private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → V x} (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov σ (f • τ) x = f x • compatibilityTensorAux I cov σ τ x := by - unfold compatibilityTensorAux - rw [product_smul_right, cov.isCovariantDerivativeOn.leibniz hτ hf] - ext X - simp only [smul_eq_mul, Pi.smul_apply', map_smul, ContinuousLinearMap.smul_comp, - ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, - ContinuousLinearMap.coe_sub', Pi.sub_apply, ContinuousLinearMap.add_apply, - ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.smul_apply, - comp_apply, ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply] - erw [ContinuousLinearMap.sub_apply, ContinuousLinearMap.sub_apply, ContinuousLinearMap.comp_apply] - --set A := inner ℝ (σ x) ((cov τ x) X) - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.smul_apply] - conv => - enter [1, 1, 2, 2] - erw [ContinuousLinearMap.comp_apply] - dsimp - --set B := inner ℝ (τ x) ((cov σ x) X) - erw [mfderiv_smul (hσ.inner_bundle' hτ) hf] - --set C := (mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) X - --set D := (mfderiv I 𝓘(ℝ, ℝ) f x) X - simp only [smul_eq_mul, fromTangentSpace, ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, - LinearMap.coe_mk, AddHom.coe_mk, inner_smul_right] - -- would be nice to finish by a tactic now! - erw [mul_add, mul_add] - rw [Pi.mul_apply, mul_neg, mul_neg, - ← sub_eq_add_neg, ← sub_eq_add_neg, sub_add_eq_sub_sub] - match_scalars <;> all_goals simp + ext X₀ + rw [compatibilityTensorAux_apply, product_smul_right, + fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, + inner_smul_right, real_inner_comm] + ring variable {I} in private lemma aux4 (σ τ τ' : (x : M) → V x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index 0f7a471547fd45..f00e64ed46bd72 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -5,7 +5,6 @@ Authors: Patrick Massot, Michael Rothgang -/ module -public import Mathlib.Geometry.Manifold.MfDerivSMul public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim @@ -51,7 +50,7 @@ noncomputable def trivial [IsManifold I 1 M] : leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ ext1 X₀ - exact mfderiv_smul hσ hf X₀ + exact fromTangentSpace_mfderiv_smul_apply hf hσ X₀ lemma of_endomorphism (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F) : IsCovariantDerivativeOn F @@ -80,7 +79,7 @@ noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial leibniz {σ f x} hσ hf hx := by rw [mdifferentiableAt_section] at hσ ext1 X₀ - exact mfderiv_smul hσ hf X₀ } + exact fromTangentSpace_mfderiv_smul_apply hf hσ X₀ } end trivial_bundle From 9ca3c4e4725d49046b098e3cb2437fdd8154063d Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 16:42:40 +0000 Subject: [PATCH 564/601] clean up proofs a bit --- .../Manifold/MFDeriv/SpecificFunctions.lean | 14 +++++ .../CovariantDerivative/Metric.lean | 56 ++++++------------- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index b93c5a81d2bbaf..7ed84dacbe9868 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -796,6 +796,20 @@ theorem mfderiv_add (hf : MDiffAt f z) (hg : MDiffAt g z) : (by exact mfderiv% f z) + (by exact mfderiv% g z) := (hf.hasMFDerivAt.add hg.hasMFDerivAt).mfderiv +open NormedSpace in +theorem fromTangentSpace_mfderiv_add (hf : MDiffAt f z) (hg : MDiffAt g z) : + (fromTangentSpace _).toContinuousLinearMap ∘L (mfderiv% (f + g) z) + = (fromTangentSpace _).toContinuousLinearMap ∘L (mfderiv% f z) + + (fromTangentSpace _).toContinuousLinearMap ∘L (mfderiv% g z) := + (hf.hasMFDerivAt.add hg.hasMFDerivAt).mfderiv + +open NormedSpace in +theorem fromTangentSpace_mfderiv_add_apply (hf : MDiffAt f z) (hg : MDiffAt g z) + (v : TangentSpace I x) : + fromTangentSpace _ (mfderiv% (f + g) z v) + = fromTangentSpace _ (mfderiv% f z v) + fromTangentSpace _ (mfderiv% g z v) := + congr($(fromTangentSpace_mfderiv_add hf hg) v) + section sum variable {ι : Type} {t : Finset ι} {f : ι → M → E'} {f' : ι → TangentSpace I z →L[𝕜] E'} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 1ae1a62800bcc0..14e6f7c3dc35c5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -196,17 +196,15 @@ variable {F} prefer using `compatibilityTensor` instead -/ noncomputable def compatibilityTensorAux (σ τ : Π x : M, V x) : Π (x : M), TangentSpace I x →L[ℝ] ℝ := fun x ↦ - letI b : TangentSpace I x →L[ℝ] ℝ := mfderiv% ⟪σ, τ⟫ x - b - ((innerSL ℝ (τ x)) ∘L (cov σ x)) - ((innerSL ℝ (σ x)) ∘L (cov τ x)) + (NormedSpace.fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% ⟪σ, τ⟫ x + - ((innerSL ℝ (τ x)) ∘L (cov σ x)) - ((innerSL ℝ (σ x)) ∘L (cov τ x)) lemma compatibilityTensorAux_apply (σ τ : Π x : M, V x) {x : M} (X₀ : TangentSpace I x) : compatibilityTensorAux I cov σ τ x X₀ = NormedSpace.fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x X₀) - - innerSL ℝ (τ x) (cov σ x X₀) - innerSL ℝ (σ x) (cov τ x X₀) := by - unfold compatibilityTensorAux - simp - congr 1 + - innerSL ℝ (τ x) (cov σ x X₀) - innerSL ℝ (σ x) (cov τ x X₀) := + rfl variable [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {x : M} @@ -217,7 +215,7 @@ private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → V x} ext X₀ rw [compatibilityTensorAux_apply, product_smul_left, fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] - simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_right, + simp [compatibilityTensorAux, cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_right, inner_smul_right, real_inner_comm] ring @@ -226,28 +224,11 @@ private lemma aux2 (σ σ' τ : (x : M) → V x) (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : compatibilityTensorAux I cov (σ + σ') τ x = compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ' τ x := by - simp only [compatibilityTensorAux] - ext X - simp only [ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, - Pi.sub_apply, comp_apply, ContinuousLinearMap.add_apply] - rw [product_add_left, - mfderiv_add (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ), - cov.isCovariantDerivativeOn.add hσ hσ', - ContinuousLinearMap.comp_add] - erw [ContinuousLinearMap.coe_sub'] - rw [Pi.sub_apply] - erw [ContinuousLinearMap.add_apply, Pi.add_apply, inner_add_left] - -- set A := mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x - -- set A' := mfderiv I 𝓘(ℝ, ℝ) ⟪σ', τ⟫ x - -- set B := ((innerSL ℝ) (τ x)).comp (cov σ x) - -- set B' := ((innerSL ℝ) (τ x)).comp (cov σ' x) - -- set C := inner ℝ (σ x) ((cov τ x) X) - -- set C' := inner ℝ (σ' x) ((cov τ x) X) - erw [ContinuousLinearMap.add_apply, ContinuousLinearMap.sub_apply, - ContinuousLinearMap.sub_apply] - -- bug: abel fails, but module works - -- hypothesis: B, B', C, C' are in ℝ, while A and A' are in the tangent space at ℝ instead - module + ext X₀ + rw [compatibilityTensorAux_apply, product_add_left, + fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hσ hσ', inner_add_right] + abel variable {I} in private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → V x} @@ -256,7 +237,7 @@ private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → V x} ext X₀ rw [compatibilityTensorAux_apply, product_smul_right, fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] - simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, + simp [compatibilityTensorAux, cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, inner_smul_right, real_inner_comm] ring @@ -266,15 +247,10 @@ private lemma aux4 (σ τ τ' : (x : M) → V x) compatibilityTensorAux I cov σ (τ + τ') x = compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ τ' x := by ext X₀ - rw [compatibilityTensorAux_apply]; dsimp - rw [compatibilityTensorAux_apply, compatibilityTensorAux_apply]; dsimp - rw [product_add_right, mfderiv_add (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ'), - cov.isCovariantDerivativeOn.add hτ hτ'] - simp only [Pi.add_apply, ContinuousLinearMap.add_apply, inner_add_left, inner_add_right, - fromTangentSpace, -- this line is slightly fishy - ContinuousLinearEquiv.coe_mk, LinearEquiv.coe_mk, LinearMap.coe_mk, AddHom.coe_mk] - erw [ContinuousLinearMap.add_apply] - module + rw [compatibilityTensorAux_apply, product_add_right, + fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ')] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hτ hτ', inner_add_right] + abel theorem compatibilityTensorAux_tensorial₁ (τ : Π x, V x) (hτ : MDiffAt (T% τ) x) : TensorialAt I F (compatibilityTensorAux I cov · τ x) x where @@ -303,7 +279,7 @@ theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) - ⟪∇ σ, X, τ⟫ x - ⟪σ, ∇ τ, X⟫ x := by unfold compatibilityTensor rw [TensorialAt.mkHom₂_apply _ _ hσ hτ] - --rw [compatibilityTensorAux_apply] + --rw [compatibilityTensorAux] simp only [compatibilityTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', coe_innerSL_apply, Pi.sub_apply, comp_apply] conv => From 5a038e0cd12403a5ab50ab22df015cd6389eeff4 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 17:18:58 +0000 Subject: [PATCH 565/601] clean up proofs --- .../CovariantDerivative/LeviCivita.lean | 34 ++--- .../CovariantDerivative/Metric.lean | 133 ++++++------------ .../CovariantDerivative/Torsion.lean | 13 +- .../Manifold/VectorBundle/Tensoriality.lean | 74 +++++----- 4 files changed, 108 insertions(+), 146 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ddcd88710746ce..17bf0d8c58fccd 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -538,7 +538,7 @@ lemma aux (h : cov.IsLeviCivitaConnection) {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ X, Z⟫ x + ⟪Y, VectorField.mlieBracket I X Z⟫ x := by trans ⟪∇ Y, X, Z⟫ x + ⟪Y, ∇ Z, X⟫ x - · exact cov.isCompatible_apply h.1 hY hZ + · exact cov.isCompatible_iff.mp h.1 hX hY hZ · simp [← cov.torsion_eq_zero_iff.mp h.2 hX hZ, product, inner_sub_right] variable {cov} in @@ -702,14 +702,14 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : ext X₀ Y₀ simp only [TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, lcAux₀'] rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] - · exact leviCivitaRhs_addY_apply _ (mdifferentiableAt_extend ..) - hY hY' (mdifferentiableAt_extend ..) - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + · exact leviCivitaRhs_addY_apply _ (FiberBundle.mdifferentiableAt_extend ..) + hY hY' (FiberBundle.mdifferentiableAt_extend ..) + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. leibniz {Y f x} hY hf _ := by unfold lcAux dsimp @@ -731,14 +731,15 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : simp only [lcAux₀, lcAux₀', TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] - · convert leviCivitaRhs_smulY_apply I (Z := _root_.extend E Z₀) (x := x) - hf (mdifferentiableAt_extend I E X₀) hY (mdifferentiableAt_extend I E Z₀) + · convert leviCivitaRhs_smulY_apply I (Z := FiberBundle.extend E Z₀) (x := x) + hf (FiberBundle.mdifferentiableAt_extend I E X₀) hY + (FiberBundle.mdifferentiableAt_extend I E Z₀) · simp · simp [Φ, product] - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. - · exact mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. + · exact FiberBundle.mdifferentiableAt_extend .. exact MDifferentiableAt.smul_section hf hY end @@ -765,7 +766,7 @@ omit [IsManifold I 2 M] in lemma leviCivitaConnection_isCompatible_aux {x : M} {X Y Z : (x : M) → TangentSpace I x} : leviCivitaRhs I X Y Z x + leviCivitaRhs I X Z Y x = - ((mfderiv% fun x ↦ inner ℝ (Y x) (Z x)) x) (X x) := by + fromTangentSpace _ ((mfderiv% fun x ↦ inner ℝ (Y x) (Z x)) x (X x)) := by simp only [leviCivitaRhs, Pi.smul_apply, ← smul_add, leviCivitaRhs'] -- Normalise the expressions by swapping arguments for rhs_aux and mlieBracket, -- until the swappable arguments are in order X < Y < Z. @@ -778,6 +779,7 @@ lemma leviCivitaConnection_isCompatible_aux · simp abel · rw [← two_mul, ← mul_assoc, one_div, inv_mul_cancel₀ (by simp), one_mul] + rfl -- Why is everything so slow? lemma leviCivitaConnection_isCompatible [FiniteDimensional ℝ E] : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 14e6f7c3dc35c5..669003fa8d038d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -199,68 +199,48 @@ noncomputable def compatibilityTensorAux (σ τ : Π x : M, V x) : (NormedSpace.fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% ⟪σ, τ⟫ x - ((innerSL ℝ (τ x)) ∘L (cov σ x)) - ((innerSL ℝ (σ x)) ∘L (cov τ x)) +omit [IsManifold I 2 M] in lemma compatibilityTensorAux_apply (σ τ : Π x : M, V x) {x : M} (X₀ : TangentSpace I x) : compatibilityTensorAux I cov σ τ x X₀ = NormedSpace.fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x X₀) - - innerSL ℝ (τ x) (cov σ x X₀) - innerSL ℝ (σ x) (cov τ x X₀) := + - inner ℝ (cov σ x X₀) (τ x) - inner ℝ (σ x) (cov τ x X₀) := by + rw [real_inner_comm] rfl variable [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {x : M} -variable {I} in -private lemma aux1 {f : M → ℝ} {σ τ : (x : M) → V x} - (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - compatibilityTensorAux I cov (f • σ) τ x = f x • compatibilityTensorAux I cov σ τ x := by - ext X₀ - rw [compatibilityTensorAux_apply, product_smul_left, - fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] - simp [compatibilityTensorAux, cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_right, - inner_smul_right, real_inner_comm] - ring - -variable {I} in -private lemma aux2 (σ σ' τ : (x : M) → V x) - (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hτ : MDiffAt (T% τ) x) : - compatibilityTensorAux I cov (σ + σ') τ x = - compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ' τ x := by - ext X₀ - rw [compatibilityTensorAux_apply, product_add_left, - fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ)] - simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hσ hσ', inner_add_right] - abel - -variable {I} in -private lemma aux3 {f : M → ℝ} {σ τ : (x : M) → V x} - (hf : MDiffAt f x) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - compatibilityTensorAux I cov σ (f • τ) x = f x • compatibilityTensorAux I cov σ τ x := by - ext X₀ - rw [compatibilityTensorAux_apply, product_smul_right, - fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] - simp [compatibilityTensorAux, cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, - inner_smul_right, real_inner_comm] - ring - -variable {I} in -private lemma aux4 (σ τ τ' : (x : M) → V x) - (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) (hτ' : MDiffAt (T% τ') x) : - compatibilityTensorAux I cov σ (τ + τ') x = - compatibilityTensorAux I cov σ τ x + compatibilityTensorAux I cov σ τ' x := by - ext X₀ - rw [compatibilityTensorAux_apply, product_add_right, - fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ')] - simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hτ hτ', inner_add_right] - abel - theorem compatibilityTensorAux_tensorial₁ (τ : Π x, V x) (hτ : MDiffAt (T% τ) x) : TensorialAt I F (compatibilityTensorAux I cov · τ x) x where - smul hf hσ := aux1 cov hf hσ hτ - add hσ hσ' := aux2 cov _ _ _ hσ hσ' hτ + smul hf hσ := by + ext X₀ + rw [compatibilityTensorAux_apply, product_smul_left, + fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_left, + inner_smul_left] + ring + add hσ hσ' := by + ext X₀ + rw [compatibilityTensorAux_apply, product_add_left, + fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hσ hσ', inner_add_left] + abel theorem compatibilityTensorAux_tensorial₂ (σ : Π x, V x) (hσ : MDiffAt (T% σ) x) : TensorialAt I F (compatibilityTensorAux I cov σ · x) x where - smul hf hτ := aux3 cov hf hσ hτ - add hτ hτ' := aux4 cov _ _ _ hσ hτ hτ' + smul hf hτ := by + ext X₀ + rw [compatibilityTensorAux_apply, product_smul_right, + fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, + inner_smul_right] + ring + add hτ hτ' := by + ext X₀ + rw [compatibilityTensorAux_apply, product_add_right, + fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ')] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hτ hτ', inner_add_right] + abel variable {I} [ContMDiffVectorBundle 1 F V I] in /-- The tensor `(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)` defining when a connection @@ -275,30 +255,19 @@ variable {X : Π x : M, TangentSpace I x} variable {I} [ContMDiffVectorBundle 1 F V I] in theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - compatibilityTensor cov x (σ x) (τ x) (X x) = + cov.compatibilityTensor x (σ x) (τ x) (X x) = fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) - ⟪∇ σ, X, τ⟫ x - ⟪σ, ∇ τ, X⟫ x := by unfold compatibilityTensor - rw [TensorialAt.mkHom₂_apply _ _ hσ hτ] - --rw [compatibilityTensorAux] - simp only [compatibilityTensorAux, ContinuousLinearMap.coe_sub', ContinuousLinearMap.coe_comp', - coe_innerSL_apply, Pi.sub_apply, comp_apply] - conv => - enter [1, 1] - erw [ContinuousLinearMap.sub_apply] - conv => - enter [1, 1, 2] - erw [ContinuousLinearMap.comp_apply] - simp [product, real_inner_comm, fromTangentSpace] + rw [TensorialAt.mkHom₂_apply _ _ hσ hτ, compatibilityTensorAux_apply] variable {I} [ContMDiffVectorBundle 1 F V I] in theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ F] (X₀ : TangentSpace I x) (σ₀ τ₀ : V x) : - compatibilityTensor cov x σ₀ τ₀ X₀ = + cov.compatibilityTensor x σ₀ τ₀ X₀ = fromTangentSpace _ (mfderiv% ⟪(FiberBundle.extend F σ₀), (FiberBundle.extend F τ₀)⟫ x X₀) - - ⟪∇ FiberBundle.extend F σ₀, (FiberBundle.extend E X₀), FiberBundle.extend F τ₀⟫ x - - ⟪FiberBundle.extend F σ₀, ∇ FiberBundle.extend F τ₀, (FiberBundle.extend E X₀)⟫ x := by - simpa [extend_apply_self] using compatibilityTensor_apply cov x (X := FiberBundle.extend E X₀) - (FiberBundle.mdifferentiableAt_extend I F σ₀) (FiberBundle.mdifferentiableAt_extend I F τ₀) + - inner ℝ (cov (FiberBundle.extend F σ₀) x X₀) τ₀ + - inner ℝ σ₀ (cov (FiberBundle.extend F τ₀) x X₀) := by + simp [compatibilityTensor, TensorialAt.mkHom₂_apply_eq_extend, compatibilityTensorAux_apply] variable {I} [ContMDiffVectorBundle 1 F V I] in /-- Predicate saying that a connection `∇` on a Riemannian bundle `(V, g)` is compatible with the @@ -306,35 +275,21 @@ ambient metric, i.e. for all differentiable vector fields `X` on `M` and section `V`, we have `X ⟨σ, τ⟩ = ⟨∇ X σ, τ⟩ + ⟨σ, ∇ X τ⟩`. -/ def IsCompatible [FiniteDimensional ℝ F] : Prop := compatibilityTensor cov = 0 --- Auxiliary computation for `IsCompatible_apply`. --- TODO: inlining this lemma does not work -private lemma isCompatible_apply_aux {A B C : ℝ} (h : A - B - C = 0) : A = B + C := by grind - -variable {I} [ContMDiffVectorBundle 1 F V I] in --- TODO: give a better name; maybe inline? --- variable {I} in -lemma isCompatible_apply [FiniteDimensional ℝ F] (hcov : cov.IsCompatible) - (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - mfderiv% ⟪σ, τ⟫ x (X x) = ⟪∇ σ, X, τ⟫ x + ⟪σ, ∇ τ, X⟫ x := by - rw [IsCompatible] at hcov - have : compatibilityTensor cov x (σ x) (τ x) (X x) = 0 := by simp [hcov] - rw [compatibilityTensor_apply cov x hσ hτ] at this - change (fromTangentSpace _ ((mfderiv I 𝓘(ℝ, ℝ) ⟪σ, τ⟫ x) (X x))) = _ - exact isCompatible_apply_aux this - -open FiberBundle in variable {I} [ContMDiffVectorBundle 1 F V I] in lemma isCompatible_iff [FiniteDimensional ℝ F] : cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {σ τ : (x : M) → V x} (_hX : MDiffAt (T% X) x) (_hσ : MDiffAt (T% σ) x) (_hτ : MDiffAt (T% τ) x), - mfderiv% ⟪σ, τ⟫ x (X x) = ⟪∇ σ, X, τ⟫ x + ⟪σ, ∇ τ, X⟫ x := by - refine ⟨fun hcov x X σ τ hX hσ hτ ↦ cov.isCompatible_apply hcov hσ hτ, fun h ↦ ?_⟩ - unfold IsCompatible + fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) = ⟪∇ σ, X, τ⟫ x + ⟪σ, ∇ τ, X⟫ x := by + refine ⟨fun hcov x X σ τ hX hσ hτ ↦ ?_, fun h ↦ ?_⟩ + · have H := congr($hcov x (σ x) (τ x) (X x)) + simp [compatibilityTensor_apply _ _ hσ hτ] at H + linear_combination H ext x σ₀ τ₀ X₀ - rw [compatibilityTensor_apply_eq_extend, sub_sub, sub_eq_iff_eq_add'] - simp only [Pi.zero_apply, ContinuousLinearMap.zero_apply, add_zero] + rw [compatibilityTensor_apply_eq_extend] have h' := h (FiberBundle.mdifferentiableAt_extend I E X₀) (FiberBundle.mdifferentiableAt_extend I F σ₀) (FiberBundle.mdifferentiableAt_extend I F τ₀) - simpa [fromTangentSpace, extend_apply_self] using h' + simp [product] at h' ⊢ + linear_combination (norm := skip) h' + ring_nf end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 7de77b1bff7dcb..dbbd899f341939 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -86,8 +86,8 @@ theorem torsion_apply (hcov : IsCovariantDerivativeOn E cov univ) {x} theorem torsion_apply_eq_extend (hcov : IsCovariantDerivativeOn E cov univ) {x} (X₀ Y₀ : TangentSpace I x) : torsion hcov x X₀ Y₀ = - cov (extend E Y₀) x X₀ - cov (extend E X₀) x Y₀ - - VectorField.mlieBracket I (extend E X₀) (extend E Y₀) x := by + cov (FiberBundle.extend E Y₀) x X₀ - cov (FiberBundle.extend E X₀) x Y₀ + - VectorField.mlieBracket I (FiberBundle.extend E X₀) (FiberBundle.extend E Y₀) x := by simp [torsion, torsionAux, TensorialAt.mkHom₂_apply_eq_extend] variable (X) in @@ -129,8 +129,9 @@ lemma torsion_apply (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : lemma torsion_apply_eq_extend (X₀ Y₀ : TangentSpace I x) : cov.torsion x X₀ Y₀ = - cov (extend E Y₀) x (extend E X₀ x) - cov (extend E X₀) x (extend E Y₀ x) - - mlieBracket I (extend E X₀) (extend E Y₀) x := by + cov (FiberBundle.extend E Y₀) x (FiberBundle.extend E X₀ x) + - cov (FiberBundle.extend E X₀) x (FiberBundle.extend E Y₀ x) + - mlieBracket I (FiberBundle.extend E X₀) (FiberBundle.extend E Y₀) x := by unfold torsion IsCovariantDerivativeOn.torsion apply TensorialAt.mkHom₂_apply_eq_extend @@ -153,7 +154,7 @@ lemma torsion_eq_zero_iff : cov.torsion = 0 ↔ ext x u v rw [torsion_apply_eq_extend, h] · simp - · apply mdifferentiableAt_extend - · apply mdifferentiableAt_extend + · apply FiberBundle.mdifferentiableAt_extend + · apply FiberBundle.mdifferentiableAt_extend end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index 3c62b600c76775..f0de414abe2c3e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -174,7 +174,7 @@ lemma pointwise₂ · exact (hΦ₁ _ hτ).pointwise hσ hσ' hσσ' · exact (hΦ₂ _ hσ').pointwise hτ hτ' hττ' -variable [IsManifold I 1 M] +variable -- TODO prove transport lemmas `ContinuousLinearEquiv.IsTopologicalAddGroup` and -- `ContinuousLinearEquiv.continuousSMul`, then the next four hypotheses can be removed -- (and the appropriate instances constructed in the proof of `TensorialAt.mkHom` by transport @@ -194,26 +194,29 @@ noncomputable def mkHom have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional LinearMap.toContinuousLinearMap { - toFun v := Φ (_root_.extend F v) + toFun v := Φ (FiberBundle.extend F v) map_add' v₁ v₂ := by - rw [← hΦ.add (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..)] - apply hΦ.pointwise (mdifferentiableAt_extend ..) <| - mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) + rw [← hΦ.add (FiberBundle.mdifferentiableAt_extend ..) + (FiberBundle.mdifferentiableAt_extend ..)] + apply hΦ.pointwise (FiberBundle.mdifferentiableAt_extend ..) <| + mdifferentiableAt_add_section (FiberBundle.mdifferentiableAt_extend ..) + (FiberBundle.mdifferentiableAt_extend ..) simp map_smul' c v := by dsimp - rw [← hΦ.smul (f := fun _ ↦ c) (mdifferentiable_const ..) (mdifferentiableAt_extend ..)] - apply hΦ.pointwise (mdifferentiableAt_extend ..) <| - mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..) + rw [← hΦ.smul (f := fun _ ↦ c) (mdifferentiable_const ..) + (FiberBundle.mdifferentiableAt_extend ..)] + apply hΦ.pointwise (FiberBundle.mdifferentiableAt_extend ..) <| + mdifferentiableAt_const.smul_section (FiberBundle.mdifferentiableAt_extend ..) simp } theorem mkHom_apply {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F (Φ ·) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : mkHom Φ x hΦ (σ x) = Φ σ := - hΦ.pointwise (mdifferentiableAt_extend ..) hσ (by simp) + hΦ.pointwise (FiberBundle.mdifferentiableAt_extend ..) hσ (by simp) theorem mkHom_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F Φ x) (σ : V x) : - mkHom Φ x hΦ σ = Φ (_root_.extend F σ) := + mkHom Φ x hΦ σ = Φ (FiberBundle.extend F σ) := rfl /-- Given an `A`-valued operation `Φ` on sections of vector bundles `V` and `V'` which is tensorial @@ -234,37 +237,38 @@ noncomputable def mkHom₂ have : T2Space (V' x) := Ψ'.symm.toHomeomorph.t2Space have : FiniteDimensional 𝕜 (V' x) := Ψ'.symm.toLinearEquiv.finiteDimensional have H : IsBilinearMap 𝕜 - (fun (v : V x) (w : V' x) ↦ Φ (_root_.extend F v) (_root_.extend F' w)) := + (fun (v : V x) (w : V' x) ↦ Φ (FiberBundle.extend F v) (FiberBundle.extend F' w)) := { add_left v₁ v₂ w := by - rw [← (hΦ₁ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) - (mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) _ - (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) _ rfl - · exact mdifferentiableAt_add_section (mdifferentiableAt_extend ..) - (mdifferentiableAt_extend ..) + rw [← (hΦ₁ _ (FiberBundle.mdifferentiableAt_extend ..)).add + (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) _ + (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) _ rfl + · exact mdifferentiableAt_add_section (FiberBundle.mdifferentiableAt_extend ..) + (FiberBundle.mdifferentiableAt_extend ..) · simp smul_left c v w := by - rw [← (hΦ₁ _ (mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) (mdifferentiable_const ..) - (mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) - (mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..)) - (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) + rw [← (hΦ₁ _ (FiberBundle.mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) + (mdifferentiable_const ..) (FiberBundle.mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) + (mdifferentiableAt_const.smul_section (FiberBundle.mdifferentiableAt_extend ..)) + (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) · simp · rfl add_right v w₁ w₂ := by - rw [← (hΦ₂ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) - (mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) - (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) <| - mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) + rw [← (hΦ₂ _ (FiberBundle.mdifferentiableAt_extend ..)).add + (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) + (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) <| + mdifferentiableAt_add_section (FiberBundle.mdifferentiableAt_extend ..) + (FiberBundle.mdifferentiableAt_extend ..) · rfl · simp smul_right c v w := by - rw [← (hΦ₂ _ (mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) (mdifferentiable_const ..) - (mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) - (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) <| - mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..) + rw [← (hΦ₂ _ (FiberBundle.mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) + (mdifferentiable_const ..) (FiberBundle.mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) + (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) <| + mdifferentiableAt_const.smul_section (FiberBundle.mdifferentiableAt_extend ..) · rfl · simp } H.toLinearMap.toContinuousBilinearMap @@ -275,15 +279,15 @@ theorem mkHom₂_apply (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : mkHom₂ Φ x hΦ₁ hΦ₂ (σ x) (τ x) = Φ σ τ := - TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) hσ (mdifferentiableAt_extend ..) hτ - (by simp) (by simp) + TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) hσ + (FiberBundle.mdifferentiableAt_extend ..) hτ (by simp) (by simp) theorem mkHom₂_apply_eq_extend {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) (σ : V x) (τ : V' x) : - mkHom₂ Φ x hΦ₁ hΦ₂ σ τ = Φ (_root_.extend F σ) (_root_.extend F' τ) := + mkHom₂ Φ x hΦ₁ hΦ₂ σ τ = Φ (FiberBundle.extend F σ) (FiberBundle.extend F' τ) := rfl end TensorialAt From dcabc20bd42ac37b415c961662a3f41c7c5dd674 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 18:30:01 +0000 Subject: [PATCH 566/601] defer MDifferentiable.inner_bundle issue --- .../CovariantDerivative/LeviCivita.lean | 20 +++++++++ .../CovariantDerivative/Metric.lean | 42 ++++++------------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 17bf0d8c58fccd..e8d42b1cef1e8e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -80,6 +80,26 @@ def IsLeviCivitaConnection [FiniteDimensional ℝ E] : Prop := cov.IsCompatible local notation "⟪" X ", " Y "⟫" => product X Y +/- TODO: writing `hσ.inner_bundle hτ` or writing `by apply MDifferentiable.inner_bundle hσ hτ` +yields an error +synthesized type class instance is not definitionally equal to expression inferred by typing rules, +synthesized + fun x ↦ instNormedAddCommGroupOfRiemannianBundle x +inferred + fun b ↦ inst✝⁷ +Diagnose and fix this, and then replace the below by `MDifferentiable(At).inner_bundle! -/ + +variable {I} in +lemma _root_.MDifferentiable.inner_bundle' {X Y : Π x : M, TangentSpace I x} + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) : MDiff ⟪X, Y⟫ := + MDifferentiable.inner_bundle hX hY + +variable {I} in +lemma _root_.MDifferentiableAt.inner_bundle' {x : M} {X Y : Π x : M, TangentSpace I x} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : + MDiffAt ⟪X, Y⟫ x := + MDifferentiableAt.inner_bundle hX hY + variable (X Y Z) in /-- The first term in the definition of the candidate Levi-Civita connection: `rhs_aux I X Y Z = X ⟨Y, Z⟩ = x ↦ d(⟨Y, Z⟩)_x (X x)`. diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 669003fa8d038d..2f005b12fa0e65 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -50,7 +50,7 @@ variable -- Let `M` be a `C^k` real manifold modeled on `(E, H)` {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ℝ E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 2 M] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- Let `V` be a bundle over `M`, endowed with a Riemannian metric. (F : Type*) [NormedAddCommGroup F] [NormedSpace ℝ F] {V : M → Type*} [TopologicalSpace (TotalSpace F V)] @@ -79,7 +79,7 @@ local notation "⟪" σ ", " τ "⟫" => product σ τ -- Basic API for the product of two sections. section product -omit [TopologicalSpace M] [IsManifold I 2 M] +omit [TopologicalSpace M] lemma product_apply (x) : ⟪σ, τ⟫ x = inner ℝ (σ x) (τ x) := rfl @@ -146,41 +146,23 @@ end product -- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) -- only hold point-wise. They abstract the expanding and unexpanding of `product`. -omit [TopologicalSpace M] [IsManifold I 2 M] in +omit [TopologicalSpace M] in lemma product_congr_left {x} (h : σ x = σ' x) : product σ τ x = product σ' τ x := by rw [product_apply, h, ← product_apply] -omit [TopologicalSpace M] [IsManifold I 2 M] in +omit [TopologicalSpace M] in lemma product_congr_left₂ {x} (h : σ x = σ' x + σ'' x) : product σ τ x = product σ' τ x + product σ'' τ x := by rw [product_apply, h, inner_add_left, ← product_apply] -omit [TopologicalSpace M] [IsManifold I 2 M] in +omit [TopologicalSpace M] in lemma product_congr_right {x} (h : τ x = τ' x) : product σ τ x = product σ τ' x := by rw [product_apply, h, ← product_apply] -omit [TopologicalSpace M] [IsManifold I 2 M] in +omit [TopologicalSpace M] in lemma product_congr_right₂ {x} (h : τ x = τ' x + τ'' x) : product σ τ x = product σ τ' x + product σ τ'' x := by rw [product_apply, h, inner_add_right, ← product_apply] -/- TODO: writing `hσ.inner_bundle hτ` or writing `by apply MDifferentiable.inner_bundle hσ hτ` -yields an error -synthesized type class instance is not definitionally equal to expression inferred by typing rules, -synthesized - fun x ↦ instNormedAddCommGroupOfRiemannianBundle x -inferred - fun b ↦ inst✝⁷ -Diagnose and fix this, and then replace the below by `MDifferentiable(At).inner_bundle! -/ - -variable {F} [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {I} in -lemma MDifferentiable.inner_bundle' (hσ : MDiff (T% σ)) (hτ : MDiff (T% τ)) : MDiff ⟪σ, τ⟫ := - MDifferentiable.inner_bundle hσ hτ - -variable {F} [VectorBundle ℝ F V] [IsContMDiffRiemannianBundle I 1 F V] {I} in -lemma MDifferentiableAt.inner_bundle' {x} (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : - MDiffAt ⟪σ, τ⟫ x := - MDifferentiableAt.inner_bundle hσ hτ - namespace CovariantDerivative -- Let `cov` be a covariant derivative on `V`. @@ -199,7 +181,6 @@ noncomputable def compatibilityTensorAux (σ τ : Π x : M, V x) : (NormedSpace.fromTangentSpace _).toContinuousLinearMap ∘L mfderiv% ⟪σ, τ⟫ x - ((innerSL ℝ (τ x)) ∘L (cov σ x)) - ((innerSL ℝ (σ x)) ∘L (cov τ x)) -omit [IsManifold I 2 M] in lemma compatibilityTensorAux_apply (σ τ : Π x : M, V x) {x : M} (X₀ : TangentSpace I x) : compatibilityTensorAux I cov σ τ x X₀ = @@ -215,14 +196,14 @@ theorem compatibilityTensorAux_tensorial₁ (τ : Π x, V x) (hτ : MDiffAt (T% smul hf hσ := by ext X₀ rw [compatibilityTensorAux_apply, product_smul_left, - fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] + fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle hτ)] simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hσ hf, inner_add_left, inner_smul_left] ring add hσ hσ' := by ext X₀ rw [compatibilityTensorAux_apply, product_add_left, - fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ'.inner_bundle' hτ)] + fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle hτ) (hσ'.inner_bundle hτ)] simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hσ hσ', inner_add_left] abel @@ -231,14 +212,14 @@ theorem compatibilityTensorAux_tensorial₂ (σ : Π x, V x) (hσ : MDiffAt (T% smul hf hτ := by ext X₀ rw [compatibilityTensorAux_apply, product_smul_right, - fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle' hτ)] + fromTangentSpace_mfderiv_smul_apply hf (hσ.inner_bundle hτ)] simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hτ hf, inner_add_right, inner_smul_right] ring add hτ hτ' := by ext X₀ rw [compatibilityTensorAux_apply, product_add_right, - fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle' hτ) (hσ.inner_bundle' hτ')] + fromTangentSpace_mfderiv_add_apply (hσ.inner_bundle hτ) (hσ.inner_bundle hτ')] simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hτ hτ', inner_add_right] abel @@ -275,7 +256,8 @@ ambient metric, i.e. for all differentiable vector fields `X` on `M` and section `V`, we have `X ⟨σ, τ⟩ = ⟨∇ X σ, τ⟩ + ⟨σ, ∇ X τ⟩`. -/ def IsCompatible [FiniteDimensional ℝ F] : Prop := compatibilityTensor cov = 0 -variable {I} [ContMDiffVectorBundle 1 F V I] in +variable {I} [IsManifold I 1 M] [ContMDiffVectorBundle 1 F V I] + lemma isCompatible_iff [FiniteDimensional ℝ F] : cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {σ τ : (x : M) → V x} (_hX : MDiffAt (T% X) x) (_hσ : MDiffAt (T% σ) x) (_hτ : MDiffAt (T% τ) x), From d2d07e6e85c35825725a18b70627114f022a03a0 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 15:33:10 +0000 Subject: [PATCH 567/601] docs --- .../VectorBundle/CovariantDerivative/Metric.lean | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 2f005b12fa0e65..0600a3c7a11980 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -32,10 +32,15 @@ and differentiable sections `σ`, `τ`. ## TODO -* when mathlib has a notion of parallel transport, prove the equivalence of - `CovariantDerivative.IsCompatible` with the characterisation that parallel transport be an +* When Mathlib has a notion of parallel transport, prove the equivalence of + `CovariantDerivative.IsCompatible` with the characterisation that parallel transport be an isometry. +* Given connections on bundles `V` and `W`, there is an induced connnection on bundle Hom(V, W). + When this induced connection has been defined in Mathlib, rephrase the definition of + `CovariantDerivative.compatibilityTensor`, to be simply the covariant derivative of the metric + tensor. + -/ open Bundle Function NormedSpace From b6fb0a03b92142bd1c6745ffea58963a6bdd56c2 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Sat, 7 Mar 2026 22:27:25 +0100 Subject: [PATCH 568/601] Some cleanup --- .../CovariantDerivative/Metric.lean | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 0600a3c7a11980..8fbd1dc68d9b56 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -14,13 +14,13 @@ public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace This file defines connections on a Riemannian vector bundle which are compatible with the ambient metric. A bundled connection `∇` on a Riemannian vector bundle `(V, g)` is compatible with the metric `g` if and only if the differentiated metric tensor `∇ g` (defined by -`(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)`) vanishes on all differentiable vector fields `X` -and differentiable sections `σ`, `τ`. +`(X, σ, τ) ↦ ∇_X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)`) vanishes on all differentiable vector fields +`X` and differentiable sections `σ`, `τ`. ## Main definitions and results * `CovariantDerivative.compatibilityTensor`: the tensor - `(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)` defining when a connection `∇` on a Riemannian + `(X, σ, τ) ↦ X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)` defining when a connection `∇` on a Riemannian vector bundle `(V, g)` is compatible with the metric `g`. * `CovariantDerivative.compatibilityTensor_apply` and `CovariantDerivative.compatibilityTensor_apply` give formulas for applying the compatibility @@ -42,7 +42,6 @@ and differentiable sections `σ`, `τ`. tensor. -/ - open Bundle Function NormedSpace open scoped Manifold ContDiff @@ -64,15 +63,22 @@ variable [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul ℝ (V x)] [FiberBundle F V] [RiemannianBundle V] -/-! Compatible connections: a connection on `V` is compatible with the metric on `V` iff -`∇ X ⟨σ, τ⟩ = ⟨∇ X σ, τ⟩ + ⟨σ, ∇ X τ⟩` holds for all sufficiently nice vector fields `X` on `M` and -sections `σ`, `τ` of `V`. In our definition, we ask for this identity to at each `x : M`, whenever -`X`, `σ` and `τ` are differentiable at `x`. +/-! # Compatible connections + +A connection on `V` is compatible with the metric on `V` iff `X ⟨σ, τ⟩ = ⟨∇_X σ, τ⟩ + ⟨σ, ∇_X τ⟩` +holds for all sufficiently nice vector fields `X` on `M` and sections `σ`, `τ` of `V`. The left hand side is the pushforward of the function `⟨σ, τ⟩` along the vector field `X`: -the left hand side at `x` is `df(X x)`, where `f := ⟨σ, τ⟩`. -/ +the left hand side at `x` is `df(X x)`, where `f := ⟨σ, τ⟩` (ie. `X` is seen a derivation on +the algebra of function on the base manifold acting on the function `⟨σ, τ⟩`). +In our definition, we ask for this identity to at each `x : M`, whenever `X`, `σ` and `τ` are +differentiable at `x`. +-/ variable {σ σ' σ'' τ τ' τ'' : Π x : M, V x} +-- set_option trace.profiler true +-- set_option profiler.threshold 500 + /-- The scalar product of two sections. -/ noncomputable abbrev product (σ τ : Π x : M, V x) : M → ℝ := fun x ↦ inner ℝ (σ x) (τ x) @@ -97,7 +103,7 @@ lemma product_swap : ⟪τ, σ⟫ = ⟪σ, τ⟫ := by @[simp] lemma product_zero_left : ⟪0, σ⟫ = 0 := by ext x - simp [product] + simp only [product, Pi.zero_apply, inner_zero_left] @[simp] lemma product_zero_right : ⟪σ, 0⟫ = 0 := by rw [product_swap, product_zero_left] @@ -174,8 +180,11 @@ namespace CovariantDerivative -- TODO: include in cheat sheet! variable (cov : CovariantDerivative I F V) -/-- Local notation for a connection. Caution: `∇ σ, X` corresponds to `∇ₓ σ` in textbooks -/ -local notation "∇" σ "," X => fun (x:M) ↦ cov σ x (X x) + +/-- Local notation for a covariant derivative on a vector bundle acting on a vector field and a +section. -/ +local syntax "∇" term:arg term : term +local macro_rules | `(∇ $X $σ) => `(fun (x : M) ↦ cov $σ x ($X x)) variable {F} @@ -229,7 +238,7 @@ theorem compatibilityTensorAux_tensorial₂ (σ : Π x, V x) (hσ : MDiffAt (T% abel variable {I} [ContMDiffVectorBundle 1 F V I] in -/-- The tensor `(X, σ, τ) ↦ ∇ₓ g(σ, τ) - g(∇ₓ σ, τ) - g(σ, ∇ₓ τ)` defining when a connection +/-- The tensor `(X, σ, τ) ↦ X g(σ, τ) - g(∇_X σ, τ) - g(σ, ∇_X τ)` defining when a connection `∇` on a Riemannian bundle `(M, V)` is compatible with the metric `g`. -/ @[no_expose] noncomputable def compatibilityTensor [FiniteDimensional ℝ F] (x : M) : V x →L[ℝ] V x →L[ℝ] (TangentSpace I x →L[ℝ] ℝ) := @@ -242,7 +251,7 @@ variable {I} [ContMDiffVectorBundle 1 F V I] in theorem compatibilityTensor_apply [FiniteDimensional ℝ F] (x : M) (hσ : MDiffAt (T% σ) x) (hτ : MDiffAt (T% τ) x) : cov.compatibilityTensor x (σ x) (τ x) (X x) = - fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) - ⟪∇ σ, X, τ⟫ x - ⟪σ, ∇ τ, X⟫ x := by + fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) - ⟪∇ X σ, τ⟫ x - ⟪σ, ∇ X τ⟫ x := by unfold compatibilityTensor rw [TensorialAt.mkHom₂_apply _ _ hσ hτ, compatibilityTensorAux_apply] @@ -258,15 +267,15 @@ theorem compatibilityTensor_apply_eq_extend [FiniteDimensional ℝ F] (X₀ : Ta variable {I} [ContMDiffVectorBundle 1 F V I] in /-- Predicate saying that a connection `∇` on a Riemannian bundle `(V, g)` is compatible with the ambient metric, i.e. for all differentiable vector fields `X` on `M` and sections `σ` and `τ` of -`V`, we have `X ⟨σ, τ⟩ = ⟨∇ X σ, τ⟩ + ⟨σ, ∇ X τ⟩`. -/ +`V`, we have `X ⟨σ, τ⟩ = ⟨∇_X σ, τ⟩ + ⟨σ, ∇_X τ⟩`. -/ def IsCompatible [FiniteDimensional ℝ F] : Prop := compatibilityTensor cov = 0 variable {I} [IsManifold I 1 M] [ContMDiffVectorBundle 1 F V I] lemma isCompatible_iff [FiniteDimensional ℝ F] : - cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {σ τ : (x : M) → V x} - (_hX : MDiffAt (T% X) x) (_hσ : MDiffAt (T% σ) x) (_hτ : MDiffAt (T% τ) x), - fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) = ⟪∇ σ, X, τ⟫ x + ⟪σ, ∇ τ, X⟫ x := by + cov.IsCompatible ↔ ∀ {x : M} {X : Π x, TangentSpace I x} {σ τ : (x : M) → V x}, + MDiffAt (T% X) x → MDiffAt (T% σ) x → MDiffAt (T% τ) x → + fromTangentSpace _ (mfderiv% ⟪σ, τ⟫ x (X x)) = ⟪∇ X σ, τ⟫ x + ⟪σ, ∇ X τ⟫ x := by refine ⟨fun hcov x X σ τ hX hσ hτ ↦ ?_, fun h ↦ ?_⟩ · have H := congr($hcov x (σ x) (τ x) (X x)) simp [compatibilityTensor_apply _ _ hσ hτ] at H @@ -280,3 +289,4 @@ lemma isCompatible_iff [FiniteDimensional ℝ F] : ring_nf end CovariantDerivative +#lint From 165f4c2e87da337ce40a30baa9b392744f658177 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 22:37:59 +0000 Subject: [PATCH 569/601] stray #lint --- .../Manifold/VectorBundle/CovariantDerivative/Metric.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 8fbd1dc68d9b56..8d692762ecd388 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -289,4 +289,3 @@ lemma isCompatible_iff [FiniteDimensional ℝ F] : ring_nf end CovariantDerivative -#lint From f8ff4b7547c214a824fa5f2a05bc1d229dcbca52 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 22:55:05 +0000 Subject: [PATCH 570/601] remove smuls --- .../CovariantDerivative/LeviCivita.lean | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index e8d42b1cef1e8e..d3d5dc8d6f1cc4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -159,12 +159,12 @@ lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) omit [IsManifold I 2 M] in variable (X Y Z) in -lemma rhs_aux_smulX_apply (f : M → ℝ) (x) : rhs_aux I (f • X) Y Z x = f x • rhs_aux I X Y Z x := by +lemma rhs_aux_smulX_apply (f : M → ℝ) (x) : rhs_aux I (f • X) Y Z x = f x * rhs_aux I X Y Z x := by simp [rhs_aux] omit [IsManifold I 2 M] in variable (X Y Z) in -lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f • rhs_aux I X Y Z := by +lemma rhs_aux_smulX (f : M → ℝ) : rhs_aux I (f • X) Y Z = f * rhs_aux I X Y Z := by ext x exact rhs_aux_smulX_apply .. @@ -172,20 +172,20 @@ variable (X) in lemma rhs_aux_smulY_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) - rhs_aux I X (f • Y) Z x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by + rhs_aux I X (f • Y) Z x = f x * rhs_aux I X Y Z x + A x * ⟪Y, Z⟫ x := by rw [rhs_aux, product_smul_left, mfderiv_smul hf (hY.inner_bundle' hZ)] rfl variable (X) in lemma rhs_aux_smulY {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) - rhs_aux I X (f • Y) Z = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by + rhs_aux I X (f • Y) Z = f * rhs_aux I X Y Z + A * ⟪Y, Z⟫ := by ext x simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] variable (X) in lemma rhs_aux_smulY_const_apply {a : ℝ} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - rhs_aux I X (a • Y) Z x = a • rhs_aux I X Y Z x := by + rhs_aux I X (a • Y) Z x = a * rhs_aux I X Y Z x := by let f : M → ℝ := fun _ ↦ a have h1 : rhs_aux I X (a • Y) Z x = rhs_aux I X (f • Y) Z x := by simp only [f]; congr rw [h1, rhs_aux_smulY_apply I X mdifferentiableAt_const hY hZ] @@ -201,20 +201,20 @@ variable (X) in lemma rhs_aux_smulZ_apply {f : M → ℝ} (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) - rhs_aux I X Y (f • Z) x = f x • rhs_aux I X Y Z x + A x • ⟪Y, Z⟫ x := by + rhs_aux I X Y (f • Z) x = f x * rhs_aux I X Y Z x + A x * ⟪Y, Z⟫ x := by rw [rhs_aux_swap, rhs_aux_smulY_apply, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] variable (X) in lemma rhs_aux_smulZ {f : M → ℝ} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) - rhs_aux I X Y (f • Z) = f • rhs_aux I X Y Z + A • ⟪Y, Z⟫ := by + rhs_aux I X Y (f • Z) = f * rhs_aux I X Y Z + A * ⟪Y, Z⟫ := by rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] exacts [hf, hZ, hY] variable (X) in lemma rhs_aux_smulZ_const_apply {a : ℝ} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : - rhs_aux I X Y (a • Z) x = a • rhs_aux I X Y Z x := by + rhs_aux I X Y (a • Z) x = a * rhs_aux I X Y Z x := by let f : M → ℝ := fun _ ↦ a have h1 : rhs_aux I X Y (a • Z) x = rhs_aux I X Y (f • Z) x := by simp only [f]; congr rw [h1, rhs_aux_smulZ_apply I X mdifferentiableAt_const hY hZ] From 958346352a8ea7a92f5933f2716d0f198b6e23a2 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 22:58:08 +0000 Subject: [PATCH 571/601] namespaces --- .../Manifold/VectorBundle/CovariantDerivative/Metric.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 8d692762ecd388..f21019531d9db2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -42,7 +42,7 @@ metric `g` if and only if the differentiated metric tensor `∇ g` (defined by tensor. -/ -open Bundle Function NormedSpace +open Bundle NormedSpace open scoped Manifold ContDiff @[expose] public section From 8c5cd5c3b5cc74fb263f71a89b2c2f545b2f4386 Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 23:06:11 +0000 Subject: [PATCH 572/601] doc --- .../Manifold/VectorBundle/CovariantDerivative/Metric.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index f21019531d9db2..54ebf466a50e45 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -39,7 +39,7 @@ metric `g` if and only if the differentiated metric tensor `∇ g` (defined by * Given connections on bundles `V` and `W`, there is an induced connnection on bundle Hom(V, W). When this induced connection has been defined in Mathlib, rephrase the definition of `CovariantDerivative.compatibilityTensor`, to be simply the covariant derivative of the metric - tensor. + tensor (considered as a section of Hom(V, Hom(V, ℝ))). -/ open Bundle NormedSpace From 5fd575dd7208c2d4382a21fd641b0c0168f80d6d Mon Sep 17 00:00:00 2001 From: Heather Macbeth <25316162+hrmacbeth@users.noreply.github.com> Date: Sat, 7 Mar 2026 23:07:39 +0000 Subject: [PATCH 573/601] typo --- .../Manifold/VectorBundle/CovariantDerivative/Metric.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean index 54ebf466a50e45..7f9e7ae75a2757 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -36,7 +36,7 @@ metric `g` if and only if the differentiated metric tensor `∇ g` (defined by `CovariantDerivative.IsCompatible` with the characterisation that parallel transport be an isometry. -* Given connections on bundles `V` and `W`, there is an induced connnection on bundle Hom(V, W). +* Given connections on bundles `V` and `W`, there is an induced connnection on the bundle Hom(V, W). When this induced connection has been defined in Mathlib, rephrase the definition of `CovariantDerivative.compatibilityTensor`, to be simply the covariant derivative of the metric tensor (considered as a section of Hom(V, Hom(V, ℝ))). From b16f68144ec435e83d89f6c919e9e7d192b8ec81 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 8 Mar 2026 10:43:56 +0100 Subject: [PATCH 574/601] feat: add sub and neg lemmas for covariant derivatives --- .../CovariantDerivative/Basic.lean | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 091dc28fbbf7b9..fc0e2ec60712aa 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -194,6 +194,20 @@ lemma zero [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) simpa using (hcov.add (mdifferentiableAt_zeroSection ..) (mdifferentiableAt_zeroSection ..) : cov (0 + 0) x = _) +lemma neg [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) + {σ : Π x : M, V x} {x} + (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + cov (-σ) x = - cov σ x := by + rw [eq_neg_iff_add_eq_zero, ← hcov.add (mdifferentiableAt_neg_section hσ) hσ] + simp (disch := assumption) + +lemma sub [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) + {σ σ' : Π x : M, V x} {x} + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : + cov (σ - σ') x = cov σ x - cov σ' x := by + rw [sub_eq_neg_add, hcov.add (mdifferentiableAt_neg_section hσ') hσ, hcov.neg hσ'] + abel + theorem smul_const (hcov : IsCovariantDerivativeOn F cov s) {σ : Π x : M, V x} {x} (a : 𝕜) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : @@ -372,6 +386,22 @@ lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 ext1 x simp [cov.isCovariantDerivativeOnUniv.zero] +-- XXX: do we prefer this statement, or point-wise versions instead? +-- if both, which one should be simp? +@[simp] +lemma neg [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) + {σ : Π x : M, V x} (hσ : MDiff (T% σ)) : + cov (-σ) = - cov σ := by + ext1 x + exact cov.isCovariantDerivativeOnUniv.neg (hσ x) + +@[simp] +lemma sub [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) + {σ σ' : Π x : M, V x} (hσ : MDiff (T% σ)) (hσ' : MDiff (T% σ')) : + cov (σ - σ') = cov σ - cov σ' := by + ext1 x + exact cov.isCovariantDerivativeOnUniv.sub (hσ x) (hσ' x) + /-- If `cov` is a covariant derivative on each set in an open cover, it is a covariant derivative. -/ def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} From b1a6f3b74db3b0808a428ed1e30ade99d5bb9669 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 8 Mar 2026 11:35:15 +0100 Subject: [PATCH 575/601] wip: define the curvature tensor --- Mathlib.lean | 1 + .../CovariantDerivative/Curvature.lean | 172 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean diff --git a/Mathlib.lean b/Mathlib.lean index fc474e354ac402..d1953f609292a9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4430,6 +4430,7 @@ public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.ChristoffelSymbols +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Curvature public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean new file mode 100644 index 00000000000000..3287ded343502e --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -0,0 +1,172 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorField.LieBracket + +/-! # Curvature of an affine connection + +We define the curvature tensor of an affine connection, i.e. a covariant derivative on the tangent +bundle `TM` of some manifold `M`. + +## Main definitions and results + +TODO! + +-/ + +@[expose] public section + +open Bundle Set NormedSpace +open scoped Manifold ContDiff + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +/-! ## Curvature tensor of an unbundled covariant derivative on `TM` on a set `s` -/ +namespace IsCovariantDerivativeOn + +variable (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) + +variable {X X' Y : (Π x : M, TangentSpace I x)} + +/-- Local notation for a covariant derivative on a vector bundle acting on a vector field and a +section. -/ +local syntax "∇" term:arg term : term +local macro_rules | `(∇ $X $σ) => `(fun (x : M) ↦ cov $σ x ($X x)) + +example {x} : (∇ X Y) x = cov Y x (X x) := by rfl + +/-- The Riemannian curvature endomorphism of a covariant derivative on the tangent bundle `TM`, +as a bare function. Prefer to use `IsCovariantDerivativeOn.curvatureTensor` +(which is a (3,1)-tensor) instead. -/ +noncomputable def curvatureTensorAux : + (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) → + (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x) := + fun X Y Z ↦ (∇ X (∇ Y Z)) - ∇ Y (∇ X Z) - ∇ (VectorField.mlieBracket I X Y) Z + +variable [IsManifold I 2 M] [CompleteSpace E] + {cov cov' : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)} + {X X' Y Z : Π x : M, TangentSpace I x} + +-- TODO: generalise further and try to find in the library! +lemma temp + {cov : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} + (hcov : IsCovariantDerivativeOn E cov) + {x : M} {X σ : (x : M) → TangentSpace I x} + (hσ : CMDiff 2 T% σ) (hZ : CMDiff 2 T% X) + (aux : ContMDiffAt I (I.prod 𝓘(𝕜, E →L[𝕜] E)) 1 + (fun x ↦ TotalSpace.mk' (E →L[𝕜] E) x (cov X x)) x) : + ContMDiffAt I (I.prod 𝓘(𝕜, E)) 1 (fun x ↦ TotalSpace.mk' E x ((cov X x) (σ x))) x := by + sorry + +lemma temp' -- I suspect this one will also work! + {cov : ((x : M) → TangentSpace I x) → (x : M) → TangentSpace I x →L[𝕜] TangentSpace I x} + (hcov : IsCovariantDerivativeOn E cov) + {x : M} {X σ : (x : M) → TangentSpace I x} + -- XXX: I suspect σ being C¹ will suffice, and no extra hypotheses on X are necessary + (hσ : CMDiffAt 1 (T% σ) x) + (aux : ContMDiffAt I (I.prod 𝓘(𝕜, E →L[𝕜] E)) 1 + (fun x ↦ TotalSpace.mk' (E →L[𝕜] E) x (cov X x)) x) : + ContMDiffAt I (I.prod 𝓘(𝕜, E)) 1 (fun x ↦ TotalSpace.mk' E x ((cov X x) (σ x))) x := by + sorry + +/- Lessons learned from the experiment below: +- we need the lemma temp (or perhaps just temp'); is this in mathlib already? +- the curvature tensor needs a C¹ connection, and a manifold of order 3 and minSmoothness k 2 or so +- we can only prove tensoriality for C² sections (at a point, I hope! to be confirmed), + so need new tensoriality lemmas +- `mdifferentiableAt` lemmas for C^k covariant derivatives would be nice API addition +- want more `have`s, and perhaps even more API, around cov applied to the various sections +-/ + +variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] +theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + (Y Z : (Π x : M, TangentSpace I x)) : + TensorialAt I E (curvatureTensorAux cov · Y Z x) x where + smul {f X} hf hX := by + unfold curvatureTensorAux + dsimp + sorry + add {σ σ'} hσ hσ' := by + unfold curvatureTensorAux + simp only [Pi.add_apply, map_add, Pi.sub_apply] + --rw [VectorField.mlieBracket_add_left hσ hσ'] + have : VectorField.mlieBracket I (σ + σ') Y x = + VectorField.mlieBracket I σ Y x + VectorField.mlieBracket I σ' Y x := by + rw [VectorField.mlieBracket_add_left hσ hσ'] + set A := cov (fun x ↦ (cov Z x) (Y x)) x (σ x) + set B := cov (fun x ↦ (cov Z x) (Y x)) x (σ' x) + --erw [ContinuousLinearMap.add_apply] + -- TODO: need stronger assumptions on σ, σ' and Z! + have hσ : CMDiff 2 (T% σ) := sorry + have hσ' : CMDiff 2 (T% σ') := sorry + have hY : CMDiffAt 2 (T% Y) x := sorry + have hZ : CMDiff 2 (T% Z) := sorry + have hZ' : CMDiffAt 2 (T% Z) x := sorry + rw [hcov.sub] + rotate_left + · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply ContMDiffAt.add_section + · exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + · exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply ContMDiffAt.mlieBracket_vectorField (ContMDiff.add_section hσ hσ' ..) hY + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general k + rw [hcov.sub]; rotate_left + · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply ContMDiffAt.mlieBracket_vectorField (hσ x) hY _ + simp; sorry -- same as above + dsimp + erw [hcov.add]; rotate_left + · -- TODO: centralise, same as above! + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + · -- TODO: centralise, same as above! + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + simp only [ContinuousLinearMap.add_apply] + set C := cov (fun x ↦ (cov Z x) (σ x)) x + set D := cov (fun x ↦ (cov Z x) (σ' x)) x + rw [hcov.sub]; rotate_left + · -- TODO: centralise, same as above! + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + · --- TODO: centralise, same as above! + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply ContMDiffAt.mlieBracket_vectorField (hσ' x) hY _ + simp; sorry -- same as above + simp + sorry + +-- update hypotheses to match lemma above, once proven! +variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] +theorem curvatureTensorAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + (X Z : (Π x : M, TangentSpace I x)) : + TensorialAt I E (curvatureTensorAux cov X · Z x) x := + -- proof is analogous to the version in X + sorry + +-- update hypotheses to match lemma above, once proven! +variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] +theorem curvatureTensorAux_tensorial₃ (hcov : IsCovariantDerivativeOn E cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + (X Y : (Π x : M, TangentSpace I x)) : + TensorialAt I E (curvatureTensorAux cov X Y · x) x := + -- linearity should be "easy" also, scalar multiplication is a different proof + sorry + +end IsCovariantDerivativeOn From d2dfd9ff52b93a149bc6ab804949b9f003e054b3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 8 Mar 2026 11:57:00 +0100 Subject: [PATCH 576/601] chore: remove _root_.extend --- it has been moved to FiberBundle --- Mathlib.lean | 1 - .../CovariantDerivative/Ehresmann.lean | 2 +- .../CovariantDerivative/LeviCivita.lean | 10 +- .../Manifold/VectorBundle/Extend.lean | 103 ------------------ .../Manifold/VectorBundle/Tensoriality.lean | 3 +- 5 files changed, 8 insertions(+), 111 deletions(-) delete mode 100644 Mathlib/Geometry/Manifold/VectorBundle/Extend.lean diff --git a/Mathlib.lean b/Mathlib.lean index d1953f609292a9..c587d676d065a0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4440,7 +4440,6 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial -public import Mathlib.Geometry.Manifold.VectorBundle.Extend public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho public import Mathlib.Geometry.Manifold.VectorBundle.Hom diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 17a6bed53a8347..570491ae1e5bb2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -260,7 +260,7 @@ lemma coordChangeL_mem_horiz [FiniteDimensional 𝕜 E] rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] rintro ⟨s, sdiff, sxv, sxuw, covs⟩ use fun x ↦ e.coordChangeL 𝕜 e' x (s x), ?_, ?_, ?_ - · let X := extend E u + · let X := FiberBundle.extend E u -- have hX : MDiffAt (T% X) x := mdifferentiableAt_extend I E u -- TODO: investigate whether the following line comes from inconsistent ways to -- state assumptions diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index d3d5dc8d6f1cc4..ca317eb4b867ed 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -44,7 +44,7 @@ connection. -/ -open Bundle Function NormedSpace +open Bundle FiberBundle Function NormedSpace open scoped Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! @@ -598,7 +598,7 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] ext1 x apply congr_of_forall_product_apply intro Z₀ - simpa [product] using congr($(h (_root_.extend E Z₀)) x) + simpa [product] using congr($(h (extend E Z₀)) x) /-- The Levi-Civita connection on `(M, g)` is uniquely determined, at least on differentiable vector fields. -/ @@ -614,7 +614,7 @@ theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional ℝ E] set Φ := InnerProductSpace.toDual ℝ (TangentSpace I x) apply Φ.injective ext Z₀ - let Z := _root_.extend E Z₀ + let Z := extend E Z₀ have hZ := mdifferentiableAt_extend I E Z₀ suffices inner ℝ (cov Y x (X x)) (Z x) = inner ℝ (cov' Y x (X x)) (Z x) by simpa [Φ, Z] trans leviCivitaRhs I X Y Z x @@ -830,7 +830,7 @@ lemma leviCivitaConnection_torsion_eq_zero [FiniteDimensional ℝ E] : trans (inner ℝ (((LeviCivitaConnection I M) Y x) (X x)) Z) - (inner ℝ (((LeviCivitaConnection I M) X x) (Y x)) Z) · apply inner_sub_left - have hZ' : _root_.extend E Z x = Z := extend_apply_self Z + have hZ' : extend E Z x = Z := extend_apply_self E Z rw [← hZ'] rw [leviCivitaConnection_apply I hY hX (mdifferentiableAt_extend ..)] rw [leviCivitaConnection_apply I hX hY (mdifferentiableAt_extend ..)] @@ -840,7 +840,7 @@ lemma leviCivitaConnection_torsion_eq_zero [FiniteDimensional ℝ E] : simp only [VectorField.mlieBracket_swap (V := Y) (W := X)] simp only [Pi.neg_apply, inner_neg_right, sub_neg_eq_add] set C := inner ℝ Z (VectorField.mlieBracket I X Y x) - set Z' := _root_.extend E Z + set Z' := extend E Z simp only [VectorField.mlieBracket_swap (V := Z') (W := X)] simp only [VectorField.mlieBracket_swap (V := Z') (W := Y)] simp only [Pi.neg_apply, inner_neg_right] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean b/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean deleted file mode 100644 index cf2d9cf66b33ad..00000000000000 --- a/Mathlib/Geometry/Manifold/VectorBundle/Extend.lean +++ /dev/null @@ -1,103 +0,0 @@ -/- -Copyright (c) 2025 Patrick Massot. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang --/ -module - -public import Mathlib.Geometry.Manifold.VectorBundle.Basic -public import Mathlib.Geometry.Manifold.MFDeriv.Basic -import Mathlib.Geometry.Manifold.Notation - -/-! -# Locally extending an element of a vector bundle to a smooth section - -This construction doesn't use bump functions, it just extends naively on a trivialization's domain. -So it is smooth only locally - --/ - -public section - -open Bundle Filter Module Topology Set -open scoped Manifold ContDiff - -section extend - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] - {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - -variable (F : Type*) [NormedAddCommGroup F] - -- `F` model fiber - {V : M → Type*} [TopologicalSpace (TotalSpace F V)] - [∀ x, AddCommGroup (V x)] - [∀ x : M, TopologicalSpace (V x)] - [FiberBundle F V] - -- `V` vector bundle - -open Classical in -/-- Extend a vector `v ∈ V x` to a section of the bundle `V`, whose value at `x` is `v`. -The details of the extension are mostly unspecified: for covariant derivatives, the value of -`s` at points other than `x` will not matter (except for shorter proofs). --/ -noncomputable def extend {x : M} (v₀ : V x) (x' : M) : V x' := - letI t := trivializationAt F V x - letI w : F := (t ⟨x, v₀⟩).2 - t.symm x' w - -variable {I F} in -@[simp] lemma extend_apply_self {x : M} (v : V x) : extend F v x = v := by - simp [extend, FiberBundle.mem_baseSet_trivializationAt' x] - -variable [NormedSpace 𝕜 F] - -lemma exists_contMDiffOn_extend {k} [IsManifold I k M] [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] - [ContMDiffVectorBundle k F V I] {x₀ : M} (σ₀ : V x₀) : - ∃ s ∈ 𝓝 x₀, ContMDiffOn I (I.prod 𝓘(𝕜, F)) k (T% (extend F σ₀)) s := by - set t := trivializationAt F V x₀ - refine ⟨t.baseSet, ?_, ?_⟩ - · refine t.open_baseSet.mem_nhds ?_ - exact FiberBundle.mem_baseSet_trivializationAt' x₀ - suffices ContMDiffOn I 𝓘(𝕜, F) k (fun x ↦ (t ⟨x, extend F σ₀ x⟩).2) t.baseSet by - intro x hx - rw [t.contMDiffWithinAt_section _ hx] - exact this x hx - let w : F := (t ⟨x₀, σ₀⟩).2 - have : ContMDiffOn I 𝓘(𝕜, F) k (fun x_1 ↦ w) t.baseSet := contMDiffOn_const - refine this.congr ?_ - intro x hx - dsimp only - unfold extend - rw [t.mk_symm hx, t.apply_symm_apply' hx] - --- TODO there is a lemma already with this name which should be renamed to something like --- `Chart.contMDiffAt_extend` or `OpenPartialHomeomorph.contMDiffAt_extend` -lemma contMDiffAt_extend' {k} [IsManifold I k M] {x : M} (σ₀ : V x) : - CMDiffAt k (T% (extend F σ₀)) x := by - rw [contMDiffAt_section] - set t := trivializationAt F V x - let w : F := (t ⟨x, σ₀⟩).2 - have : CMDiffAt k (fun (_x : M) ↦ w) x := contMDiffAt_const - refine this.congr_of_eventuallyEq ?_ - apply eventually_nhds_iff.mpr - refine ⟨t.baseSet, ?_, t.open_baseSet, ?_⟩ - · intro x hx - dsimp only - unfold extend - simp [t, hx, w] - · exact FiberBundle.mem_baseSet_trivializationAt' x - -lemma exists_mdifferentiableOn_extend [IsManifold I 1 M] [∀ x, Module 𝕜 (V x)] [VectorBundle 𝕜 F V] - [ContMDiffVectorBundle 1 F V I] {x₀ : M} (σ₀ : V x₀) : - ∃ s ∈ 𝓝 x₀, MDifferentiableOn I (I.prod 𝓘(𝕜, F)) (T% (extend F σ₀)) s := by - obtain ⟨s, hs, hsσ⟩ := exists_contMDiffOn_extend (k := 1) I F σ₀ - exact ⟨s, hs, hsσ.mdifferentiableOn one_ne_zero⟩ - -lemma mdifferentiableAt_extend [IsManifold I 1 M] {x : M} (σ₀ : V x) : - MDiffAt (T% (extend F σ₀)) x := - (contMDiffAt_extend' (k := 1) I F σ₀).mdifferentiableAt one_ne_zero - -end extend diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index f0de414abe2c3e..f5d9b4235f808e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -5,7 +5,8 @@ Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.Extend +public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.MFDeriv.Basic public import Mathlib.Topology.Algebra.Module.FiniteDimensionBilinear import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame From 1f9cd5e154233b254dc0d5e0ad23aaf0b8ac4789 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 8 Mar 2026 13:26:07 +0100 Subject: [PATCH 577/601] Clean up curvature proof; additivity in X almost done --- .../CovariantDerivative/Curvature.lean | 74 +++++++++++-------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean index 3287ded343502e..5ebdf7a65f385b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -111,45 +111,57 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( have hY : CMDiffAt 2 (T% Y) x := sorry have hZ : CMDiff 2 (T% Z) := sorry have hZ' : CMDiffAt 2 (T% Z) x := sorry - rw [hcov.sub] - rotate_left - · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply ContMDiffAt.add_section - · exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - · exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - apply ContMDiffAt.mlieBracket_vectorField (ContMDiff.add_section hσ hσ' ..) hY - simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general k - rw [hcov.sub]; rotate_left - · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - apply ContMDiffAt.mlieBracket_vectorField (hσ x) hY _ - simp; sorry -- same as above - dsimp - erw [hcov.add]; rotate_left - · -- TODO: centralise, same as above! + -- corollaries, which occur as side goals several times + have hZσ : MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (σ x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - · -- TODO: centralise, same as above! + have hZσ' : MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (σ' x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - simp only [ContinuousLinearMap.add_apply] - set C := cov (fun x ↦ (cov Z x) (σ x)) x - set D := cov (fun x ↦ (cov Z x) (σ' x)) x - rw [hcov.sub]; rotate_left - · -- TODO: centralise, same as above! + -- just extracted for readability; could be one common lemma + have hZσY : + MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (VectorField.mlieBracket I σ Y x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - · --- TODO: centralise, same as above! + apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply ContMDiffAt.mlieBracket_vectorField (hσ x) hY _ + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general 𝕜 + have hZσ'Y : + MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (VectorField.mlieBracket I σ' Y x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) apply ContMDiffAt.mlieBracket_vectorField (hσ' x) hY _ - simp; sorry -- same as above - simp - sorry + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general 𝕜 + + have missing : + (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I (σ + σ') Y x)) x) (Y x) = + (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ Y x)) x) (Y x) + + (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ' Y x)) x) (Y x) := by + trans (cov (fun x ↦ ( + cov Z x (VectorField.mlieBracket I σ Y x)) + cov Z x (VectorField.mlieBracket I σ' Y x) + ) x) (Y x) + · congr 1 + sorry -- missing tensoriality lemma; first arguments are equal at x + · erw [hcov.add hZσY hZσ'Y] + simp + rw [hcov.sub] + rotate_left + · exact mdifferentiableAt_add_section hZσ hZσ' + · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply ContMDiffAt.mlieBracket_vectorField (ContMDiff.add_section hσ hσ' ..) hY + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general k + rw [hcov.sub hZσ hZσY] + dsimp + erw [hcov.add hZσ hZσ'] + simp only [ContinuousLinearMap.add_apply] + --set C := cov (fun x ↦ (cov Z x) (σ x)) x + --set D := cov (fun x ↦ (cov Z x) (σ' x)) x + rw [hcov.sub hZσ' hZσ'Y] + rw [missing] + --set E := (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ Y x)) x) (Y x) + dsimp + --set F := (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ' Y x)) x) (Y x) + abel -- update hypotheses to match lemma above, once proven! variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] From d198c1fbbb99409ba22fe70f472a50040b4e74c4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sun, 8 Mar 2026 20:27:05 +0100 Subject: [PATCH 578/601] Further clean-up of additivity proof: extract helper lemma --- .../CovariantDerivative/Curvature.lean | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean index 5ebdf7a65f385b..6acd788c31a7e5 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -83,10 +83,21 @@ lemma temp' -- I suspect this one will also work! - we can only prove tensoriality for C² sections (at a point, I hope! to be confirmed), so need new tensoriality lemmas - `mdifferentiableAt` lemmas for C^k covariant derivatives would be nice API addition -- want more `have`s, and perhaps even more API, around cov applied to the various sections -/ variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] + +lemma aux + (hcov : IsCovariantDerivativeOn E cov) [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + {x : M} {Y Z σ : (x : M) → TangentSpace I x} + -- XXX: after rephrasing hcov', does CMDiffAt 2 (T% Z) x suffice? + (hσ : CMDiffAt 2 (T% σ) x) (hY : CMDiffAt 2 (T% Y) x) (hZ : CMDiff 2 (T% Z)) : + (MDiffAt fun x ↦ TotalSpace.mk' E x ((cov Z x) (VectorField.mlieBracket I σ Y x))) x := by + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply ContMDiffAt.mlieBracket_vectorField hσ hY _ + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general 𝕜 + theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) (x : M) [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] (Y Z : (Π x : M, TangentSpace I x)) : @@ -118,20 +129,6 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( have hZσ' : MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (σ' x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - -- just extracted for readability; could be one common lemma - have hZσY : - MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (VectorField.mlieBracket I σ Y x))) x := by - apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - apply ContMDiffAt.mlieBracket_vectorField (hσ x) hY _ - simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general 𝕜 - have hZσ'Y : - MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (VectorField.mlieBracket I σ' Y x))) x := by - apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) - apply ContMDiffAt.mlieBracket_vectorField (hσ' x) hY _ - simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general 𝕜 - have missing : (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I (σ + σ') Y x)) x) (Y x) = (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ Y x)) x) (Y x) @@ -141,7 +138,7 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( ) x) (Y x) · congr 1 sorry -- missing tensoriality lemma; first arguments are equal at x - · erw [hcov.add hZσY hZσ'Y] + · erw [hcov.add (aux hcov (hσ x) hY hZ) (aux hcov (hσ' x) hY hZ)] simp rw [hcov.sub] rotate_left @@ -150,13 +147,13 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) apply ContMDiffAt.mlieBracket_vectorField (ContMDiff.add_section hσ hσ' ..) hY simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general k - rw [hcov.sub hZσ hZσY] + rw [hcov.sub hZσ (aux hcov (hσ x) hY hZ)] dsimp erw [hcov.add hZσ hZσ'] simp only [ContinuousLinearMap.add_apply] --set C := cov (fun x ↦ (cov Z x) (σ x)) x --set D := cov (fun x ↦ (cov Z x) (σ' x)) x - rw [hcov.sub hZσ' hZσ'Y] + rw [hcov.sub hZσ' ((aux hcov (hσ' x) hY hZ))] rw [missing] --set E := (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ Y x)) x) (Y x) dsimp @@ -164,7 +161,6 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( abel -- update hypotheses to match lemma above, once proven! -variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] theorem curvatureTensorAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) (x : M) [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] (X Z : (Π x : M, TangentSpace I x)) : @@ -173,7 +169,6 @@ theorem curvatureTensorAux_tensorial₂ (hcov : IsCovariantDerivativeOn E cov) ( sorry -- update hypotheses to match lemma above, once proven! -variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] theorem curvatureTensorAux_tensorial₃ (hcov : IsCovariantDerivativeOn E cov) (x : M) [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] (X Y : (Π x : M, TangentSpace I x)) : From 1febf77e2e6b7551bbc8c6e6129031584e9eb50b Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 9 Mar 2026 23:02:58 +0100 Subject: [PATCH 579/601] chore(Ehresmann): remove obsolete section real Nothing in that file is only about real bundles, any more. --- .../VectorBundle/CovariantDerivative/Ehresmann.lean | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 570491ae1e5bb2..0a79551f93bc93 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -25,8 +25,6 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! -section real - variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} @@ -117,8 +115,6 @@ end projection_trivial_bundle end IsCovariantDerivativeOn ---end real - namespace Bundle.Trivialization section to_trivialization @@ -438,8 +434,6 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] end CovariantDerivative end horiz -end real - -- variable (E E') in -- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ -- @[simps] From 0b78020d2b10bbaded76aab48e57c6147570fea1 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 9 Mar 2026 23:16:17 +0100 Subject: [PATCH 580/601] chore(Basic): use WithTop ENat instead --- forward-ports a review adjustment made on the PR branch --- .../CovariantDerivative/Basic.lean | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index fc0e2ec60712aa..99b4bbcf0d1885 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -104,7 +104,7 @@ A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` `C^{k+1}` section, the result `∇_X σ` is a `C^k` section. This is a class so typeclass inference can deduce this automatically. -/ -class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle 𝕜 F V] (k : ℕ∞) +class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle 𝕜 F V] (k : WithTop ℕ∞) (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) (u : Set M) where contMDiff : ∀ {σ : Π x : M, V x}, CMDiff[u] (k + 1) (T% σ) → @@ -116,13 +116,11 @@ variable {F} namespace IsCovariantDerivativeOn --- TODO: prove that `cov σ x` depends on `σ` only via the 1-jet of `σ` at `x`. --- This should be easy using the projection formula in `CovariantDerivative.Ehresmann`. --- In the mean time we use the following weaker result (which is convenient to apply anyway). - set_option backward.isDefEq.respectTransparency false in /-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and -`σ'` agree on `s` and are differentiable at `x`, then `cov σ x = cov σ x'`. -/ +`σ'` agree on `s` and are differentiable at `x`, then `cov σ x = cov σ x'`. + +This is a convenient special case of `congr_of_eq_one_jet`. -/ lemma congr_of_eqOn {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -155,6 +153,18 @@ lemma congr_of_eqOn _ = cov σ' x := by simp [hcov.leibniz hσ' hψ'.mdifferentiableAt, hψx, hψ'.mfderiv] +/-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and +`σ'` are differentiable at `x` with the same one-jet (i.e., agree at `x` and have the same +`mfderiv`), then `cov σ x = cov σ x'`. -/ +lemma congr_of_eq_one_jet + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {x : M} (hxs : s ∈ 𝓝 x) + {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) + (hσσ' : σ x = σ' x) (hσσ' : mfderiv% (T% σ) x = mfderiv% (T% σ') x) : + cov σ x = cov σ' x := by + -- This should be easy using the projection formula in `CovariantDerivative.Ehresmann`. + sorry + /-! ### Changing set In this section, we change `s` in `IsCovariantDerivativeOn F cov s`, proving the condition is @@ -250,7 +260,7 @@ lemma affine_combination (hcov : IsCovariantDerivativeOn F cov s) lemma _root_.ContMDiffCovariantDerivativeOn.affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] {cov cov' : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} - {u: Set M} {f : M → 𝕜} {n : ℕ∞} (hf : CMDiff[u] n f) + {u: Set M} {f : M → 𝕜} {n : WithTop ℕ∞} (hf : CMDiff[u] n f) (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : ContMDiffCovariantDerivativeOn F n (fun σ ↦ (f • (cov σ)) + (1 - f) • (cov' σ)) u where @@ -282,8 +292,8 @@ lemma finite_affine_combination {ι : Type*} {s : Finset ι} [Nonempty s] _ = g x • ∑ i ∈ s, f i x • cov i σ x + B := by rw [hf]; simp /-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ -lemma _root_.ContMDiffCovariantDerivativeOn.finite_affine_combination [IsManifold I 1 M] {n : ℕ∞} - [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} +lemma _root_.ContMDiffCovariantDerivativeOn.finite_affine_combination [IsManifold I 1 M] + {n : WithTop ℕ∞} [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} {u : Set M} {cov : ι → (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : ∀ i ∈ s, ContMDiffCovariantDerivativeOn F n (cov i) u) {f : ι → M → 𝕜} (hf : ∀ i ∈ s, CMDiff[u] n (f i)) : @@ -422,12 +432,12 @@ A covariant derivative ∇ is called of class `C^k` iff, whenever `X` is a `C^k` This is a class so typeclass inference can deduce this automatically. -/ class ContMDiffCovariantDerivative [IsManifold I 1 M] [VectorBundle 𝕜 F V] - (cov : CovariantDerivative I F V) (k : ℕ∞) where + (cov : CovariantDerivative I F V) (k : WithTop ℕ∞) where contMDiff : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ @[simp] lemma contMDiffCovariantDerivativeOn_univ_iff [IsManifold I 1 M] [VectorBundle 𝕜 F V] - {cov : CovariantDerivative I F V} {k : ℕ∞} : + {cov : CovariantDerivative I F V} {k : WithTop ℕ∞} : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ ↔ ContMDiffCovariantDerivative cov k := ⟨fun h ↦ ⟨h⟩, fun h ↦ h.contMDiff⟩ @@ -475,7 +485,7 @@ lemma ContMDiffCovariantDerivative.affine_combination [IsManifold I 1 M] [Vector /-- An affine combination of finitely many `C^k` connections is a `C^k` connection. -/ lemma ContMDiffCovariantDerivative.finite_affine_combination [IsManifold I 1 M] [VectorBundle 𝕜 F V] {ι : Type*} {s : Finset ι} [Nonempty s] - (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : ℕ∞} + (cov : ι → CovariantDerivative I F V) {f : ι → M → 𝕜} (hf : ∑ i ∈ s, f i = 1) {n : WithTop ℕ∞} (hf' : ∀ i ∈ s, ContMDiff I 𝓘(𝕜) n (f i)) (hcov : ∀ i ∈ s, ContMDiffCovariantDerivative (cov i) n) : ContMDiffCovariantDerivative (finite_affine_combination cov hf) n where From 1d5103ab1be7c276779f90798f942faf95c13c66 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 9 Mar 2026 21:51:23 +0100 Subject: [PATCH 581/601] wip(Curvature): indicate how global hypotheses on differentiability are hopefully not necessary --- .../CovariantDerivative/Curvature.lean | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean index 6acd788c31a7e5..42d0603af353e2 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -29,6 +29,48 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} +/-! A preliminary lemma about -/ +section prelim + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] + {V : M → Type*} [TopologicalSpace (TotalSpace F V)] + [∀ x, AddCommGroup (V x)] [∀ x, Module 𝕜 (V x)] + [∀ x : M, TopologicalSpace (V x)] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + [FiberBundle F V] + +-- FIXME: does this require real bundles? +lemma exists_contMDiff_of_one_form {k : WithTop ℕ∞} + {σ : Π x : M, V x} (hσ : CMDiffAt k (T% σ) x) : + ∃ σ' : (Π x : M, V x), + CMDiff k (T% σ') ∧ σ' x = σ x ∧ mfderiv% (T% σ') x = mfderiv% (T% σ) x := by + /- proof idea: assuming smooth bump functions, this becomes a local question + locally, convolve σ with a bump function of small support; should preserve σ x and mfderiv + does mathlib have this already? (Moritz Doll proved something similar, I think!) + -/ + sorry + +-- We need one level more of agreement! + +-- TODO: might be a better definition of smoothness; proving the equivalence requires more work! +variable {F} in +lemma ContMDiffCovariantDerivativeOn.contMDiff' [IsManifold I 1 M] [VectorBundle 𝕜 F V] + {k : WithTop ℕ∞} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + (hcov : IsCovariantDerivativeOn F cov) [hcov' : ContMDiffCovariantDerivativeOn F k cov univ] + {σ : Π x : M, V x} (hσ :CMDiffAt (k + 1) (T% σ) x) : + letI cov (x : M) : TotalSpace (E →L[𝕜] F) fun x ↦ TangentSpace I x →L[𝕜] V x := ⟨x, cov σ x⟩ + ContMDiffAt I (I.prod 𝓘(𝕜, E →L[𝕜] F)) k cov x := by + obtain ⟨σ', hσ', heqs, hdiffx⟩ := exists_contMDiff_of_one_form F hσ + have aux := contMDiffOn_univ.mp (hcov'.contMDiff hσ'.contMDiffOn) + -- know: ∇ σ and ∇ σ' agree at x + have aux' := hcov.congr_of_eq_one_jet (Filter.univ_mem) + (hσ.mdifferentiableAt (by simp)) (hσ'.mdifferentiableAt (by simp)) + heqs.symm hdiffx.symm -- TODO: choose direction for both equalities! + -- we need one more level, though! + sorry + +end prelim + /-! ## Curvature tensor of an unbundled covariant derivative on `TM` on a set `s` -/ namespace IsCovariantDerivativeOn @@ -90,11 +132,10 @@ variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness 𝕜 2) M] lemma aux (hcov : IsCovariantDerivativeOn E cov) [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] {x : M} {Y Z σ : (x : M) → TangentSpace I x} - -- XXX: after rephrasing hcov', does CMDiffAt 2 (T% Z) x suffice? - (hσ : CMDiffAt 2 (T% σ) x) (hY : CMDiffAt 2 (T% Y) x) (hZ : CMDiff 2 (T% Z)) : + (hσ : CMDiffAt 2 (T% σ) x) (hY : CMDiffAt 2 (T% Y) x) (hZ : CMDiffAt 2 (T% Z) x) : (MDiffAt fun x ↦ TotalSpace.mk' E x ((cov Z x) (VectorField.mlieBracket I σ Y x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply temp' hcov ?_ (hcov'.contMDiff' hcov hZ) apply ContMDiffAt.mlieBracket_vectorField hσ hY _ simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general 𝕜 @@ -125,10 +166,10 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( -- corollaries, which occur as side goals several times have hZσ : MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (σ x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - exact temp hcov hσ hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + exact temp hcov hσ hZ (hcov'.contMDiff' hcov hZ') have hZσ' : MDiffAt (fun x ↦ TotalSpace.mk' E x (cov Z x (σ' x))) x := by apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - exact temp hcov hσ' hZ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + exact temp hcov hσ' hZ (hcov'.contMDiff' hcov hZ') have missing : (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I (σ + σ') Y x)) x) (Y x) = (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ Y x)) x) (Y x) @@ -138,22 +179,22 @@ theorem curvatureTensorAux_tensorial₁ (hcov : IsCovariantDerivativeOn E cov) ( ) x) (Y x) · congr 1 sorry -- missing tensoriality lemma; first arguments are equal at x - · erw [hcov.add (aux hcov (hσ x) hY hZ) (aux hcov (hσ' x) hY hZ)] + · erw [hcov.add (aux hcov (hσ x) hY hZ') (aux hcov (hσ' x) hY hZ')] simp rw [hcov.sub] rotate_left · exact mdifferentiableAt_add_section hZσ hZσ' · apply ContMDiffAt.mdifferentiableAt _ one_ne_zero - apply temp' hcov ?_ ((hcov'.contMDiff hZ.contMDiffOn).contMDiffAt (by simp)) + apply temp' hcov ?_ (hcov'.contMDiff' hcov hZ') apply ContMDiffAt.mlieBracket_vectorField (ContMDiff.add_section hσ hσ' ..) hY simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general k - rw [hcov.sub hZσ (aux hcov (hσ x) hY hZ)] + rw [hcov.sub hZσ (aux hcov (hσ x) hY hZ')] dsimp erw [hcov.add hZσ hZσ'] simp only [ContinuousLinearMap.add_apply] --set C := cov (fun x ↦ (cov Z x) (σ x)) x --set D := cov (fun x ↦ (cov Z x) (σ' x)) x - rw [hcov.sub hZσ' ((aux hcov (hσ' x) hY hZ))] + rw [hcov.sub hZσ' ((aux hcov (hσ' x) hY hZ'))] rw [missing] --set E := (cov (fun x ↦ (cov Z x) (VectorField.mlieBracket I σ Y x)) x) (Y x) dsimp From d39526c377f1f60b8e5a51eaebc744514e0b166e Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 14 Mar 2026 10:22:49 +0100 Subject: [PATCH 582/601] golf(CovariantDerivative): re-use existing result; use fromNormedSpace slightly more; golf proof --- .../CovariantDerivative/Trivial.lean | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index f00e64ed46bd72..e03afa39307870 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -15,15 +15,13 @@ Don't be afraid to ask. TODO! -/ -open Bundle +open Bundle Filter Module NormedSpace Topology Set open scoped Manifold ContDiff variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -open Bundle Filter Module Topology Set - variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] @@ -42,21 +40,18 @@ set_option backward.isDefEq.respectTransparency false in variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : - IsCovariantDerivativeOn F (V := Trivial M F) - (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where - add {σ σ' x} hσ hσ' hx := by + IsCovariantDerivativeOn F (V := Trivial M F) (fun s x ↦ mfderiv I 𝓘(𝕜, F) s x) univ where + add hσ hσ' hx := by rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' rw [mfderiv_add hσ hσ'] - leibniz {σ f x} hσ hf hx := by + leibniz hσ hf hx := by rw [mdifferentiableAt_section] at hσ ext1 X₀ exact fromTangentSpace_mfderiv_smul_apply hf hσ X₀ lemma of_endomorphism (A : (x : M) → F →L[𝕜] TangentSpace I x →L[𝕜] F) : IsCovariantDerivativeOn F - (fun (s : M → F) x ↦ - letI d : TangentSpace I x →L[𝕜] F := mfderiv I 𝓘(𝕜, F) s x - d + A x (s x)) univ := + (fun (s : M → F) x ↦ (fromTangentSpace (𝕜 := 𝕜) (s x) ∘L mfderiv% s x) + A x (s x)) univ := trivial I M F |>.add_one_form A end trivial_bundle @@ -67,19 +62,11 @@ namespace CovariantDerivative section trivial_bundle -set_option backward.isDefEq.respectTransparency false in variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where toFun s x := mfderiv I 𝓘(𝕜, F) s x - isCovariantDerivativeOnUniv := -- TODO use previous work - { add {σ σ' x} hσ hσ' hx := by - rw [mdifferentiableAt_section_trivial_iff] at hσ hσ' - rw [mfderiv_add hσ hσ'] - leibniz {σ f x} hσ hf hx := by - rw [mdifferentiableAt_section] at hσ - ext1 X₀ - exact fromTangentSpace_mfderiv_smul_apply hf hσ X₀ } + isCovariantDerivativeOnUniv := IsCovariantDerivativeOn.trivial .. end trivial_bundle @@ -119,8 +106,8 @@ noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : toFun σ := fun x ↦ fderiv 𝕜 σ x + A x (σ x) isCovariantDerivativeOnUniv := by convert IsCovariantDerivativeOn.of_endomorphism (I := 𝓘(𝕜, E)) A - ext f x v - rw [mfderiv_eq_fderiv] + simp [mfderiv_eq_fderiv, NormedSpace.fromTangentSpace] + rfl end CovariantDerivative From 5b0d3a901c4dda73d7f4f0d2173a3744a1a8dc1e Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 17 Mar 2026 13:00:15 +0100 Subject: [PATCH 583/601] feat: Relax type class assumption on T% elaborator --- Mathlib/Geometry/Manifold/Notation.lean | 47 ++++++++++++++----- .../DifferentialGeometry/Notation/Basic.lean | 17 +++++-- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/Mathlib/Geometry/Manifold/Notation.lean b/Mathlib/Geometry/Manifold/Notation.lean index f6f6ef9c07f57f..33140d63bd70dd 100644 --- a/Mathlib/Geometry/Manifold/Notation.lean +++ b/Mathlib/Geometry/Manifold/Notation.lean @@ -121,6 +121,39 @@ private def findSomeLocalHyp? {α} (p : Expr → Expr → MetaM (Option α)) : M let type ← whnfR <| ← instantiateMVars decl.type p decl.toExpr type +/-- Given `V : Expr` representing `E : B → Type*`, try to find a model fiber for `E` +by searching in local context for either a `FiberBundle F E` instance or +`TopologicalSpace (TotalSpace F E)`. We could try a more systematic search of +`TotalSpace F E` anywhere in the local context, but the current heuristic is faster +and sufficient so far. -/ +private def findModelFiber? (V : Expr) : MetaM (Option Expr) := do + withTraceNode `Elab.DiffGeo.TotalSpaceMk + (fun _ ↦ do return m!"Searching for a model fiber for {← ppExpr V}") do + trace[Elab.DiffGeo.TotalSpaceMk] "Searching for relevant `FiberBundle` instance in context " + let f? ← findSomeLocalInstanceOf? `FiberBundle fun _ declType ↦ do + /- Note: we do not use `match_expr` here since that would require importing + `Mathlib.Topology.FiberBundle.Basic` to resolve `FiberBundle`. -/ + match declType with + | mkApp7 (.const `FiberBundle _) _ F _ _ E _ _ => do + if ← withReducible (pureIsDefEq E V) then + trace[Elab.DiffGeo.TotalSpaceMk] "It worked! model fiber is {← ppExpr F}" + return some F + else return none + | _ => return none + if f?.isSome then + return f? + else + trace[Elab.DiffGeo.TotalSpaceMk] "Could not find a relevant `FiberBundle` instance in context " + trace[Elab.DiffGeo.TotalSpaceMk] "Searching for a relevant \ + `TopologicalSpace (Bundle.TotalSpace _ _)` instance in context" + return ← findSomeLocalInstanceOf? `TopologicalSpace fun _ declType ↦ do + match declType with + | mkApp (.const `TopologicalSpace _) (mkApp3 (.const `Bundle.TotalSpace _) _ F E) => do + if ← withReducible (pureIsDefEq E V) then + trace[Elab.DiffGeo.TotalSpaceMk] "It worked! model fiber is {← ppExpr F}" + return some F + else return none + | _ => return none /-- Utility for sections in a fibre bundle: if an expression `e` is a section `s : Π x : M, V x` as a dependent function, convert it to a non-dependent function into the total @@ -162,18 +195,10 @@ def totalSpaceMk (e : Expr) : MetaM Expr := do | _ => match (← instantiateMVars tgt).cleanupAnnotations with | .app V _ => trace[Elab.DiffGeo.TotalSpaceMk] "Section of a bundle as a dependent function" - let f? ← findSomeLocalInstanceOf? `FiberBundle fun _ declType ↦ - /- Note: we do not use `match_expr` here since that would require importing - `Mathlib.Topology.FiberBundle.Basic` to resolve `FiberBundle`. -/ - match declType with - | mkApp7 (.const `FiberBundle _) _ F _ _ E _ _ => do - if ← withReducible (pureIsDefEq E V) then + match ← findModelFiber? V with + | some F => let body ← mkAppM ``Bundle.TotalSpace.mk' #[F, x, (e.app x).headBeta] - some <$> mkLambdaFVars #[x] body - else return none - | _ => return none - match f? with - | some e => return e.headBeta + return (← mkLambdaFVars #[x] body).headBeta | none => -- future: special-case `Bundle.TotalSpace` for V; -- if so, say "there is no need to apply T% twice" diff --git a/MathlibTest/DifferentialGeometry/Notation/Basic.lean b/MathlibTest/DifferentialGeometry/Notation/Basic.lean index b0500179483543..a1257b0394cb8d 100644 --- a/MathlibTest/DifferentialGeometry/Notation/Basic.lean +++ b/MathlibTest/DifferentialGeometry/Notation/Basic.lean @@ -154,15 +154,22 @@ hint: you may be missing suitable typeclass assumptions #guard_msgs in #check (T% (T% X)) x +section +-- Check minimal assumptions to find a model fiber. + +variable {B F Z : Type*} [TopologicalSpace B] [TopologicalSpace F] + {E : B → Type*} [TopologicalSpace (TotalSpace F E)] (σ : (b : B) → E b) +/-- info: fun b ↦ ⟨b, σ b⟩ : B → TotalSpace F E -/ +#guard_msgs in +#check T% σ + +end -- Error message when missing typeclass assumptions for sections of a fiber bundle. -- This used to silently do nothing; now there is a helpful error. section variable {B F Z : Type*} [TopologicalSpace B] [TopologicalSpace F] - {E : B → Type*} [TopologicalSpace (TotalSpace F E)] - (e : Trivialization F (π F E)) [(x : B) → Zero (E x)] - -variable (σ : (b : B) → E b) in + {E : B → Type*} (σ : (b : B) → E b) /-- error: could not find a `FiberBundle` instance on `E`: `σ` is a function into `E` @@ -174,7 +181,7 @@ hint: you may be missing suitable typeclass assumptions /-- info: fun b ↦ ⟨b, σ b⟩ : B → TotalSpace F E -/ #guard_msgs in -variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] (σ : (b : B) → E b) in +variable [TopologicalSpace (TotalSpace F E)] [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] in #check T% σ end From e7b1409a54836fa3536b3bad6e4239ff571eb01f Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 14:49:16 +0100 Subject: [PATCH 584/601] feat: skeleton for 3-tensors --- .../Manifold/VectorBundle/Tensoriality.lean | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index f5d9b4235f808e..ddf5a6530fca6c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -57,6 +57,12 @@ variable [∀ x, AddCommGroup (V' x)] [∀ x, Module 𝕜 (V' x)] [∀ x : M, TopologicalSpace (V' x)] [FiberBundle F' V'] +variable + (F'' : Type*) [NormedAddCommGroup F''] [NormedSpace 𝕜 F''] + {V'' : M → Type*} [TopologicalSpace (TotalSpace F'' V'')] + [∀ x, AddCommGroup (V'' x)] [∀ x, Module 𝕜 (V'' x)] [∀ x : M, TopologicalSpace (V'' x)] + [FiberBundle F'' V''] + variable {A : Type*} [AddCommGroup A] [Module 𝕜 A] /-- An operation `Φ` on sections of a vector bundle `V` over `M` is *tensorial* at `x : M`, if it @@ -66,7 +72,7 @@ structure TensorialAt (Φ : (Π x : M, V x) → A) (x : M) : Prop where add : ∀ {σ σ'}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → Φ (σ + σ') = Φ σ + Φ σ' variable {Φ : (Π x : M, V x) → A} {x : M} -variable {I F F'} +variable {I F F' F''} namespace TensorialAt @@ -100,7 +106,7 @@ protected theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x _ = Φ (ψ • σ') := by rw [funext this] _ = Φ σ' := by simp [hΦ.smul hψ' hσ', hψx] -variable [VectorBundle 𝕜 F V] [VectorBundle 𝕜 F' V'] +variable [VectorBundle 𝕜 F V] [VectorBundle 𝕜 F' V'] [VectorBundle 𝕜 F'' V''] /-- A tensorial operation on sections of a vector bundle respects sums (since it respects binary addition). -/ @@ -121,8 +127,10 @@ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι simp only [Finset.sum_insert ha, ← h] exact hΦ.add (hσ a) (.sum_section hσ) -variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 F'] +variable [CompleteSpace 𝕜] + [FiniteDimensional 𝕜 F] [FiniteDimensional 𝕜 F'] [FiniteDimensional 𝕜 F''] [ContMDiffVectorBundle 1 F V I] [ContMDiffVectorBundle 1 F' V' I] + [ContMDiffVectorBundle 1 F'' V'' I] /-- If the operation `Φ` on sections of a vector bundle `V` is tensorial at `x`, then it depends only on the value of the section at `x`. -/ @@ -177,11 +185,12 @@ lemma pointwise₂ variable -- TODO prove transport lemmas `ContinuousLinearEquiv.IsTopologicalAddGroup` and - -- `ContinuousLinearEquiv.continuousSMul`, then the next four hypotheses can be removed + -- `ContinuousLinearEquiv.continuousSMul`, then the next six hypotheses can be removed -- (and the appropriate instances constructed in the proof of `TensorialAt.mkHom` by transport -- from the model fibre.) [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [∀ x, IsTopologicalAddGroup (V' x)] [∀ x, ContinuousSMul 𝕜 (V' x)] + [∀ x, IsTopologicalAddGroup (V'' x)] [∀ x, ContinuousSMul 𝕜 (V'' x)] [TopologicalSpace A] [IsTopologicalAddGroup A] [ContinuousSMul 𝕜 A] /-- Given an `A`-valued operation `Φ` on sections of a vector bundle `V` which is tensorial at `x`, @@ -291,4 +300,38 @@ theorem mkHom₂_apply_eq_extend mkHom₂ Φ x hΦ₁ hΦ₂ σ τ = Φ (FiberBundle.extend F σ) (FiberBundle.extend F' τ) := rfl +/-- Given an `A`-valued operation `Φ` on sections of vector bundles `V`, `V'` and `V''` which is +tensorial at `x` in each argument, the construction `TensorialAt.mkHom₃` provides the associated +continuous linear map `V x →L[𝕜] V' x →L[𝕜] V'' x →L[𝕜] A`. -/ +noncomputable def mkHom₃ + -- `Φ` and `x` explicit to make it easier to generate the side conditions at point of use + (Φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x : M, V'' x) → A) (x : M) + -- TODO: may require further differentiability conditions here, or not! + -- if so, propagate down below + (hΦ₁ : ∀ τ τ', MDiffAt (T% τ) x → TensorialAt I F (Φ · τ τ') x) + (hΦ₂ : ∀ σ τ', MDiffAt (T% σ) x → TensorialAt I F' (Φ σ · τ') x) + (hΦ₃ : ∀ σ τ, MDiffAt (T% σ) x → TensorialAt I F'' (Φ σ τ ·) x) : + V x →L[𝕜] V' x →L[𝕜] V'' x →L[𝕜] A := + sorry -- TODO: prove mutatis mutandis + +theorem mkHom₃_apply + {Φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x : M, V'' x) → A} {x} + (hΦ₁ : ∀ τ τ', MDiffAt (T% τ) x → TensorialAt I F (Φ · τ τ') x) + (hΦ₂ : ∀ σ τ', MDiffAt (T% σ) x → TensorialAt I F' (Φ σ · τ') x) + (hΦ₃ : ∀ σ τ, MDiffAt (T% σ) x → TensorialAt I F'' (Φ σ τ ·) x) + {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) + {τ' : Π x : M, V'' x} (hτ : MDiffAt (T% τ') x) : + mkHom₃ Φ x hΦ₁ hΦ₂ hΦ₃ (σ x) (τ x) (τ' x) = Φ σ τ τ' := + sorry -- mkHom₂_apply mutatis mutandis + +theorem mkHom₃_apply_eq_extend + {Φ : (Π x : M, V x) → (Π x : M, V' x) → (Π x : M, V'' x) → A} {x} + (hΦ₁ : ∀ τ τ', MDiffAt (T% τ) x → TensorialAt I F (Φ · τ τ') x) + (hΦ₂ : ∀ σ τ', MDiffAt (T% σ) x → TensorialAt I F' (Φ σ · τ') x) + (hΦ₃ : ∀ σ τ, MDiffAt (T% σ) x → TensorialAt I F'' (Φ σ τ ·) x) + (σ : V x) (τ : V' x) (τ' : V'' x) : + mkHom₃ Φ x hΦ₁ hΦ₂ hΦ₃ σ τ τ' = + Φ (FiberBundle.extend F σ) (FiberBundle.extend F' τ) (FiberBundle.extend F'' τ') := + sorry -- once the above proofs are filled in, this should be try by `rfl` + end TensorialAt From c35486ac248a00abaab50d83a3fbb01424c39822 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 15:37:46 +0100 Subject: [PATCH 585/601] feat: skeleton for Ricci and scalar curvature --- .../CovariantDerivative/Curvature.lean | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean index 42d0603af353e2..ed040d3b593566 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -7,6 +7,7 @@ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.LinearAlgebra.Trace /-! # Curvature of an affine connection @@ -71,7 +72,10 @@ lemma ContMDiffCovariantDerivativeOn.contMDiff' [IsManifold I 1 M] [VectorBundle end prelim -/-! ## Curvature tensor of an unbundled covariant derivative on `TM` on a set `s` -/ +/-! ## The Riemannian curvature tensor of an unbundled covariant derivative on `TM` on a set `s` + +TODO: generalise this discussion to any vector bundle E +-/ namespace IsCovariantDerivativeOn variable (cov : (Π x : M, TangentSpace I x) → (Π x : M, TangentSpace I x →L[𝕜] TangentSpace I x)) @@ -217,4 +221,59 @@ theorem curvatureTensorAux_tensorial₃ (hcov : IsCovariantDerivativeOn E cov) ( -- linearity should be "easy" also, scalar multiplication is a different proof sorry +noncomputable section + +/-- The Riemannian curvature endomorphism `R`, as a (3,1)-tensor field: for vector fields `X`, `Y` +and `Z`, it is defined as `R(X, Y)Z = ∇_X (∇_Y Z) - ∇_Y (∇_X Z) - ∇_[X,Y] Z`. -/ +-- This definition follows Lee's sign conventions. +-- TODO: decide if we want this one, and add a comment accordingly! +def curvatureEndomorphismTensor (hcov : IsCovariantDerivativeOn E cov) (x : M) + [ContMDiffCovariantDerivativeOn E 1 cov univ] : + TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x →L[𝕜] TangentSpace I x := + TensorialAt.mkHom₃ (curvatureTensorAux cov · · · x) x + (fun σ τ _ ↦ hcov.curvatureTensorAux_tensorial₁ x σ τ) + (fun σ τ _ ↦ hcov.curvatureTensorAux_tensorial₂ x σ τ) + (fun σ τ _ ↦ hcov.curvatureTensorAux_tensorial₃ x σ τ) + +variable [ContMDiffCovariantDerivativeOn E 1 cov univ] + +-- lemmas: curvatureEndomorphismTensor_apply and curvatureEndomorphismTensor_apply_extend + +variable (X) in +@[simp] +lemma curvatureEndomorphismTensor_self (hcov : IsCovariantDerivativeOn E cov) + (X₀ : TangentSpace I x) : + hcov.curvatureEndomorphismTensor x X₀ X₀ = 0 := by + sorry + +variable (X Y) in +lemma curvatureEndomorphismTensor_swap (hcov : IsCovariantDerivativeOn E cov) + (X₀ Y₀ : TangentSpace I x) : + hcov.curvatureEndomorphismTensor x X₀ Y₀ = - hcov.curvatureEndomorphismTensor x Y₀ X₀ := by + sorry + +-- lemma: if cov is the Levi-Civita connection, we have + = 0 +-- for all vector fields V, X, Y and Z. + +-- The Ricci curvature is the trace of this linear map +def ricciCurvatureAux (hcov : IsCovariantDerivativeOn E cov) (x : M) (Y Z : TangentSpace I x) : + TangentSpace I x →L[𝕜] TangentSpace I x where + toFun := fun X₀ ↦ curvatureEndomorphismTensor hcov x X₀ Y Z + map_add' X₀ X₁ := by simp + map_smul' a X₀ := by simp + +def RicciCurvatureFun (hcov : IsCovariantDerivativeOn E cov) (x : M) : + TangentSpace I x → TangentSpace I x → 𝕜 := + fun Y Z ↦ LinearMap.trace 𝕜 _ (ricciCurvatureAux hcov x Y Z).toLinearMap + +def RicciCurvature (hcov : IsCovariantDerivativeOn E cov) (x : M) : + TangentSpace I x →L[𝕜] TangentSpace I x → 𝕜 := + sorry -- apply tensoriality criterion, again + +-- most conceptual proof: define the contraction of a tensor and show it is still a tensor + +-- scalar curvature left to the reader + +end + end IsCovariantDerivativeOn From 66a132419bea39893314cb54732ccca2fa5540c4 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 17:46:40 +0100 Subject: [PATCH 586/601] Revert spurious diff; small tweak --- Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean | 4 ++-- Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index 1567d40925322e..a704dd982a283b 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -81,6 +81,8 @@ theorem Differentiable.comp_mdifferentiable {g : F → F'} {f : M → F} (hg : Differentiable 𝕜 g) (hf : MDiff f) : MDiff (g ∘ f) := fun x ↦ hg.differentiableAt.comp_mdifferentiableAt (hf x) +end Module + section extChartAt variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] {f : M → F} @@ -101,8 +103,6 @@ theorem DifferentiableWithinAt.mdifferentiableWithinAt_of_comp_extChartAt_symm [ end extChartAt -end Module - /-! ### Linear maps between normed spaces are differentiable -/ theorem MDifferentiableWithinAt.clm_precomp {f : M → F₁ →L[𝕜] F₂} {s : Set M} {x : M} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 780932aab134e2..9eaa0acf875db6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -6,7 +6,6 @@ Authors: Sébastien Gouëzel, Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.VectorBundle.Basic -public import Mathlib.Geometry.Manifold.Algebra.Monoid public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions import Mathlib.Geometry.Manifold.Notation @@ -18,9 +17,8 @@ import Mathlib.Geometry.Manifold.Notation public section -open Bundle Set OpenPartialHomeomorph ContinuousLinearMap Pretrivialization Filter - -open scoped Manifold Bundle Topology +open Bundle Set ContinuousLinearMap Pretrivialization Filter +open scoped Manifold Topology section From e84416aa525c29b35e9e43c705142d38bc539780 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 17:50:34 +0100 Subject: [PATCH 587/601] Fix bad merge in Tensoriality --- .../Manifold/VectorBundle/Tensoriality.lean | 132 ++++++++---------- 1 file changed, 60 insertions(+), 72 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index ddf5a6530fca6c..780ae1282c7f92 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -5,9 +5,10 @@ Authors: Patrick Massot, Michael Rothgang, Heather Macbeth -/ module -public import Mathlib.Geometry.Manifold.VectorBundle.Basic -public import Mathlib.Geometry.Manifold.MFDeriv.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable public import Mathlib.Topology.Algebra.Module.FiniteDimensionBilinear +public import Mathlib.Topology.VectorBundle.FiniteDimensional +import Mathlib.Geometry.Manifold.Notation import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame /-! @@ -33,7 +34,7 @@ fibre `W x`), the construction produces a continuous linear map `V x →L[𝕜] arguments defines a continuous bilinear map out of `V x` and `V' x`. -/ -open Bundle Topology Module +open Bundle FiberBundle Topology Module open scoped Manifold ContDiff @@ -66,7 +67,7 @@ variable variable {A : Type*} [AddCommGroup A] [Module 𝕜 A] /-- An operation `Φ` on sections of a vector bundle `V` over `M` is *tensorial* at `x : M`, if it -respects addition and scalar multiplication by germs of diffentiable functions at `f`. -/ +respects addition and scalar multiplication by germs of differentiable functions at `f`. -/ structure TensorialAt (Φ : (Π x : M, V x) → A) (x : M) : Prop where smul : ∀ {f : M → 𝕜} {σ : Π x : M, V x}, MDiffAt f x → MDiffAt (T% σ) x → Φ (f • σ) = f x • Φ σ add : ∀ {σ σ'}, MDiffAt (T% σ) x → MDiffAt (T% σ') x → Φ (σ + σ') = Φ σ + Φ σ' @@ -85,22 +86,16 @@ protected theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hσσ' : ∀ᶠ x' in 𝓝 x, σ x' = σ' x') : Φ σ = Φ σ' := by classical - rw [eventually_nhds_iff] at hσσ' -- Introduce the indicator function of a neighbourhood `t` of `x` on which equality holds, -- and cut off the two sections `σ` and `σ'` using this indicator function. - obtain ⟨t, htσσ', ht, hxt⟩ := hσσ' - let ψ (x' : M) : 𝕜 := if x' ∈ t then 1 else 0 - have hψx : ψ x = 1 := by simp [ψ, hxt] + let ψ (x' : M) : 𝕜 := if σ x' = σ' x' then 1 else 0 + have hψx : ψ x = 1 := by simp [ψ, hσσ'.self_of_nhds] have (x' : M) : (ψ • σ) x' = (ψ • σ') x' := by dsimp [ψ] - split_ifs with hx't - · simpa using htσσ' _ hx't - · simp + split_ifs with hx' <;> simp [hx'] have hψ' : MDiffAt ψ x := by have : MDiffAt (fun (_x : M) ↦ (1 : 𝕜)) x := mdifferentiableAt_const - refine this.congr_of_eventuallyEq ?_ - apply eventually_nhds_iff.mpr - exact ⟨t, by simp [ψ], ht, hxt⟩ + exact this.congr_of_eventuallyEq (hσσ'.mono fun x' hx' ↦ by simp [ψ, hx']) calc Φ σ _ = Φ (ψ • σ) := by simp [hΦ.smul hψ' hσ, hψx] _ = Φ (ψ • σ') := by rw [funext this] @@ -108,6 +103,14 @@ protected theorem «local» (hΦ : TensorialAt I F Φ x) {σ σ' : Π x : M, V x variable [VectorBundle 𝕜 F V] [VectorBundle 𝕜 F' V'] [VectorBundle 𝕜 F'' V''] +/-- A tensorial operation on sections of a vector bundle respects zero (since it respects scalar + multiplication). -/ +theorem zero (hΦ : TensorialAt I F Φ x) : Φ 0 = 0 := by + calc + Φ 0 = Φ ((0 : M → 𝕜) • (0 : Π x, V x)) := by simp + _ = 0 • Φ 0 := hΦ.smul mdifferentiableAt_const (mdifferentiable_zeroSection ..) + _ = 0 := by simp + /-- A tensorial operation on sections of a vector bundle respects sums (since it respects binary addition). -/ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι → Π x : M, V x) @@ -116,14 +119,9 @@ theorem sum (hΦ : TensorialAt I F Φ x) {ι : Type*} {s : Finset ι} (σ : ι classical induction s using Finset.induction_on with | empty => - simp only [Finset.sum_empty] - have h₁ : MDiffAt (fun x' : M ↦ (0 : 𝕜)) x := mdifferentiableAt_const - rw [show (fun x' : M ↦ (0 : V x')) = (0 : M → 𝕜) • fun x' ↦ 0 by simp; rfl, hΦ.smul] - · simp - · exact h₁ - · exact mdifferentiable_zeroSection .. + rw [Finset.sum_empty] + exact hΦ.zero | insert a s ha h => - change Φ (fun x' : M ↦ ∑ i ∈ (insert a s : Finset ι), σ i x') = _ simp only [Finset.sum_insert ha, ← h] exact hΦ.add (hσ a) (.sum_section hσ) @@ -197,36 +195,31 @@ variable the construction `TensorialAt.mkHom` provides the associated continuous linear map `V x →L[𝕜] A`. -/ noncomputable def mkHom -- `Φ` and `x` explicit to make it easier to generate the side condition at point of use - (Φ : (Π x : M, V x) → A) (x : M) (hΦ : TensorialAt I F (Φ) x) : + (Φ : (Π x : M, V x) → A) (x : M) (hΦ : TensorialAt I F Φ x) : V x →L[𝕜] A := - let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional + have : T2Space (V x) := FiberBundle.t2Space F V x + have : FiniteDimensional 𝕜 (V x) := VectorBundle.finiteDimensional 𝕜 F V x LinearMap.toContinuousLinearMap { - toFun v := Φ (FiberBundle.extend F v) + toFun v := Φ (extend F v) map_add' v₁ v₂ := by - rw [← hΦ.add (FiberBundle.mdifferentiableAt_extend ..) - (FiberBundle.mdifferentiableAt_extend ..)] - apply hΦ.pointwise (FiberBundle.mdifferentiableAt_extend ..) <| - mdifferentiableAt_add_section (FiberBundle.mdifferentiableAt_extend ..) - (FiberBundle.mdifferentiableAt_extend ..) + rw [← hΦ.add (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..)] + apply hΦ.pointwise (mdifferentiableAt_extend ..) <| + mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) simp map_smul' c v := by dsimp - rw [← hΦ.smul (f := fun _ ↦ c) (mdifferentiable_const ..) - (FiberBundle.mdifferentiableAt_extend ..)] - apply hΦ.pointwise (FiberBundle.mdifferentiableAt_extend ..) <| - mdifferentiableAt_const.smul_section (FiberBundle.mdifferentiableAt_extend ..) + rw [← hΦ.smul (f := fun _ ↦ c) (mdifferentiable_const ..) (mdifferentiableAt_extend ..)] + apply hΦ.pointwise (mdifferentiableAt_extend ..) <| + mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..) simp } theorem mkHom_apply {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F (Φ ·) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) : mkHom Φ x hΦ (σ x) = Φ σ := - hΦ.pointwise (FiberBundle.mdifferentiableAt_extend ..) hσ (by simp) + hΦ.pointwise (mdifferentiableAt_extend ..) hσ (by simp) theorem mkHom_apply_eq_extend {Φ : (Π x : M, V x) → A} {x} (hΦ : TensorialAt I F Φ x) (σ : V x) : - mkHom Φ x hΦ σ = Φ (FiberBundle.extend F σ) := + mkHom Φ x hΦ σ = Φ (extend F σ) := rfl /-- Given an `A`-valued operation `Φ` on sections of vector bundles `V` and `V'` which is tensorial @@ -238,47 +231,42 @@ noncomputable def mkHom₂ (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) : V x →L[𝕜] V' x →L[𝕜] A := - let Ψ : V x ≃L[𝕜] F := (trivializationAt F V x).continuousLinearEquivAt 𝕜 x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V x) := Ψ.symm.toHomeomorph.t2Space - have : FiniteDimensional 𝕜 (V x) := Ψ.symm.toLinearEquiv.finiteDimensional - let Ψ' : V' x ≃L[𝕜] F' := (trivializationAt F' V' x).continuousLinearEquivAt 𝕜 x - (FiberBundle.mem_baseSet_trivializationAt' x) - have : T2Space (V' x) := Ψ'.symm.toHomeomorph.t2Space - have : FiniteDimensional 𝕜 (V' x) := Ψ'.symm.toLinearEquiv.finiteDimensional + have : T2Space (V x) := FiberBundle.t2Space F V x + have : FiniteDimensional 𝕜 (V x) := VectorBundle.finiteDimensional 𝕜 F V x + have : T2Space (V' x) := FiberBundle.t2Space F' V' x + have : FiniteDimensional 𝕜 (V' x) := VectorBundle.finiteDimensional 𝕜 F' V' x have H : IsBilinearMap 𝕜 - (fun (v : V x) (w : V' x) ↦ Φ (FiberBundle.extend F v) (FiberBundle.extend F' w)) := + (fun (v : V x) (w : V' x) ↦ Φ (extend F v) (extend F' w)) := { add_left v₁ v₂ w := by - rw [← (hΦ₁ _ (FiberBundle.mdifferentiableAt_extend ..)).add - (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) _ - (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) _ rfl - · exact mdifferentiableAt_add_section (FiberBundle.mdifferentiableAt_extend ..) - (FiberBundle.mdifferentiableAt_extend ..) + rw [← (hΦ₁ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) _ + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) _ rfl + · exact mdifferentiableAt_add_section (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..) · simp smul_left c v w := by - rw [← (hΦ₁ _ (FiberBundle.mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) - (mdifferentiable_const ..) (FiberBundle.mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) - (mdifferentiableAt_const.smul_section (FiberBundle.mdifferentiableAt_extend ..)) - (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) + rw [← (hΦ₁ _ (mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) (mdifferentiable_const ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) + (mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..)) + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) · simp · rfl add_right v w₁ w₂ := by - rw [← (hΦ₂ _ (FiberBundle.mdifferentiableAt_extend ..)).add - (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) - (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) <| - mdifferentiableAt_add_section (FiberBundle.mdifferentiableAt_extend ..) - (FiberBundle.mdifferentiableAt_extend ..) + rw [← (hΦ₂ _ (mdifferentiableAt_extend ..)).add (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) <| + mdifferentiableAt_add_section (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) · rfl · simp smul_right c v w := by - rw [← (hΦ₂ _ (FiberBundle.mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) - (mdifferentiable_const ..) (FiberBundle.mdifferentiableAt_extend ..)] - apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) - (FiberBundle.mdifferentiableAt_extend ..) (FiberBundle.mdifferentiableAt_extend ..) <| - mdifferentiableAt_const.smul_section (FiberBundle.mdifferentiableAt_extend ..) + rw [← (hΦ₂ _ (mdifferentiableAt_extend ..)).smul (f := fun _ ↦ c) (mdifferentiable_const ..) + (mdifferentiableAt_extend ..)] + apply TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) + (mdifferentiableAt_extend ..) (mdifferentiableAt_extend ..) <| + mdifferentiableAt_const.smul_section (mdifferentiableAt_extend ..) · rfl · simp } H.toLinearMap.toContinuousBilinearMap @@ -289,15 +277,15 @@ theorem mkHom₂_apply (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) {σ : Π x : M, V x} (hσ : MDiffAt (T% σ) x) {τ : Π x : M, V' x} (hτ : MDiffAt (T% τ) x) : mkHom₂ Φ x hΦ₁ hΦ₂ (σ x) (τ x) = Φ σ τ := - TensorialAt.pointwise₂ hΦ₁ hΦ₂ (FiberBundle.mdifferentiableAt_extend ..) hσ - (FiberBundle.mdifferentiableAt_extend ..) hτ (by simp) (by simp) + TensorialAt.pointwise₂ hΦ₁ hΦ₂ (mdifferentiableAt_extend ..) hσ (mdifferentiableAt_extend ..) hτ + (by simp) (by simp) theorem mkHom₂_apply_eq_extend {Φ : (Π x : M, V x) → (Π x : M, V' x) → A} {x} (hΦ₁ : ∀ τ, MDiffAt (T% τ) x → TensorialAt I F (Φ · τ) x) (hΦ₂ : ∀ σ, MDiffAt (T% σ) x → TensorialAt I F' (Φ σ) x) (σ : V x) (τ : V' x) : - mkHom₂ Φ x hΦ₁ hΦ₂ σ τ = Φ (FiberBundle.extend F σ) (FiberBundle.extend F' τ) := + mkHom₂ Φ x hΦ₁ hΦ₂ σ τ = Φ (extend F σ) (extend F' τ) := rfl /-- Given an `A`-valued operation `Φ` on sections of vector bundles `V`, `V'` and `V''` which is From 38b6c2bdd2ea5fa255dec7c9ff272408bf99b4c7 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 17:53:47 +0100 Subject: [PATCH 588/601] Fix bad merge in CovariantDerivative/Basic.lean --- .../CovariantDerivative/Basic.lean | 56 ++++++++++++++++--- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 92e72d33cf3a41..c9ae59ce2fed24 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -142,13 +142,10 @@ lemma iUnion {ι : Type*} {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x end changing_set --- TODO: prove that `cov σ x` depends on `σ` only via the 1-jet of `σ` at `x`. --- This will be easy using the projection formula about Ehresmann connections, --- which will be added in the planned file `CovariantDerivative/Ehresmann.lean`. --- In the mean-time we use the following weaker results (which are convenient to apply anyway). - /-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and -`σ'` agree on `s` and are differentiable at `x`, then `cov σ x = cov σ x'`. -/ +`σ'` agree on `s` and are differentiable at `x`, then `cov σ x = cov σ x'`. + +This is a convenient special case of `congr_of_eq_one_jet`. -/ lemma congr_of_eqOn {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -183,7 +180,9 @@ lemma congr_of_eqOn open Filter Set in /-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and -`σ'` agree near `x` and are differentiable at `x`, then `cov σ x = cov σ x'`. -/ +`σ'` agree near `x` and are differentiable at `x`, then `cov σ x = cov σ x'`. + +This is a convenient special case of `congr_of_eq_one_jet`. -/ lemma congr_of_eventuallyEq {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -195,18 +194,45 @@ lemma congr_of_eventuallyEq choose s' hs' b using hσσ' exact (hcov.mono inter_subset_left).congr_of_eqOn hσ hσ' (inter_mem hxs hs') fun x hx ↦ b x hx.2 +/-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `σ` and +`σ'` are differentiable at `x` with the same one-jet (i.e., agree at `x` and have the same +`mfderiv`), then `cov σ x = cov σ x'`. -/ +lemma congr_of_eq_one_jet + {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {x : M} (hxs : s ∈ 𝓝 x) + {σ σ' : Π x : M, V x} (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) + (hσσ' : σ x = σ' x) (hσσ' : mfderiv% (T% σ) x = mfderiv% (T% σ') x) : + cov σ x = cov σ' x := by + -- This should be easy using the projection formula in `CovariantDerivative.Ehresmann`. + sorry + /-! ### Computational properties -/ section computational_properties variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} +@[simp] lemma zero [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) {x} (hx : x ∈ s := by trivial) : cov 0 x = 0 := by simpa using (hcov.add (mdifferentiableAt_zeroSection ..) (mdifferentiableAt_zeroSection ..) : cov (0 + 0) x = _) +lemma neg [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) + {σ : Π x : M, V x} {x} + (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : + cov (-σ) x = - cov σ x := by + rw [eq_neg_iff_add_eq_zero, ← hcov.add (mdifferentiableAt_neg_section hσ) hσ] + simp (disch := assumption) + +lemma sub [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) + {σ σ' : Π x : M, V x} {x} + (hσ : MDiffAt (T% σ) x) (hσ' : MDiffAt (T% σ') x) (hx : x ∈ s := by trivial) : + cov (σ - σ') x = cov σ x - cov σ' x := by + rw [sub_eq_neg_add, hcov.add (mdifferentiableAt_neg_section hσ') hσ, hcov.neg hσ'] + abel + theorem smul_const (hcov : IsCovariantDerivativeOn F cov s) {σ : Π x : M, V x} {x} (a : 𝕜) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : @@ -387,6 +413,22 @@ lemma zero [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) : cov 0 = 0 ext1 x simp [cov.isCovariantDerivativeOnUniv.zero] +-- XXX: do we prefer this statement, or point-wise versions instead? +-- if both, which one should be simp? +@[simp] +lemma neg [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) + {σ : Π x : M, V x} (hσ : MDiff (T% σ)) : + cov (-σ) = - cov σ := by + ext1 x + exact cov.isCovariantDerivativeOnUniv.neg (hσ x) + +@[simp] +lemma sub [VectorBundle 𝕜 F V] (cov : CovariantDerivative I F V) + {σ σ' : Π x : M, V x} (hσ : MDiff (T% σ)) (hσ' : MDiff (T% σ')) : + cov (σ - σ') = cov σ - cov σ' := by + ext1 x + exact cov.isCovariantDerivativeOnUniv.sub (hσ x) (hσ' x) + /-- If `cov` is a covariant derivative on each set in an open cover, it is a covariant derivative. -/ def of_isCovariantDerivativeOn_of_open_cover {ι : Type*} {s : ι → Set M} From 742f63782882ee267953876f1e632cb502ee511c Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 17:59:31 +0100 Subject: [PATCH 589/601] Fixup LeviCivita --- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index ca317eb4b867ed..38b8450d10b69e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -731,8 +731,7 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : · exact FiberBundle.mdifferentiableAt_extend .. · exact FiberBundle.mdifferentiableAt_extend .. leibniz {Y f x} hY hf _ := by - unfold lcAux - dsimp + dsimp [lcAux] rw [dif_pos hY, dif_pos] · unfold lcAux₁ dsimp @@ -746,16 +745,14 @@ lemma isCovariantDerivativeOn_lcAux [FiniteDimensional ℝ E] : LinearIsometryEquiv.coe_symm_toContinuousLinearEquiv, comp_apply, LinearIsometryEquiv.apply_symm_apply, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, - ContinuousLinearMap.toSpanSingleton_apply, map_add, map_smul] + map_add, map_smul] ext Z₀ simp only [lcAux₀, lcAux₀', TensorialAt.mkHom₂_apply_eq_extend, ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] rw [if_pos, if_pos, if_pos, if_pos] - · convert leviCivitaRhs_smulY_apply I (Z := FiberBundle.extend E Z₀) (x := x) - hf (FiberBundle.mdifferentiableAt_extend I E X₀) hY + · convert leviCivitaRhs_smulY_apply I hf (FiberBundle.mdifferentiableAt_extend I E X₀) hY (FiberBundle.mdifferentiableAt_extend I E Z₀) - · simp - · simp [Φ, product] + simp [Φ, product] · exact FiberBundle.mdifferentiableAt_extend .. · exact FiberBundle.mdifferentiableAt_extend .. · exact FiberBundle.mdifferentiableAt_extend .. From 8bf6ea3a4469bf28a4cd083e9906eca1789fcc3a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 20:22:26 +0100 Subject: [PATCH 590/601] chore: trivially generalise extDerivFun to codomain normed spaces --- Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index a704dd982a283b..0e2769b98e8589 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -398,20 +398,20 @@ end smul /-! ### Exterior derivative of a scalar function -/ /-- The exterior derivative of a scalar function on `M`, as a section of the cotangent bundle. -/ -noncomputable abbrev extDerivFun (g : M → 𝕜) : - Π x : M, TangentSpace I x →L[𝕜] 𝕜 := +noncomputable abbrev extDerivFun (g : M → F) : + Π x : M, TangentSpace I x →L[𝕜] F := fun x ↦ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap ∘L (mfderiv% g x) @[simp] -lemma extDerivFun_add {g g' : M → 𝕜} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) : +lemma extDerivFun_add {g g' : M → F} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) : extDerivFun (g + g') x = extDerivFun (I := I) g x + extDerivFun g' x := by simp [extDerivFun, mfderiv_add hg hg'] congr @[simp] -lemma extDerivFun_zero {x : M} : extDerivFun (I := I) (0 : M → 𝕜) x = 0 := by - have : extDerivFun (0 : M → 𝕜) x + extDerivFun (0 : M → 𝕜) x = - extDerivFun (I := I) (0 : M → 𝕜) x := by +lemma extDerivFun_zero {x : M} : extDerivFun (I := I) (0 : M → F) x = 0 := by + have : extDerivFun (0 : M → F) x + extDerivFun (0 : M → F) x = + extDerivFun (I := I) (0 : M → F) x := by rw [← extDerivFun_add (by exact mdifferentiable_const ..) (by exact mdifferentiable_const ..)] simp simpa using this From bf9e054726a8a8e6bb24fb065468ff6071a8b596 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 17 Mar 2026 20:48:36 +0100 Subject: [PATCH 591/601] Remove bad simp annotation added in merge --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index c9ae59ce2fed24..960e192a7d3451 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -212,7 +212,6 @@ section computational_properties variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} {s : Set M} -@[simp] lemma zero [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) {x} (hx : x ∈ s := by trivial) : cov 0 x = 0 := by @@ -224,7 +223,7 @@ lemma neg [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : cov (-σ) x = - cov σ x := by rw [eq_neg_iff_add_eq_zero, ← hcov.add (mdifferentiableAt_neg_section hσ) hσ] - simp (disch := assumption) + simp (disch := assumption) [hcov.zero] lemma sub [VectorBundle 𝕜 F V] (hcov : IsCovariantDerivativeOn F cov s) {σ σ' : Π x : M, V x} {x} From 5ab2c38abf357d22f28684f1013a405d2c6117f9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 21 Mar 2026 10:53:58 +0100 Subject: [PATCH 592/601] Remove check' --- Mathlib/Geometry/Manifold/VectorBundle/Basic.lean | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index ee6cad290f2fa3..4b5bb3c3a8d11b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -61,18 +61,6 @@ fields, etc. @[expose] public section --- Kyle’s #check' command. This has nothing to do here but will be convenient for us -open Lean Elab Command PrettyPrinter Delaborator in -elab tk:"#check' " name:ident : command => runTermElabM fun _ => do - for c in (← realizeGlobalConstWithInfos name) do - addCompletionInfo <| .id name name.getId (danglingDot := false) {} none - let info ← getConstInfo c - let delab : Delab := do - delabForallParamsWithSignature fun binders type => do - let binders := binders.filter fun binder => binder.raw.isOfKind ``Parser.Term.explicitBinder - return ⟨← `(declSigWithId| $(mkIdent c) $binders* : $type)⟩ - logInfoAt tk <| .ofFormatWithInfosM (PrettyPrinter.ppExprWithInfos (delab := delab) info.type) - assert_not_exists mfderiv open Bundle Set OpenPartialHomeomorph From f4c7992444ea6600673895380b7eb41349352192 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 21 Mar 2026 10:54:05 +0100 Subject: [PATCH 593/601] chore: remove duplicate open --- Mathlib/Geometry/Manifold/VectorBundle/Basic.lean | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 4b5bb3c3a8d11b..cb07d559d2b07b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -63,13 +63,9 @@ fields, etc. assert_not_exists mfderiv -open Bundle Set OpenPartialHomeomorph - +open Bundle Filter Set OpenPartialHomeomorph open Function (id_def) - -open Filter - -open scoped Manifold Bundle Topology ContDiff +open scoped Manifold Topology ContDiff variable {n : WithTop ℕ∞} {𝕜 B B' F M : Type*} {E : B → Type*} From a333eb95247f335bbed88003f73c54f462d6cce8 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 26 Mar 2026 15:06:06 +0100 Subject: [PATCH 594/601] Some progress on Ehresmann --- .../CovariantDerivative/Ehresmann.lean | 221 ++++++++---------- .../CovariantDerivative/Lift.lean | 7 + .../CovariantDerivative/TrivPrelim.lean | 52 ++++- 3 files changed, 153 insertions(+), 127 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 0a79551f93bc93..0b5c8d83d56d2c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -21,6 +21,18 @@ TODO: add a more complete doc-string open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff +lemma Bundle.Trivialization.continuousLinearMapAt_apply_of_mem (R : Type*) {B : Type*} {F : Type*} + {E : B → Type*} [NontriviallyNormedField R] [(x : B) → AddCommMonoid (E x)] + [(x : B) → Module R (E x)] + [NormedAddCommGroup F] [NormedSpace R F] + [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + [(x : B) → TopologicalSpace (E x)] [FiberBundle F E] (e : Trivialization F TotalSpace.proj) + [Trivialization.IsLinear R e] {b : B} (hb : b ∈ e.baseSet) (y : E b) : + (continuousLinearMapAt R e b) y = (e ⟨b, y⟩).2 := by + simp [coe_linearMapAt_of_mem e hb] + +attribute [simp] Bundle.Trivialization.coe_linearMapAt_of_mem + variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @[expose] public section -- TODO: think if we want to expose all definitions! @@ -82,10 +94,10 @@ lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f set_option backward.isDefEq.respectTransparency false in lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] (hcov : IsCovariantDerivativeOn F cov s) {x : M} {f : F} {u : TM x} {v : F} (hx : x ∈ s := by trivial) : (u, v) ∈ hcov.horiz x f ↔ - ∃ σ : M → F, MDiffAt (T% σ) x ∧ - σ x = f ∧ - mfderiv I 𝓘(𝕜, F) σ x u = v ∧ - cov σ x u = 0 := by + ∃ s : M → F, MDiffAt s x ∧ + s x = f ∧ + mfderiv I 𝓘(𝕜, F) s x u = v ∧ + cov s x u = 0 := by constructor · intro huv simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv @@ -95,9 +107,9 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] (hcov : IsCovariantDerivat replace huv : v = 0 := by simpa using huv subst huv use fun x ↦ f - simp [mdifferentiableAt_section, mdifferentiableAt_const] + simp [mdifferentiableAt_const] rcases map_of_one_jet_spec u w (by tauto) with ⟨h, h', h''⟩ - use map_of_one_jet u w, ?_, h, h'' + use map_of_one_jet u w, h', h, h'' · rw [hcov.eq_one_form] · simp only [w, h] convert huv @@ -105,10 +117,9 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] (hcov : IsCovariantDerivat (hcov.one_form x f) u exact h''.symm · rwa [mdifferentiableAt_section] - · rwa [mdifferentiableAt_section] - · rintro ⟨σ, σ_diff, rfl, rfl, covσ⟩ - simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covσ] - rw [hcov.eq_one_form σ_diff] + · rintro ⟨s, s_diff, rfl, rfl, covs⟩ + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, ← covs] + rw [hcov.eq_one_form (mdifferentiableAt_section_trivial_iff.mpr s_diff)] rfl end projection_trivial_bundle @@ -128,27 +139,39 @@ def pushCovDer (M → F) → (Π x : M, TangentSpace I x →L[𝕜] F) := fun σ x ↦ e.continuousLinearMapAt 𝕜 x ∘L (cov (e.funToSec σ) x) -lemma pushCovDer_ofSect [FiniteDimensional 𝕜 F] - [IsManifold I 1 M] + +-- FIXME Decide whether we want to add enough assumption to use the commented out statement +omit [IsManifold I 1 M] in +lemma pushCovDer_secToFun -- [CompleteSpace 𝕜] + [FiniteDimensional 𝕜 F] [IsManifold I 1 M] [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} (hcov : IsCovariantDerivativeOn F cov e.baseSet) - {X₀ : TangentSpace I x} {σ : Π x : M, V x} {x : M} + {u : TangentSpace I x} {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) (hx : x ∈ e.baseSet := by assumption) : - (e.pushCovDer cov) (fun x ↦ (e (σ x)).2) x X₀ = (e (cov σ x X₀)).2 := by - have : cov (fun x' ↦ e.symm x' (e (T% σ x')).2) x = cov σ x := by +-- e.pushCovDer cov (e.secToFun σ) x = (e.linearEquivAt 𝕜 x hx).toContinuousLinearMap ∘L (cov σ x) + e.pushCovDer cov (e.secToFun σ) x u = (e (cov σ x u)).2 := by + have : cov (e.funToSec (e.secToFun σ)) x = cov σ x := by apply hcov.congr_of_eqOn _ hσ (e.baseSet_mem_nhds hx) - · exact fun y hy ↦ symm_apply_apply_mk e hy (σ y) --FIXME extract as lemma? - · stop - rw [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] + · simp +contextual + · rw [(e.total_funToSec_secToFun_eventuallyEq hx σ).mdifferentiableAt_iff] exact hσ unfold pushCovDer - stop - rw [this] - simp [coe_linearMapAt, hx] + simp [this, hx] +omit [IsManifold I 1 M] in +lemma pushCovDer_funToSec [FiniteDimensional 𝕜 F] + [IsManifold I 1 M] + [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] + [ContMDiffVectorBundle 1 F V I] + (cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)) + {x : M} {s : M → F} + (hx : x ∈ e.baseSet := by assumption) : + cov (e.funToSec s) x = e.symmL 𝕜 x ∘L (e.pushCovDer cov s x) := by + ext u + simp [pushCovDer, hx] variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -194,81 +217,7 @@ lemma pushCovDer_isCovariantDerivativeOn congr! 1 exact e.linearMapAt_symmₗ (R := 𝕜) (hu hx) (σ x) -variable {e} in -lemma coordChangeL_pushCovDer - [IsManifold I 1 M] - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) - {s : M → F} (hs : MDiffAt s x) : - e.coordChangeL 𝕜 e' x ∘L (e.pushCovDer cov s x) = - e'.pushCovDer cov (fun x ↦ e.coordChangeL 𝕜 e' x (s x)) x := by - ext1 X₀ - simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, Function.comp_apply] - unfold pushCovDer - let σ := (fun x' ↦ e.symm x' (s x')) - rw [coordChangeL_apply e e' hx] - simp only [ContinuousLinearMap.coe_comp', continuousLinearMapAt_apply, coe_linearMapAt, hx.1, - ↓reduceIte, Function.comp_apply, hx.2] - refold_let σ - have : e.symm x (e ⟨x, cov σ x X₀⟩).2 = cov σ x X₀ := by - simp [hx.1] - stop - rw [this] - -- TODO: extract lemma? - have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = - e'.symm x' ((fun x ↦ (coordChangeL 𝕜 e e' x) (s x)) x') := by - rintro x' ⟨hx'e, hx'e'⟩ - simp only - rw [coordChangeL_apply e e' ⟨hx'e, hx'e'⟩] - -- simp [hx'e'] -- TODO doesn’t work - rw [symm_apply_apply_mk e' hx'e'] - have mem : e.baseSet ∩ e'.baseSet ∈ 𝓝 x := by - -- FIXME: make sure grind can do this proof - exact inter_mem (baseSet_mem_nhds e (mem_of_mem_inter_left hx)) - (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) - have hσ : MDiffAt (T% σ) x := - mdifferentiableAt_section_of_function e hx.1 hs - rw [hcov.congr_of_eqOnhσ ?_ mem this] - -- TODO have automatation doing the next three lines… - apply mdifferentiableAt_section_of_function e' hx.2 - have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 - exact this.mdifferentiableAt (zero_ne_one.symm) |>.clm_apply hs - -variable [CompleteSpace 𝕜] - -variable {e} in -lemma coordChangeL_mem_horiz [FiniteDimensional 𝕜 E] - [IsManifold I 1 M] [FiniteDimensional 𝕜 F] - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : - haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov - haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov - (u, w) ∈ hcove.horiz x v → - (u, e.coordChangeL 𝕜 e' x w) ∈ hcove'.horiz x (e.coordChangeL 𝕜 e' x v) := by - have hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov - have hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov - rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] - rintro ⟨s, sdiff, sxv, sxuw, covs⟩ - use fun x ↦ e.coordChangeL 𝕜 e' x (s x), ?_, ?_, ?_ - · let X := FiberBundle.extend E u - -- have hX : MDiffAt (T% X) x := mdifferentiableAt_extend I E u - -- TODO: investigate whether the following line comes from inconsistent ways to - -- state assumptions - rw [mdifferentiableAt_section_trivial_iff] at sdiff - rw [← e.coordChangeL_pushCovDer hcov hx sdiff] - simp [covs] - · sorry - · congr - · rw [← sxuw] - sorry - --- This is PAIIIIINNNN +-- This is PAIIIIINNNN and currently unused variable {e} in lemma coordChangeL_coordChangeL {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] @@ -298,31 +247,6 @@ lemma coordChangeL_coordChangeL rw [(linearEquivAt 𝕜 e x hx'.2).comp_symm] simp -variable {e} in -lemma coordChangeL_mem_horiz_iff [FiniteDimensional 𝕜 E] - [IsManifold I 1 M] [FiniteDimensional 𝕜 F] - {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] - [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] - [ContMDiffVectorBundle 1 F V I] - (hcov : IsCovariantDerivativeOn F cov <| e.baseSet ∩ e'.baseSet) - {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) {u : TangentSpace I x} {v w : F} : - haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov - haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov - (u, w) ∈ hcove.horiz x v ↔ - (u, e.coordChangeL 𝕜 e' x w) ∈ hcove'.horiz x (e.coordChangeL 𝕜 e' x v) := by - refine ⟨e.coordChangeL_mem_horiz hcov hx, fun hu ↦ ?_⟩ - let v' := e.coordChangeL 𝕜 e' x v - let w' := e.coordChangeL 𝕜 e' x w - rw [inter_comm] at hx hcov - have hx' := inter_comm _ _ ▸ hx - have hvv' : v = e'.coordChangeL 𝕜 e x v' := (coordChangeL_coordChangeL hx' v).symm - have hww' : w = e'.coordChangeL 𝕜 e x w' := (coordChangeL_coordChangeL hx' w).symm - have key := e'.coordChangeL_mem_horiz hcov hx (w := w') (u := u) (v := v') ?_ - · rw [← hvv', ← hww'] at key - convert key using 2 - apply inter_comm - · convert hu using 2 - apply inter_comm end to_trivialization @@ -350,7 +274,7 @@ def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : letI Tvt := t.deriv I v t.symmL 𝕜 v.proj ∘L tproj ∘L Tvt -omit [FiniteDimensional 𝕜 F] in +omit [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] in lemma isCovariantDerivativeOn_pushCovDer (cov : CovariantDerivative I F V) (e : Trivialization F (π F V)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := @@ -431,6 +355,59 @@ lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hσ, hcov.cov_eq_proj s X₀ hs, t.mfderiv_comp_section hσ _ hx] +lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] + {cov : CovariantDerivative I F V} {v : TotalSpace F V} + (w : TangentSpace (I.prod 𝓘(𝕜, F)) v) : + letI u := mfderiv (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v w + w ∈ cov.horiz v ↔ ∃ σ : Π x, V x, + MDiffAt (T% σ) v.proj ∧ + σ v.proj = v ∧ + mfderiv% (T% σ) v.proj u = w ∧ + cov σ v.proj u = 0 + := by + set u := mfderiv (I.prod 𝓘(𝕜, F)) I TotalSpace.proj v w with u_def + set t := trivializationAt F V v.proj with t_def + set Tvt := t.deriv I v with Tvt_def + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + have hvproj : v.proj ∈ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' v.proj + have hTvtw : (Tvt w).1 = u := + t.mfderiv_proj_fst_deriv hvproj w |>.symm + simp_rw [cov.comap_trivializationAt_horiz v, ← t_def, ← Tvt_def, Submodule.mem_comap, + hcov.mem_horiz_iff_exists] + constructor + · rintro ⟨s, sdiff, sval, mfderivs, covs⟩ + use t.funToSec s, ?_, ?_, ?_ + · rw [ContinuousLinearMap.coe_coe] at covs + simp [t.pushCovDer_funToSec cov, ← hTvtw, covs, t.symm_map_zero 𝕜] + · exact t.mdifferentiableAt_funToSec hvproj sdiff + · simp [sval, hvproj] + + · -- TODO needs a lot of cleanup here + -- TODO cleanup those erw by understanding why we sometimes have Tvt and + -- sometimes Tvt.toLinerMap + erw [hTvtw] at mfderivs + rw [u_def, t.mfderiv_total_funToSec hvproj] + simp only [ContinuousLinearMap.coe_comp', Function.comp_apply, ContinuousLinearMap.prod_apply, + ContinuousLinearMap.coe_id', id_eq] + erw [mfderivs] + rw [t.mfderiv_proj_fst_deriv hvproj] + have : (((Trivialization.deriv I t v) w).1, (Tvt w).2) = Tvt w := rfl + erw [this, Tvt_def, t.funToSec_proj_eq hvproj sval] + exact t.derivInv_deriv_apply hvproj w + + · rintro ⟨σ, σdiff, σval, mfderivσ, covσ⟩ + use t.secToFun σ, ?_, ?_, ?_ + · rw [t.pushCovDer_secToFun cov.isCovariantDerivativeOn σdiff] + -- TODO cleanup those erw by understanding why we sometimes have Tvt and + -- sometimes Tvt.toLinerMap + erw [hTvtw, covσ] + exact t.map_zero 𝕜 hvproj + · exact Trivialization.mdifferentiableAt_secToFun t hvproj σdiff + · exact t.secToFun_apply_of_eq σval + · erw [hTvtw] + rw [t.mfderiv_secToFun_apply hvproj, mfderivσ, σval] + rfl + end CovariantDerivative end horiz diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index c7895ad1649c9d..f50d9cdda0fc3c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -168,6 +168,13 @@ lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace simp [h, t.symm_map_zero 𝕜] · rw [← h', t.mfderiv_proj_fst_deriv mem] +lemma CovariantDerivative.lift_vec_eq_iff' {v : TotalSpace F V} (u : TangentSpace I v.proj) + (w : TangentSpace (I.prod 𝓘(𝕜, F)) v) : + cov.lift_vec v u = w ↔ + w ∈ cov.horiz v ∧ + mfderiv (I.prod 𝓘(𝕜, F)) I (TotalSpace.proj : TotalSpace F V → M) v w = u := by + simp [CovariantDerivative.lift_vec_eq_iff, horiz] + -- noncomputable -- def CovariantDerivative.lift_vec' -- (p : TotalSpace E ((TotalSpace.proj : (TotalSpace F V → M)) *ᵖ (TangentSpace I))) : diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index 719ba680b00d5f..dbcf1f1a804c9c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -78,6 +78,11 @@ lemma bijective_symm [(x : B) → Zero (E x)] def secToFun (σ : (b : B) → E b) : B → F := fun b ↦ e (σ b) |>.2 +@[simp] +lemma secToFun_apply_of_eq {σ : (b : B) → E b} {v : TotalSpace F E} (h : σ v.proj = v) : + e.secToFun σ v.proj = (e v).2 := by + simp [secToFun, h] + lemma secToFun_congr {σ σ' : (b : B) → E b} {b : B} (h : σ b = σ' b) : e.secToFun σ b = e.secToFun σ' b := by simp [secToFun, h] @@ -97,6 +102,22 @@ variable [(x : B) → Zero (E x)] noncomputable def funToSec (s : B → F) : (b : B) → E b := fun b ↦ e.symm b (s b) +@[simp] +lemma snd_apply_funToSec {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + (e ⟨x, e.funToSec s x⟩).2 = s x := by + simp [funToSec, e.apply_mk_symm hx] + +@[simp] +lemma funToSec_proj_eq {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) {s : B → F} + (hsv : s v.proj = (e v).2) : + e.funToSec s v.proj = v.2 := by + simp [funToSec, hsv, e.symm_proj_apply v hv] + +@[simp] +lemma mk_funToSec_of_eq {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) {s : B → F} + (h : s v.proj = (e v).2) : (⟨v.proj, e.funToSec s v.proj⟩ : TotalSpace F E) = v := by + simp [funToSec, h, hv] + lemma funToSec_congr {s s' : B → F} {b : B} (h : s b = s' b) : e.funToSec s b = e.funToSec s' b := by simp [funToSec, h] @@ -128,9 +149,8 @@ lemma funToSec_secToFun {x : B} (hx : x ∈ e.baseSet) (σ : (b : B) → E b) : (e.funToSec_secToFun_eventually_eq hx σ).self_of_nhds section -variable (σ : (b : B) → E b) [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] +variable (σ : (b : B) → E b) -set_option linter.unusedSectionVars false in @[simp] lemma total_funToSec_secToFun_eventuallyEq {x : B} (hx : x ∈ e.baseSet) (σ : (b : B) → E b) : T% (e.funToSec <| e.secToFun σ) =ᶠ[𝓝 x] T% σ := by @@ -468,11 +488,33 @@ lemma mdifferentiableAt_secToFun_funToSec MDiffAt (e.secToFun <| e.funToSec s) x ↔ MDiffAt s x := e.secToFun_funToSec_eventuallyEq hx s |>.mdifferentiableAt_iff -lemma mfderiv_total_funToSec_fst_deriv {s : M → F} - (v : TotalSpace F V) (w : TangentSpace (I.prod 𝓘(𝕜, F)) v) : - mfderiv% (T% (e.funToSec s)) v.proj (e.deriv I v w).1 = w := by +lemma mfderiv_total_funToSec {s : M → F} {x : M} (hx : x ∈ e.baseSet) : + mfderiv% (T% (e.funToSec s)) x = + e.derivInv I (e.funToSec s x) ∘L .prod (.id 𝕜 <| TangentSpace I x) (mfderiv% s x) := by sorry +lemma mfderiv_secToFun + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {σ : (x : M) → V x} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ e.baseSet) : + mfderiv% (e.secToFun σ) x = + .snd 𝕜 (TangentSpace I x) F ∘L (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := by + rw [show e.secToFun σ = Prod.snd ∘ e ∘ T%σ from rfl] + have mdiffe : MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e (σ x) := + e.mdifferentiableAt hx _ + have : mfderiv% (e ∘ T%σ) x = (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := + mfderiv_comp x mdiffe hσ + -- TODO use mfderiv_comp_section or factor out stuff + sorry + +lemma mfderiv_secToFun_apply + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {σ : (x : M) → V x} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ e.baseSet) + (u : TangentSpace I x) : + mfderiv% (e.secToFun σ) x u = + (e.deriv I (σ x) (mfderiv% T%σ x u)).2 := by + simp [e.mfderiv_secToFun hσ hx] + rfl + noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule 𝕜 (TangentSpace (I.prod 𝓘(𝕜, F)) v) := (mfderiv (I.prod 𝓘(𝕜, F)) I Bundle.TotalSpace.proj v).ker From df0edadd5b5eef465209e1eedea223ed330a8425 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 26 Mar 2026 21:56:04 +0100 Subject: [PATCH 595/601] More stupid lemmas --- .../CovariantDerivative/TrivPrelim.lean | 68 +++++++++++++------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index dbcf1f1a804c9c..c8663973d346ff 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -102,7 +102,16 @@ variable [(x : B) → Zero (E x)] noncomputable def funToSec (s : B → F) : (b : B) → E b := fun b ↦ e.symm b (s b) +lemma totalSpace_mk_funToSec {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + T% (e.funToSec s) =ᶠ[𝓝 x] e.invFun ∘ fun x ↦ (x, s x) := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + exact mk_symm e hy (s y) + @[simp] +lemma apply_funToSec {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + e ⟨x, e.funToSec s x⟩ = (x, s x) := by + simp [funToSec, e.apply_mk_symm hx] + lemma snd_apply_funToSec {x : B} (hx : x ∈ e.baseSet) (s : B → F) : (e ⟨x, e.funToSec s x⟩).2 = s x := by simp [funToSec, e.apply_mk_symm hx] @@ -488,32 +497,25 @@ lemma mdifferentiableAt_secToFun_funToSec MDiffAt (e.secToFun <| e.funToSec s) x ↔ MDiffAt s x := e.secToFun_funToSec_eventuallyEq hx s |>.mdifferentiableAt_iff -lemma mfderiv_total_funToSec {s : M → F} {x : M} (hx : x ∈ e.baseSet) : +lemma mfderiv_total_funToSec + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {s : M → F} {x : M} (hs : MDiffAt s x) + (hx : x ∈ e.baseSet) : mfderiv% (T% (e.funToSec s)) x = e.derivInv I (e.funToSec s x) ∘L .prod (.id 𝕜 <| TangentSpace I x) (mfderiv% s x) := by - sorry + -- TODO build a world where this proof is not pure pain. + rw [(e.totalSpace_mk_funToSec hx s).mfderiv_eq, + mfderiv_comp x (e.mdifferentiableAt_invFun (I := I) hx (s x))] + · congr 2 + · simp [hx] + · rw [mfderiv_prodMk] + · erw [mfderiv_id] + rfl + · exact mdifferentiableAt_id + · exact hs + · exact mdifferentiableAt_id.prodMk hs -lemma mfderiv_secToFun - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] - {σ : (x : M) → V x} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ e.baseSet) : - mfderiv% (e.secToFun σ) x = - .snd 𝕜 (TangentSpace I x) F ∘L (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := by - rw [show e.secToFun σ = Prod.snd ∘ e ∘ T%σ from rfl] - have mdiffe : MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e (σ x) := - e.mdifferentiableAt hx _ - have : mfderiv% (e ∘ T%σ) x = (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := - mfderiv_comp x mdiffe hσ - -- TODO use mfderiv_comp_section or factor out stuff - sorry -lemma mfderiv_secToFun_apply - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] - {σ : (x : M) → V x} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ e.baseSet) - (u : TangentSpace I x) : - mfderiv% (e.secToFun σ) x u = - (e.deriv I (σ x) (mfderiv% T%σ x u)).2 := by - simp [e.mfderiv_secToFun hσ hx] - rfl noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : Submodule 𝕜 (TangentSpace (I.prod 𝓘(𝕜, F)) v) := @@ -560,6 +562,28 @@ lemma mfderiv_comp_section · apply mdifferentiableAt_id · exact (e.mdifferentiableAt_section_iff I σ hx).mp hσ +lemma mfderiv_secToFun_apply + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {σ : (x : M) → V x} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ e.baseSet) + (u : TangentSpace I x) : + mfderiv% (e.secToFun σ) x u = + (e.deriv I (σ x) (mfderiv% T%σ x u)).2 := by + -- TODO: Fix the erw + -- instModuleTangentSpace 𝓘(𝕜, F) (e.secToFun (E := V) σ x) + -- and + -- NormedSpace.toModule + -- are not defeq, but they are at default transparency. + -- Does it mean the statement of this lemma is bad? + erw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply] + exact congr(Prod.snd $(e.mfderiv_comp_section hσ u hx)).symm + +lemma mfderiv_secToFun + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {σ : (x : M) → V x} {x : M} (hσ : MDiffAt (T% σ) x) (hx : x ∈ e.baseSet) : + mfderiv% (e.secToFun σ) x = + .snd 𝕜 (TangentSpace I x) F ∘L (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := + ContinuousLinearMap.ext fun u ↦ mfderiv_secToFun_apply e hσ hx u + @[simp] lemma _root_.mdifferentiableAt_total_trivial_iff {s : M → F} {x : M} : MDiffAt (T% s) x ↔ MDiffAt s x := by From 5abc695e17d7ba3040e9a5dd738cb40f7135f598 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Thu, 26 Mar 2026 22:29:13 +0100 Subject: [PATCH 596/601] Finish CovariantDerivative.mem_horiz_iff_exists --- .../CovariantDerivative/Ehresmann.lean | 45 +++++++------------ .../CovariantDerivative/TrivPrelim.lean | 12 ++++- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 0b5c8d83d56d2c..b16df65f178c2b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -176,6 +176,7 @@ lemma pushCovDer_funToSec [FiniteDimensional 𝕜 F] variable {cov : (Π x : M, V x) → (Π x : M, TangentSpace I x →L[𝕜] V x)} -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) +omit [IsManifold I 1 M] in lemma pushCovDer_isCovariantDerivativeOn [∀ x, IsTopologicalAddGroup (V x)] [∀ x, ContinuousSMul 𝕜 (V x)] [ContMDiffVectorBundle 1 F V I] @@ -183,39 +184,26 @@ lemma pushCovDer_isCovariantDerivativeOn (hcov : IsCovariantDerivativeOn F cov u) : IsCovariantDerivativeOn F (e.pushCovDer cov) u where add {σ σ' x} hσ hσ' hx := by - set s := (fun x' ↦ e.symm x' (σ x')) - have hs : MDiffAt (T% s) x := by - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| - --mdifferentiableAt_section_trivial_iff.1 hσ - set s' := (fun x' ↦ e.symm x' (σ' x')) + set s := e.funToSec σ + have hs : MDiffAt (T% s) x := + mdifferentiableAt_funToSec e (hu hx) <| mdifferentiableAt_section_trivial_iff.mp hσ + set s' := e.funToSec σ' have hs' : MDiffAt (T% s') x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| - --mdifferentiableAt_section_trivial_iff.1 hσ' + mdifferentiableAt_funToSec e (hu hx) <| mdifferentiableAt_section_trivial_iff.mp hσ' unfold Trivialization.pushCovDer - stop rw [← ContinuousLinearMap.comp_add, ← hcov.add hs hs' hx] congr ext y - simp [e.symm_map_add 𝕜, s, s'] + rw [e.funToSec_map_add 𝕜] leibniz {σ g x} hσ hg hx := by - set s := (fun x' ↦ e.symm x' (σ x')) + set s := e.funToSec σ have hs : MDiffAt (T% s) x := - sorry -- e.mdifferentiableAt_section_of_function (hu hx) <| - --mdifferentiableAt_section_trivial_iff.1 hσ + mdifferentiableAt_funToSec e (hu hx) <| mdifferentiableAt_section_trivial_iff.mp hσ unfold Trivialization.pushCovDer - have : (fun x' ↦ e.symm x' ((g • σ) x')) = g • s := by - ext y - simp [s, e.symm_map_smul] - stop - rw [this, hcov.leibniz hs hg hx] - ext X₀ - simp only [ContinuousLinearMap.comp_add, ContinuousLinearMap.comp_smulₛₗ, RingHom.id_apply, - ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', ContinuousLinearMap.coe_comp', - continuousLinearMapAt_apply, Pi.smul_apply, Function.comp_apply, - ContinuousLinearEquiv.coe_coe, ContinuousLinearMap.toSpanSingleton_apply, _root_.map_smul, - add_right_inj, s] - congr! 1 - exact e.linearMapAt_symmₗ (R := 𝕜) (hu hx) (σ x) + rw [e.funToSec_map_smul g] + rw [hcov.leibniz hs hg hx] + ext u + simp [e.linearMapAt_funToSec (hu hx), s] -- This is PAIIIIINNNN and currently unused variable {e} in @@ -327,7 +315,6 @@ lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] exact FiberBundle.mem_baseSet_trivializationAt' v.proj · apply hcov.horiz_vert_direct_sum -variable [IsManifold I 1 M] variable {cov : CovariantDerivative I F V} set_option backward.isDefEq.respectTransparency false in @@ -381,12 +368,11 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] simp [t.pushCovDer_funToSec cov, ← hTvtw, covs, t.symm_map_zero 𝕜] · exact t.mdifferentiableAt_funToSec hvproj sdiff · simp [sval, hvproj] - · -- TODO needs a lot of cleanup here -- TODO cleanup those erw by understanding why we sometimes have Tvt and -- sometimes Tvt.toLinerMap erw [hTvtw] at mfderivs - rw [u_def, t.mfderiv_total_funToSec hvproj] + rw [u_def, t.mfderiv_total_funToSec sdiff hvproj] simp only [ContinuousLinearMap.coe_comp', Function.comp_apply, ContinuousLinearMap.prod_apply, ContinuousLinearMap.coe_id', id_eq] erw [mfderivs] @@ -394,7 +380,6 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] have : (((Trivialization.deriv I t v) w).1, (Tvt w).2) = Tvt w := rfl erw [this, Tvt_def, t.funToSec_proj_eq hvproj sval] exact t.derivInv_deriv_apply hvproj w - · rintro ⟨σ, σdiff, σval, mfderivσ, covσ⟩ use t.secToFun σ, ?_, ?_, ?_ · rw [t.pushCovDer_secToFun cov.isCovariantDerivativeOn σdiff] @@ -405,7 +390,7 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] · exact Trivialization.mdifferentiableAt_secToFun t hvproj σdiff · exact t.secToFun_apply_of_eq σval · erw [hTvtw] - rw [t.mfderiv_secToFun_apply hvproj, mfderivσ, σval] + rw [t.mfderiv_secToFun_apply σdiff hvproj, mfderivσ, σval] rfl end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index c8663973d346ff..2ecd792011614f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -244,6 +244,11 @@ variable {R B F : Type*} {E : B → Type*} [Semiring R] (e : Trivialization F (π F E)) [AddCommMonoid F] [Module R F] [(x : B) → AddCommMonoid (E x)] [(x : B) → Module R (E x)] +@[simp] +lemma linearMapAt_funToSec [Trivialization.IsLinear R e] {x : B} (hx : x ∈ e.baseSet) (s : B → F) : + (Trivialization.linearMapAt R e x) (e.funToSec s x) = s x := by + simp [funToSec, hx] + lemma map_smul [Trivialization.IsLinear R e] {b : B} (hb : b ∈ e.baseSet) (a : R) (v : E b) : (e ⟨b, a • v⟩).2 = a • (e ⟨b, v⟩).2 := @@ -312,7 +317,12 @@ lemma symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : e.symm x (a • f) = a • e.symm x f := (e.symmL R x).map_smul a f -lemma funToSec_map_smul [Trivialization.IsLinear R e] (a : R) (s : B → F) : +lemma funToSec_map_smul_const [Trivialization.IsLinear R e] (a : R) (s : B → F) : + e.funToSec (a • s) = a • e.funToSec s := by + ext b + simp [funToSec, e.symm_map_smul] + +lemma funToSec_map_smul [Trivialization.IsLinear R e] (a : B → R) (s : B → F) : e.funToSec (a • s) = a • e.funToSec s := by ext b simp [funToSec, e.symm_map_smul] From 0ba6600f75085d405c450c6ac722eff658bc9374 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Tue, 17 Mar 2026 16:55:04 +0100 Subject: [PATCH 597/601] Recover modifications lost in a bad merge --- .../CovariantDerivative/Ehresmann.lean | 48 ++++-------- .../CovariantDerivative/TrivPrelim.lean | 78 ++++++++++++------- .../CovariantDerivative/Trivial.lean | 6 +- 3 files changed, 70 insertions(+), 62 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index b16df65f178c2b..313845018cf2a4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -184,26 +184,17 @@ lemma pushCovDer_isCovariantDerivativeOn (hcov : IsCovariantDerivativeOn F cov u) : IsCovariantDerivativeOn F (e.pushCovDer cov) u where add {σ σ' x} hσ hσ' hx := by - set s := e.funToSec σ - have hs : MDiffAt (T% s) x := - mdifferentiableAt_funToSec e (hu hx) <| mdifferentiableAt_section_trivial_iff.mp hσ - set s' := e.funToSec σ' - have hs' : MDiffAt (T% s') x := - mdifferentiableAt_funToSec e (hu hx) <| mdifferentiableAt_section_trivial_iff.mp hσ' + have hs := mdifferentiableAt_funToSec' e (hu hx) hσ + have hs' := mdifferentiableAt_funToSec' e (hu hx) hσ' unfold Trivialization.pushCovDer - rw [← ContinuousLinearMap.comp_add, ← hcov.add hs hs' hx] - congr - ext y - rw [e.funToSec_map_add 𝕜] + rw [← ContinuousLinearMap.comp_add, ← hcov.add hs hs' hx, e.funToSec_map_add 𝕜] leibniz {σ g x} hσ hg hx := by - set s := e.funToSec σ - have hs : MDiffAt (T% s) x := - mdifferentiableAt_funToSec e (hu hx) <| mdifferentiableAt_section_trivial_iff.mp hσ + have hs := mdifferentiableAt_funToSec' e (hu hx) hσ + ext u unfold Trivialization.pushCovDer rw [e.funToSec_map_smul g] rw [hcov.leibniz hs hg hx] - ext u - simp [e.linearMapAt_funToSec (hu hx), s] + simp [e.linearMapAt_funToSec (hu hx)] -- This is PAIIIIINNNN and currently unused variable {e} in @@ -250,19 +241,17 @@ variable [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] local notation "TM" => TangentSpace I --- FIXME the statement of CovariantDerivative.isCovariantDerivativeOn should work on any set - noncomputable def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : TangentSpace (I.prod 𝓘(𝕜, F)) v →L[𝕜] V v.proj := letI t := trivializationAt F V v.proj haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (u := t.baseSet) subset_rfl - (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) + cov.isCovariantDerivativeOn letI tproj := d_covDerOn.projection v.proj (t v).2 letI Tvt := t.deriv I v t.symmL 𝕜 v.proj ∘L tproj ∘L Tvt -omit [CompleteSpace 𝕜] [FiniteDimensional 𝕜 F] in +omit [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [IsManifold I 1 M] in lemma isCovariantDerivativeOn_pushCovDer (cov : CovariantDerivative I F V) (e : Trivialization F (π F V)) [MemTrivializationAtlas e] : IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := @@ -317,30 +306,25 @@ lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] variable {cov : CovariantDerivative I F V} -set_option backward.isDefEq.respectTransparency false in -omit [ContMDiffVectorBundle 1 F V I] in -lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] - {σ : Π x : M, V x} (x : M) +lemma proj_mderiv {σ : Π x : M, V x} (x : M) (hσ : MDiffAt (T% σ) x) : cov σ x = cov.proj (σ x) ∘L (mfderiv I (I.prod 𝓘(𝕜, F)) (T% σ) x) := by - stop let t := trivializationAt F V x - let s := fun x ↦ (t (σ x)).2 + let s := t.secToFun σ let Tσx := mfderiv% (T% σ) x - -- FIXME `mfderiv%` fails in next line (fixed on master?) + -- FIXME `mfderiv%` fails in next line let Ttσx := mfderiv (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) t (σ x) ext1 X₀ - change cov σ x X₀ = (cov.proj (T% σ x)) ((mfderiv% (T% σ) x) X₀) have hcov := cov.isCovariantDerivativeOn_pushCovDer t have hx := mem_baseSet_trivializationAt F V x - have hs : MDiffAt (T% s) x := by - rw [t.mdifferentiableAt_section_iff I σ hx] at hσ - exact (mdifferentiableAt_section I s).mpr hσ + have hs : MDiffAt (T% s) x := t.mdifferentiableAt_total_secToFun hx hσ + change cov σ x X₀ = cov.proj (T% σ x) (mfderiv% (T% σ) x X₀) apply t.eq_of hx - erw [cov.snd_triv_proj (T% σ x), - ← t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) hσ, + rw [cov.snd_triv_proj (T% σ x), + ← t.pushCovDer_secToFun cov.isCovariantDerivativeOn hσ, hcov.cov_eq_proj s X₀ hs, t.mfderiv_comp_section hσ _ hx] + rfl lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] {cov : CovariantDerivative I F V} {v : TotalSpace F V} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean index 2ecd792011614f..8446549efaf9c8 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -87,6 +87,14 @@ lemma secToFun_congr {σ σ' : (b : B) → E b} {b : B} (h : σ b = σ' b) : e.secToFun σ b = e.secToFun σ' b := by simp [secToFun, h] +lemma apply_total_eventuallyEq + {x : B} (hx : x ∈ e.baseSet) (σ : Π x, E x) : + e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ (x, e.secToFun σ x) := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + ext + · exact e.coe_coe_fst hy + · simp [secToFun] + -- @[congr] -- lemma secToFun_congr {σ σ' : (b : B) → E b} {b : B} (h : ∀ x, x = b → σ x = σ' x) : -- e.secToFun σ b = e.secToFun σ' b := by @@ -218,20 +226,6 @@ lemma eq_of {x : B} {v v' : E x} (hx : x ∈ e.baseSet) (hvv' : (e v).2 = (e v') rw [hvv'] at this grind [e.symm_proj_apply v' hx] -variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] - - --- FIXME super weird elaborator bug: removing the --- omitted assumption from the variable line breaks the lemma -set_option linter.unusedSectionVars false in -lemma apply_total_eventuallyEq - {x : B} (hx : x ∈ e.baseSet) (σ : Π x, E x) : - e ∘ T%σ =ᶠ[𝓝 x] fun x ↦ (x, e.secToFun σ x) := by - filter_upwards [e.baseSet_mem_nhds hx] with y hy - ext - · exact e.coe_coe_fst hy - · simp [secToFun] - end end trivilization_topology @@ -345,6 +339,18 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] [∀ x : M, TopologicalSpace (V x)] [FiberBundle F V] +@[simp] +lemma _root_.mdifferentiableAt_total_trivial_iff {s : M → F} {x : M} : + MDiffAt (T% s) x ↔ MDiffAt s x := by + rw [mdifferentiableAt_section I] + simp + +@[simp] +lemma _root_.mdifferentiableAt_section_trivial_iff {σ : (x : M) → Trivial M F x} {x : M} : + MDiffAt (T% σ) x ↔ MDifferentiableAt I 𝓘(𝕜, F) σ x := by + rw [mdifferentiableAt_section I] + simp + variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] lemma mdifferentiableAt @@ -484,6 +490,14 @@ lemma mdifferentiableAt_funToSec have := e.secToFun_funToSec_eventuallyEq hx s exact hs.congr_of_eventuallyEq this +lemma mdifferentiableAt_funToSec' + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) {s : M → F} + (hs : MDiffAt (T% s) x) : + MDiffAt (T% (e.funToSec s)) x := by + rw [mdifferentiableAt_total_trivial_iff] at hs + apply mdifferentiableAt_funToSec _ hx hs + lemma mdifferentiableAt_secToFun [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] {x : M} (hx : x ∈ e.baseSet) {σ : (x : M) → V x} @@ -492,6 +506,14 @@ lemma mdifferentiableAt_secToFun rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] at hσ exact hσ +lemma mdifferentiableAt_total_secToFun + [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x ∈ e.baseSet) {σ : (x : M) → V x} + (hσ : MDiffAt (T% σ) x) : + MDiffAt (T% (e.secToFun σ)) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] at hσ + exact (mdifferentiableAt_section I _).mpr hσ + omit [MemTrivializationAtlas e] [(x : M) → Module 𝕜 (V x)] in @[simp] lemma mdifferentiableAt_total_funToSec_secToFun @@ -550,7 +572,7 @@ lemma mfderiv_comp_section [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] {σ : Π x : M, V x} {x : M} (hσ : MDiffAt T%σ x) (u : TangentSpace I x) (hx : x ∈ e.baseSet) : - (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv% (e.secToFun σ) x u) := by + e.deriv I (σ x) ((mfderiv% T%σ x) u) = (u, mfderiv% (e.secToFun σ) x u) := by have mdiffe : MDifferentiableAt (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) e (σ x) := e.mdifferentiableAt hx _ have : mfderiv% (e ∘ T%σ) x = (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := @@ -594,18 +616,6 @@ lemma mfderiv_secToFun .snd 𝕜 (TangentSpace I x) F ∘L (e.deriv I (σ x)) ∘L (mfderiv% T%σ x) := ContinuousLinearMap.ext fun u ↦ mfderiv_secToFun_apply e hσ hx u -@[simp] -lemma _root_.mdifferentiableAt_total_trivial_iff {s : M → F} {x : M} : - MDiffAt (T% s) x ↔ MDiffAt s x := by - rw [mdifferentiableAt_section I] - simp - -@[simp] -lemma _root_.mdifferentiableAt_section_trivial_iff {σ : (x : M) → Trivial M F x} {x : M} : - MDiffAt (T% σ) x ↔ MDifferentiableAt I 𝓘(𝕜, F) σ x := by - rw [mdifferentiableAt_section I] - simp - variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] @@ -614,6 +624,18 @@ theorem Bundle.Trivial.mdifferentiableAt_iff (σ : (x : E) → Trivial E E' x) ( MDiffAt (T% σ) e ↔ DifferentiableAt 𝕜 σ e := by simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] -end to_trivialization +-- unused but we need all combinations at some point. +@[simp] +theorem Bundle.Trivial.contMDiffOn_iff {n : WithTop ℕ∞} {σ : (x : E) → Trivial E E' x} {s : Set E} : + ContMDiffOn 𝓘(𝕜, E) (𝓘(𝕜, E).prod 𝓘(𝕜, E')) n (T% σ) s ↔ + ContDiffOn 𝕜 n σ s := by + sorry +end to_trivialization end Bundle.Trivialization + +section +@[simp] +lemma Bundle.TotalSpace.proj_mk' {B : Type*} {F : Type*} {E : B → Type*} (b : B) (e : E b) : + proj (TotalSpace.mk' F b e) = b := rfl +end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean index e03afa39307870..ec9809c44c54b4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -78,7 +78,9 @@ variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] /-- The trivial connection on the trivial bundle is smooth -/ lemma trivial_isSmooth : ContMDiffCovariantDerivative (𝕜 := 𝕜) (trivial 𝓘(𝕜, E) E E') (⊤ : ℕ∞) where - contMDiff := by -- {X σ} hX hσ + contMDiff := ⟨by + intro σ hσ + dsimp only [trivial] sorry /- -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well simp only [trivial] @@ -99,7 +101,7 @@ lemma trivial_isSmooth : simp at h₂ -- now use ContMDiffOn.congr and contDiff_infty_iff_fderiv, -- or perhaps a contMDiffOn version of this lemma? - sorry -/ + sorry -/⟩ noncomputable def of_endomorphism (A : E → E' →L[𝕜] E →L[𝕜] E') : CovariantDerivative 𝓘(𝕜, E) E' (Trivial E E') where From d6e7aa7550a769a3df33acc83c6d09ba13607b80 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Mar 2026 11:20:25 +0100 Subject: [PATCH 598/601] A bit more --- .../CovariantDerivative/Lift.lean | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index f50d9cdda0fc3c..52deb058be5dff 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -62,6 +62,11 @@ lemma IsCovariantDerivativeOn.projection_lift_vec (x : M) (f : F) : ext u simp +lemma IsCovariantDerivativeOn.lift_vec_mem_horiz (x : M) (f : F) (u : TangentSpace I x) : + hcov.lift_vec x f u ∈ hcov.horiz x f := by + rw [horiz] + simp + lemma IsCovariantDerivativeOn.lift_vec_eq_iff {x : M} {f : F} {u : TangentSpace I x} {w : TangentSpace I x × F} : hcov.lift_vec x f u = w ↔ hcov.projection x f w = 0 ∧ w.1 = u := by @@ -103,21 +108,6 @@ lemma CovariantDerivative.lift_vec_apply {v : TotalSpace F V} (u : TangentSpace letI tlift := hcov.lift_vec v.proj (t v).2 cov.lift_vec v u = t.derivInv I v (tlift u) := rfl -/-- We can compute `lift_vec v` using any trivialization whose -base set contains `v.proj`. This is crucial to prove smoothness -of `lift_vec`. -/ -lemma CovariantDerivative.lift_vec_eq {v : TotalSpace F V} - {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] - (hv : v.proj ∈ e.baseSet) - (u : TangentSpace I v.proj) : - haveI hcov := cov.isCovariantDerivativeOn_pushCovDer e - cov.lift_vec v u = e.derivInv I v (hcov.lift_vec v.proj (e v).2 u) := by - rw [cov.lift_vec_apply] - set t := trivializationAt F V v.proj - have hcov := cov.isCovariantDerivativeOn_pushCovDer t - refold_let t - sorry - @[simp] lemma CovariantDerivative.lift_vec_horiz {v : TotalSpace F V} (u : TangentSpace I v.proj) : cov.lift_vec v u ∈ cov.horiz v := by @@ -175,6 +165,25 @@ lemma CovariantDerivative.lift_vec_eq_iff' {v : TotalSpace F V} (u : TangentSpac mfderiv (I.prod 𝓘(𝕜, F)) I (TotalSpace.proj : TotalSpace F V → M) v w = u := by simp [CovariantDerivative.lift_vec_eq_iff, horiz] +/-- We can compute `lift_vec v` using any trivialization whose +base set contains `v.proj`. This is crucial to prove smoothness +of `lift_vec`. -/ +lemma CovariantDerivative.lift_vec_eq [FiniteDimensional 𝕜 E] {v : TotalSpace F V} + {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] + (hv : v.proj ∈ e.baseSet) + (u : TangentSpace I v.proj) : + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer e + cov.lift_vec v u = e.derivInv I v (hcov.lift_vec v.proj (e v).2 u) := by + apply (cov.lift_vec_eq_iff' _ _).mpr ⟨?_, ?_⟩ + · rw [cov.mem_horiz_iff_exists] + have hcov := cov.isCovariantDerivativeOn_pushCovDer e + have := hcov.lift_vec_mem_horiz v.proj (e v).2 u + rw [hcov.mem_horiz_iff_exists] at this + rcases this with ⟨s, sdiff, sval, mfderivs, covs⟩ + use e.funToSec s + sorry + · simp [hv] + -- noncomputable -- def CovariantDerivative.lift_vec' -- (p : TotalSpace E ((TotalSpace.proj : (TotalSpace F V → M)) *ᵖ (TangentSpace I))) : From 36c96bf3d0f0a89a4a55e5a0990cc30d2422ab15 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Mar 2026 12:34:42 +0100 Subject: [PATCH 599/601] Finish CovariantDerivative.lift_vec_eq --- .../CovariantDerivative/Ehresmann.lean | 6 ++--- .../CovariantDerivative/Lift.lean | 22 +++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean index 313845018cf2a4..2a29fff87c7ffe 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -347,9 +347,7 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] hcov.mem_horiz_iff_exists] constructor · rintro ⟨s, sdiff, sval, mfderivs, covs⟩ - use t.funToSec s, ?_, ?_, ?_ - · rw [ContinuousLinearMap.coe_coe] at covs - simp [t.pushCovDer_funToSec cov, ← hTvtw, covs, t.symm_map_zero 𝕜] + use t.funToSec s, ?_, ?_, ?_, ?_ · exact t.mdifferentiableAt_funToSec hvproj sdiff · simp [sval, hvproj] · -- TODO needs a lot of cleanup here @@ -364,6 +362,8 @@ lemma mem_horiz_iff_exists [FiniteDimensional 𝕜 E] have : (((Trivialization.deriv I t v) w).1, (Tvt w).2) = Tvt w := rfl erw [this, Tvt_def, t.funToSec_proj_eq hvproj sval] exact t.derivInv_deriv_apply hvproj w + · rw [ContinuousLinearMap.coe_coe] at covs + simp [t.pushCovDer_funToSec cov, ← hTvtw, covs, t.symm_map_zero 𝕜] · rintro ⟨σ, σdiff, σval, mfderivσ, covσ⟩ use t.secToFun σ, ?_, ?_, ?_ · rw [t.pushCovDer_secToFun cov.isCovariantDerivativeOn σdiff] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 52deb058be5dff..fc8370daef3800 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -179,9 +179,27 @@ lemma CovariantDerivative.lift_vec_eq [FiniteDimensional 𝕜 E] {v : TotalSpace have hcov := cov.isCovariantDerivativeOn_pushCovDer e have := hcov.lift_vec_mem_horiz v.proj (e v).2 u rw [hcov.mem_horiz_iff_exists] at this + have proj_lift : (hcov.lift_vec v.proj (e v).2 u).1 = u := by simp rcases this with ⟨s, sdiff, sval, mfderivs, covs⟩ - use e.funToSec s - sorry + -- TODO: cleanup the proof below and see how to factor stuff in + -- `CovariantDerivative.mem_horiz_iff_exists` + use e.funToSec s, ?_, ?_, ?_, ?_ + · exact e.mdifferentiableAt_funToSec hv sdiff + · simp [sval, hv] + · rw [e.mfderiv_total_funToSec sdiff hv] + simp only [TotalSpace.proj_mk', ContinuousLinearMap.coe_comp', Function.comp_apply, + ContinuousLinearMap.prod_apply, ContinuousLinearMap.coe_id', id_eq] + congr 2 + · simp [e.funToSec_proj_eq hv sval] + · simp [e.mfderiv_proj_fst_deriv, hv] + · simp only [hv, e.mfderiv_proj_derivInv_apply, ContinuousLinearMap.coe_neg, + LinearMap.neg_apply, ContinuousLinearMap.coe_coe] + rw [proj_lift] at mfderivs ⊢ + erw [mfderivs] + simp + · rw [proj_lift] at covs + simp [e.pushCovDer_funToSec cov, e.mfderiv_proj_fst_deriv hv, e.deriv_derivInv_apply hv, covs, + e.symm_map_zero 𝕜] · simp [hv] -- noncomputable From a5b21d5fa94d9e323827d52b2d3b7840294a43ae Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 27 Mar 2026 14:11:16 +0100 Subject: [PATCH 600/601] Cleanup and move around --- Mathlib.lean | 2 + .../CovariantDerivative/Geodesics.lean | 98 +++++++++ .../IntegralCurvePrelim.lean | 109 ++++++++++ .../CovariantDerivative/Lift.lean | 195 +----------------- 4 files changed, 212 insertions(+), 192 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean create mode 100644 Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean diff --git a/Mathlib.lean b/Mathlib.lean index 61605e7a0f3814..8f655d3724c8ed 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4476,6 +4476,8 @@ public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.ChristoffelSymbols public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Curvature public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Geodesics +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.IntegralCurvePrelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean new file mode 100644 index 00000000000000..f671d13ea33cc0 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean @@ -0,0 +1,98 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Heather Macbeth, Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.IntegralCurvePrelim + +/-! +# Geodesics for covariant derivatives on tangent bundles + +TODO: add a more complete doc-string + +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] + [IsManifold I 2 M] + (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) + +lemma IsMIntegralCurveAt.proj_acceleration {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) + (hγX : IsMIntegralCurveAt γ X t₀) : + cov.proj _ (velocity I.tangent (velocity I γ) t₀).2 = cov X (γ t₀) (X (γ t₀)) := by + rw [hγX.acceleration hX, cov.proj_mderiv _ hX] + simp + +/-- The geodesic vector field of a covariant derivative on a tangent bundle, defined +by send any vector `v` to its lift at itself. -/ +noncomputable +def CovariantDerivative.geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : + TangentSpace (I.prod 𝓘(ℝ, E)) v := cov.lift_vec v v.2 + +@[simp] +lemma CovariantDerivative.geodVF_horiz (v : TotalSpace E (TangentSpace I : M → Type _)) : + cov.geodVF v ∈ cov.horiz v := by + simp [CovariantDerivative.geodVF] + +@[simp] +lemma CovariantDerivative.proj_geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : + cov.proj v (cov.geodVF v) = 0 := by + simp [CovariantDerivative.geodVF] + +/-- A curve `γ : ℝ → M` is a geodesic for `cov` at `t` if it is an integral +curve of the geodesic vector field of `cov` near `t`. +Remember: `IsMIntegralCurveAt` is local, not pointwise. -/ +def CovariantDerivative.isGeodAt (γ : ℝ → M) (t : ℝ) := + IsMIntegralCurveAt (velocity I γ) cov.geodVF t + +set_option backward.isDefEq.respectTransparency false in +lemma CovariantDerivative.isGeodAt_iff_horiz {γ : ℝ → M} {t₀ : ℝ} + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : + cov.isGeodAt γ t₀ ↔ + ∀ᶠ (t : ℝ) in 𝓝 t₀, (velocity I.tangent (velocity I γ) t).2 ∈ cov.horiz _ := by + unfold CovariantDerivative.isGeodAt CovariantDerivative.geodVF + rw [IsMIntegralCurveAt_iff_mfderiv _ _ _ hγ] + refine eventually_congr ?_ + filter_upwards [hγ] with t ht + conv_lhs => rw [Eq.comm, cov.lift_vec_eq_iff (velocity I γ t).2] + rw [← cov.mem_horiz_iff_proj, proj_velocity, + show mfderiv% (velocity I γ) t (1 : ℝ) = (velocity I.tangent (velocity I γ) t).2 from + rfl, -- TODO need a simp lemma here? + ] + -- TODO: understand why + -- simp [proj_velocity, proj_acceleration I ht] + -- doesn’t close the goal + simp only [proj_velocity, and_iff_left_iff_imp] + exact fun _ ↦ proj_acceleration I ht + +lemma CovariantDerivative.isGeodAt_iff_proj {γ : ℝ → M} {t₀ : ℝ} + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : + cov.isGeodAt γ t₀ ↔ + ∀ᶠ (t : ℝ) in 𝓝 t₀, cov.proj _ (velocity I.tangent (velocity I γ) t).2 = 0 := + cov.isGeodAt_iff_horiz hγ + +def CovariantDerivative.isGeod (γ : ℝ → M) := ∀ t, cov.isGeodAt γ t + +set_option backward.isDefEq.respectTransparency false in +lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) + (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) + (hγX : IsMIntegralCurveAt γ X t₀) : + cov.isGeodAt γ t₀ ↔ ∀ᶠ t in 𝓝 t₀, cov X (γ t) (X (γ t)) = 0 := by + rw [cov.isGeodAt_iff_proj hγ] + refine eventually_congr ?_ + filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t ht ht' + rw [ht'.proj_acceleration cov ht] + diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean new file mode 100644 index 00000000000000..e28ee4137f4bb3 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean @@ -0,0 +1,109 @@ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +public import Mathlib.Geometry.Manifold.IntegralCurve.Basic + + +/-! +# Preliminaries about integral curves of vector fiels + +TODO: PR that material to Mathlib.Geometry.Manifold.IntegralCurve.Basic +except for `proj_acceleration` which uses +`Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable`. +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} + [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} + [TopologicalSpace M] [ChartedSpace H M] (γ : ℝ → M) + (v : (x : M) → TangentSpace I x) (t₀ : ℝ) + +variable (I) in +noncomputable +def velocity (γ : ℝ → M) (t : ℝ) : TangentBundle I M := ⟨γ t, mfderiv% γ t (1 : ℝ)⟩ + +@[simp] +lemma proj_velocity (γ : ℝ → M) (t : ℝ) : (velocity I γ t).proj = γ t := rfl + +lemma IsMIntegralCurveAt.mdifferentiableAt (h : IsMIntegralCurveAt γ v t₀) : + ∀ᶠ t in 𝓝 t₀, MDiffAt γ t := by + filter_upwards [h] with t ht + exact ht.mdifferentiableAt + +set_option backward.isDefEq.respectTransparency false in +protected lemma IsMIntegralCurveAt.mfderiv (hγ : IsMIntegralCurveAt γ v t₀) : + ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by + filter_upwards [hγ] with t ht + rw [ht.mfderiv] + rw [ContinuousLinearMap.smulRight_apply] + change 1 • v (γ t) = v (γ t) + simp + +protected lemma IsMIntegralCurveAt.velocity_eventuallyEq + (hγ : IsMIntegralCurveAt γ v t₀) : velocity I γ =ᶠ[𝓝 t₀] T%v ∘ γ := by + filter_upwards [hγ.mfderiv] with t ht + simp [ht, velocity] + +-- Is this really missing?? +lemma IsMIntegralCurveAt_iff_mfderiv (hγ : ∀ᶠ t in 𝓝 t₀, MDiffAt γ t) : + IsMIntegralCurveAt γ v t₀ ↔ ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by + refine ⟨fun h ↦ h.mfderiv, fun h ↦ ?_⟩ + filter_upwards [hγ.and h] with t ⟨ht, ht'⟩ + rw [← ht'] + convert ht.hasMFDerivAt + ext + simp + rfl + +lemma IsMIntegralCurveAt.eventually_isMIntegralCurveAt + {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} + (hγX : IsMIntegralCurveAt γ X t₀) : + ∀ᶠ t in 𝓝 t₀, IsMIntegralCurveAt γ X t := + eventually_eventually_nhds.2 hγX + +variable [IsManifold I 1 M] + +set_option linter.flexible false in --FIXME +lemma IsMIntegralCurveAt.acceleration {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) + (hγX : IsMIntegralCurveAt γ X t₀) : + velocity I.tangent (velocity I γ) t₀ = mfderiv% (T% X) (γ t₀) (X (γ t₀)) := by + have : velocity I γ =ᶠ[𝓝 t₀] T%X ∘ γ := hγX.velocity_eventuallyEq + have := this.mfderiv_eq (I := 𝓘(ℝ, ℝ)) (I' := I.tangent) + have foo := EventuallyEq.eq_of_nhds hγX.mfderiv + simp [velocity, this, foo] + have := hγX.mdifferentiableAt.self_of_nhds + rw [mfderiv_comp t₀ hX this, ← foo] + rfl + +lemma IsMIntegralCurveAt.eventually_acceleration {X : Π x : M, TangentSpace I x} + {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) + (hγX : IsMIntegralCurveAt γ X t₀) : + ∀ᶠ t in 𝓝 t₀, velocity I.tangent (velocity I γ) t = mfderiv% (T% X) (γ t) (X (γ t)) := by + filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t hXt hγXt + exact acceleration hXt hγXt + +-- FIXME: bug in `mfderiv%`? +-- FIXME: missing elaborator support to find I.tangent +variable (I) in +@[simp] +lemma proj_acceleration {γ : ℝ → M} {t : ℝ} (h : MDiffAt (velocity I γ) t) : + mfderiv I.tangent I (TotalSpace.proj : TangentBundle I M → M) + (velocity I γ t) (velocity I.tangent (velocity I γ) t).2 = (velocity +I γ t).2 := by + have comp_eq: (TotalSpace.proj : TangentBundle I M → M) ∘ (velocity I γ) = γ := by + ext t + simp + have diff : MDifferentiableAt I.tangent I (TotalSpace.proj : TangentBundle I M → M) + (velocity I γ t) := by + exact mdifferentiableAt_proj (TangentSpace I) + have := mfderiv_comp t diff h + rw [comp_eq] at this + exact congr($this (1 : ℝ)).symm + diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index fc8370daef3800..3fd2e5a3696bab 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -1,12 +1,11 @@ /- Copyright (c) 2025 Patrick Massot. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Patrick Massot, Michael Rothgang +Authors: Heather Macbeth, Patrick Massot, Michael Rothgang -/ module public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann -public import Mathlib.Geometry.Manifold.IntegralCurve.Basic /-! # Lifting vectors using covariant derivatives @@ -21,14 +20,6 @@ open Bundle Filter Module Topology Set open scoped Bundle Manifold ContDiff -section -variable {B : Type*} (E : B → Type*) {F : Type*} - -/-- Given a bundle `π : E → B`, the diagonal section of `π^*E → E`. -/ -def Bundle.pullback_diag (e : TotalSpace F E) : (TotalSpace.proj *ᵖ E) e := - e.2 -end - section variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] @@ -109,7 +100,7 @@ lemma CovariantDerivative.lift_vec_apply {v : TotalSpace F V} (u : TangentSpace cov.lift_vec v u = t.derivInv I v (tlift u) := rfl @[simp] -lemma CovariantDerivative.lift_vec_horiz {v : TotalSpace F V} (u : TangentSpace I v.proj) : +lemma CovariantDerivative.lift_vec_mem_horiz {v : TotalSpace F V} (u : TangentSpace I v.proj) : cov.lift_vec v u ∈ cov.horiz v := by let t := trivializationAt F V v.proj have hcov := cov.isCovariantDerivativeOn_pushCovDer t @@ -126,7 +117,7 @@ lemma CovariantDerivative.lift_vec_horiz {v : TotalSpace F V} (u : TangentSpace lemma CovariantDerivative.proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : cov.proj v (cov.lift_vec v u) = 0 := by rw [← cov.mem_horiz_iff_proj] - exact lift_vec_horiz u + exact lift_vec_mem_horiz u @[simp] lemma CovariantDerivative.mfderiv_proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : @@ -202,184 +193,4 @@ lemma CovariantDerivative.lift_vec_eq [FiniteDimensional 𝕜 E] {v : TotalSpace e.symm_map_zero 𝕜] · simp [hv] --- noncomputable --- def CovariantDerivative.lift_vec' --- (p : TotalSpace E ((TotalSpace.proj : (TotalSpace F V → M)) *ᵖ (TangentSpace I))) : --- TangentSpace (I.prod 𝓘(𝕜, F)) p.1 := --- letI t := trivializationAt F V p.1.proj --- haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn --- (cov.isCovariantDerivativeOn.mono fun _ _ ↦ mem_univ _) --- letI tlift := d_covDerOn.lift_vec p.1.proj (t p.1).2 --- t.derivInv I p.1 (tlift p.2) end - -section integralCurve -variable - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} - [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} - [TopologicalSpace M] [ChartedSpace H M] (γ : ℝ → M) - (v : (x : M) → TangentSpace I x) (t₀ : ℝ) - -variable (I) in -noncomputable -def velocity (γ : ℝ → M) (t : ℝ) : TangentBundle I M := ⟨γ t, mfderiv% γ t (1 : ℝ)⟩ - -@[simp] -lemma proj_velocity (γ : ℝ → M) (t : ℝ) : (velocity I γ t).proj = γ t := rfl - -lemma IsMIntegralCurveAt.mdifferentiableAt (h : IsMIntegralCurveAt γ v t₀) : - ∀ᶠ t in 𝓝 t₀, MDiffAt γ t := by - filter_upwards [h] with t ht - exact ht.mdifferentiableAt - -set_option backward.isDefEq.respectTransparency false in -protected lemma IsMIntegralCurveAt.mfderiv (hγ : IsMIntegralCurveAt γ v t₀) : - ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by - filter_upwards [hγ] with t ht - rw [ht.mfderiv] - rw [ContinuousLinearMap.smulRight_apply] - change 1 • v (γ t) = v (γ t) - simp - -protected lemma IsMIntegralCurveAt.velocity_eventuallyEq - (hγ : IsMIntegralCurveAt γ v t₀) : velocity I γ =ᶠ[𝓝 t₀] T%v ∘ γ := by - filter_upwards [hγ.mfderiv] with t ht - simp [ht, velocity] - --- Is this really missing?? -lemma IsMIntegralCurveAt_iff_mfderiv (hγ : ∀ᶠ t in 𝓝 t₀, MDiffAt γ t) : - IsMIntegralCurveAt γ v t₀ ↔ ∀ᶠ t in 𝓝 t₀, mfderiv% γ t (1 : ℝ) = v (γ t) := by - refine ⟨fun h ↦ h.mfderiv, fun h ↦ ?_⟩ - filter_upwards [hγ.and h] with t ⟨ht, ht'⟩ - rw [← ht'] - convert ht.hasMFDerivAt - ext - simp - rfl - -lemma IsMIntegralCurveAt.eventually_isMIntegralCurveAt - {X : Π x : M, TangentSpace I x} {γ : ℝ → M} {t₀ : ℝ} - (hγX : IsMIntegralCurveAt γ X t₀) : - ∀ᶠ t in 𝓝 t₀, IsMIntegralCurveAt γ X t := - eventually_eventually_nhds.2 hγX - -variable [IsManifold I 1 M] - -set_option linter.flexible false in --FIXME -lemma IsMIntegralCurveAt.acceleration {X : Π x : M, TangentSpace I x} - {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) - (hγX : IsMIntegralCurveAt γ X t₀) : - velocity I.tangent (velocity I γ) t₀ = mfderiv% (T% X) (γ t₀) (X (γ t₀)) := by - have : velocity I γ =ᶠ[𝓝 t₀] T%X ∘ γ := hγX.velocity_eventuallyEq - have := this.mfderiv_eq (I := 𝓘(ℝ, ℝ)) (I' := I.tangent) - have foo := EventuallyEq.eq_of_nhds hγX.mfderiv - simp [velocity, this, foo] - have := hγX.mdifferentiableAt.self_of_nhds - rw [mfderiv_comp t₀ hX this, ← foo] - rfl - -lemma IsMIntegralCurveAt.eventually_acceleration {X : Π x : M, TangentSpace I x} - {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) - (hγX : IsMIntegralCurveAt γ X t₀) : - ∀ᶠ t in 𝓝 t₀, velocity I.tangent (velocity I γ) t = mfderiv% (T% X) (γ t) (X (γ t)) := by - filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t hXt hγXt - exact acceleration hXt hγXt - -end integralCurve - -section geodesics - -variable - {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] - {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] - [ChartedSpace H M] - [IsManifold I 2 M] - (cov : CovariantDerivative I E (TangentSpace I : M → Type _)) - --- FIXME: bug in `mfderiv%`? --- FIXME: missing elaborator support to find I.tangent -variable (I) in -@[simp] -lemma proj_acceleration {γ : ℝ → M} {t : ℝ} (h : MDiffAt (velocity I γ) t) : - mfderiv I.tangent I (TotalSpace.proj : TangentBundle I M → M) - (velocity I γ t) (velocity I.tangent (velocity I γ) t).2 = (velocity -I γ t).2 := by - have comp_eq: (TotalSpace.proj : TangentBundle I M → M) ∘ (velocity I γ) = γ := by - ext t - simp - have diff : MDifferentiableAt I.tangent I (TotalSpace.proj : TangentBundle I M → M) - (velocity I γ t) := by - exact mdifferentiableAt_proj (TangentSpace I) - have := mfderiv_comp t diff h - rw [comp_eq] at this - exact congr($this (1 : ℝ)).symm - -variable [FiniteDimensional ℝ E] - -lemma IsMIntegralCurveAt.proj_acceleration {X : Π x : M, TangentSpace I x} - {γ : ℝ → M} {t₀ : ℝ} (hX : MDiffAt (T% X) (γ t₀)) - (hγX : IsMIntegralCurveAt γ X t₀) : - cov.proj _ (velocity I.tangent (velocity I γ) t₀).2 = cov X (γ t₀) (X (γ t₀)) := by - rw [hγX.acceleration hX, cov.proj_mderiv _ hX] - simp - -noncomputable -def CovariantDerivative.geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : - TangentSpace (I.prod 𝓘(ℝ, E)) v := cov.lift_vec v v.2 - -@[simp] -lemma CovariantDerivative.geodVF_horiz (v : TotalSpace E (TangentSpace I : M → Type _)) : - cov.geodVF v ∈ cov.horiz v := by - simp [CovariantDerivative.geodVF] - -@[simp] -lemma CovariantDerivative.proj_geodVF (v : TotalSpace E (TangentSpace I : M → Type _)) : - cov.proj v (cov.geodVF v) = 0 := by - simp [CovariantDerivative.geodVF] - -/-- A curve `γ : ℝ → M` is a geodesic for `cov` at `t` if it is an integral -curve of the geodesic vector field of `cov` near `t`. -Remember: `IsMIntegralCurveAt` is local, not pointwise. -/ -def CovariantDerivative.isGeodAt (γ : ℝ → M) (t : ℝ) := - IsMIntegralCurveAt (velocity I γ) cov.geodVF t - -set_option backward.isDefEq.respectTransparency false in -lemma CovariantDerivative.isGeodAt_iff_horiz {γ : ℝ → M} {t₀ : ℝ} - (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : - cov.isGeodAt γ t₀ ↔ - ∀ᶠ (t : ℝ) in 𝓝 t₀, (velocity I.tangent (velocity I γ) t).2 ∈ cov.horiz _ := by - unfold CovariantDerivative.isGeodAt CovariantDerivative.geodVF - rw [IsMIntegralCurveAt_iff_mfderiv _ _ _ hγ] - refine eventually_congr ?_ - filter_upwards [hγ] with t ht - conv_lhs => rw [Eq.comm, cov.lift_vec_eq_iff (velocity I γ t).2] - rw [← cov.mem_horiz_iff_proj, proj_velocity, - show mfderiv% (velocity I γ) t (1 : ℝ) = (velocity I.tangent (velocity I γ) t).2 from - rfl, -- TODO need a simp lemma here? - ] - -- TODO: understand why - -- simp [proj_velocity, proj_acceleration I ht] - -- doesn’t close the goal - simp only [proj_velocity, and_iff_left_iff_imp] - exact fun _ ↦ proj_acceleration I ht - -lemma CovariantDerivative.isGeodAt_iff_proj {γ : ℝ → M} {t₀ : ℝ} - (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) : - cov.isGeodAt γ t₀ ↔ - ∀ᶠ (t : ℝ) in 𝓝 t₀, cov.proj _ (velocity I.tangent (velocity I γ) t).2 = 0 := - cov.isGeodAt_iff_horiz hγ - -def CovariantDerivative.isGeod (γ : ℝ → M) := ∀ t, cov.isGeodAt γ t - -set_option backward.isDefEq.respectTransparency false in -lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} - {γ : ℝ → M} {t₀ : ℝ} (hX : ∀ᶠ t in 𝓝 t₀, MDiffAt (T% X) (γ t)) - (hγ : ∀ᶠ (t : ℝ) in 𝓝 t₀, MDiffAt (velocity I γ) t) - (hγX : IsMIntegralCurveAt γ X t₀) : - cov.isGeodAt γ t₀ ↔ ∀ᶠ t in 𝓝 t₀, cov X (γ t) (X (γ t)) = 0 := by - rw [cov.isGeodAt_iff_proj hγ] - refine eventually_congr ?_ - filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t ht ht' - rw [ht'.proj_acceleration cov ht] - -end geodesics From a612d0b6153dacba3494ea6f933ba013c64ba2a3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:12:10 +0000 Subject: [PATCH 601/601] [pre-commit.ci lite] apply automatic fixes --- .../Manifold/VectorBundle/CovariantDerivative/Geodesics.lean | 1 - .../VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean | 1 - 2 files changed, 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean index f671d13ea33cc0..0aeb17de89fd81 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean @@ -95,4 +95,3 @@ lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} refine eventually_congr ?_ filter_upwards [hX, hγX.eventually_isMIntegralCurveAt] with t ht ht' rw [ht'.proj_acceleration cov ht] - diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean index e28ee4137f4bb3..c762b2b4f68fc0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean @@ -106,4 +106,3 @@ I γ t).2 := by have := mfderiv_comp t diff h rw [comp_eq] at this exact congr($this (1 : ℝ)).symm -