From 8c1ff478bebcd04319bce051fdb041d90320a2d9 Mon Sep 17 00:00:00 2001 From: Patrick Massot Date: Fri, 20 Jun 2025 15:53:47 +0200 Subject: [PATCH 001/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] =?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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] =?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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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/441] 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 4ab2b9b5516bbb5be9671d680eaabd69cf40d350 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 13:29:25 +0000 Subject: [PATCH 425/441] chore: more simp lemmas --- Mathlib/Topology/FiberBundle/Trivialization.lean | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index 82202cef4c4db4..d548495e83603e 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -122,9 +122,11 @@ theorem coe_fst' (ex : proj x ∈ e.baseSet) : (e x).1 = proj x := protected theorem eqOn : EqOn (Prod.fst ∘ e) proj e.source := fun _ hx => e.coe_fst hx +@[simp] theorem mk_proj_snd (ex : x ∈ e.source) : (proj x, (e x).2) = e x := Prod.ext (e.coe_fst ex).symm rfl +@[simp] theorem mk_proj_snd' (ex : proj x ∈ e.baseSet) : (proj x, (e x).2) = e x := Prod.ext (e.coe_fst' ex).symm rfl @@ -148,6 +150,7 @@ theorem proj_surjOn_baseSet [Nonempty F] : Set.SurjOn proj e.source e.baseSet := ⟨e.toPartialEquiv.symm (b, y), e.toPartialEquiv.map_target <| e.mem_target.2 hb, e.proj_symm_apply' hb⟩ +@[simp] theorem apply_symm_apply {x : B × F} (hx : x ∈ e.target) : e (e.toPartialEquiv.symm x) = x := e.toPartialEquiv.right_inv hx @@ -155,10 +158,10 @@ theorem apply_symm_apply' {b : B} {x : F} (hx : b ∈ e.baseSet) : e (e.toPartialEquiv.symm (b, x)) = (b, x) := e.apply_symm_apply (e.mem_target.2 hx) +@[simp, mfld_simps] theorem symm_apply_apply {x : Z} (hx : x ∈ e.source) : e.toPartialEquiv.symm (e x) = x := e.toPartialEquiv.left_inv hx -@[simp, mfld_simps] theorem symm_apply_mk_proj {x : Z} (ex : x ∈ e.source) : e.toPartialEquiv.symm (proj x, (e x).2) = x := by rw [← e.coe_fst ex, ← e.coe_coe, e.left_inv ex] From 2708cf233cc0dbb65c9b358a0ab205f7b80bbb93 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 15:50:16 +0000 Subject: [PATCH 426/441] chore: rephrase a TODO --- the current phrasing took me a moment to parse --- Mathlib/Topology/FiberBundle/Trivialization.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index d548495e83603e..a3dd39f4e74c3e 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -91,7 +91,7 @@ lemma ext' (e e' : Pretrivialization F proj) (h₁ : e.toPartialEquiv = e'.toPar (h₂ : e.baseSet = e'.baseSet) : e = e' := by cases e; cases e'; congr --- TODO: move `ext` here? +-- TODO: tag this lemma with the `ext` attribute instead? lemma ext {e e' : Pretrivialization F proj} (h₁ : ∀ x, e x = e' x) (h₂ : ∀ x, e.toPartialEquiv.symm x = e'.toPartialEquiv.symm x) (h₃ : e.baseSet = e'.baseSet) : e = e' := by From f2685468e79daecf5df34db78c9a71e274510de8 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 16:06:43 +0000 Subject: [PATCH 427/441] More --- .../Topology/FiberBundle/Trivialization.lean | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/FiberBundle/Trivialization.lean b/Mathlib/Topology/FiberBundle/Trivialization.lean index a3dd39f4e74c3e..d87dcd82cb22aa 100644 --- a/Mathlib/Topology/FiberBundle/Trivialization.lean +++ b/Mathlib/Topology/FiberBundle/Trivialization.lean @@ -150,10 +150,11 @@ theorem proj_surjOn_baseSet [Nonempty F] : Set.SurjOn proj e.source e.baseSet := ⟨e.toPartialEquiv.symm (b, y), e.toPartialEquiv.map_target <| e.mem_target.2 hb, e.proj_symm_apply' hb⟩ -@[simp] +@[simp, mfld_simps] theorem apply_symm_apply {x : B × F} (hx : x ∈ e.target) : e (e.toPartialEquiv.symm x) = x := e.toPartialEquiv.right_inv hx +@[simp, mfld_simps] theorem apply_symm_apply' {b : B} {x : F} (hx : b ∈ e.baseSet) : e (e.toPartialEquiv.symm (b, x)) = (b, x) := e.apply_symm_apply (e.mem_target.2 hx) @@ -217,6 +218,7 @@ theorem coe_coe_fst (hb : b ∈ e'.baseSet) : (e' y).1 = b := by theorem mk_mem_target {x : B} {y : F} : (x, y) ∈ e'.target ↔ x ∈ e'.baseSet := e'.mem_target +@[simp, mfld_simps] theorem symm_coe_proj {x : B} {y : F} (e' : Pretrivialization F (π F E)) (h : x ∈ e'.baseSet) : (e'.toPartialEquiv.symm (x, y)).1 = x := e'.proj_symm_apply' h @@ -249,15 +251,17 @@ theorem mk_symm (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet TotalSpace.mk b (e.symm b y) = e.toPartialEquiv.symm (b, y) := by simp only [e.symm_apply hb, TotalSpace.mk_cast (e.proj_symm_apply' hb), TotalSpace.eta] +@[simp, mfld_simps] theorem symm_proj_apply (e : Pretrivialization F (π F E)) (z : TotalSpace F E) (hz : z.proj ∈ e.baseSet) : e.symm z.proj (e z).2 = z.2 := by rw [e.symm_apply hz, cast_eq_iff_heq, e.mk_proj_snd' hz, e.symm_apply_apply (e.mem_source.mpr hz)] +@[simp, mfld_simps] theorem symm_apply_apply_mk (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : E b) : e.symm b (e ⟨b, y⟩).2 = y := e.symm_proj_apply ⟨b, y⟩ hb -@[simp] +@[simp, mfld_simps] theorem apply_mk_symm (e : Pretrivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : F) : e ⟨b, e.symm b y⟩ = (b, y) := by rw [e.mk_symm hb, e.apply_symm_apply (e.mk_mem_target.mpr hb)] @@ -423,6 +427,7 @@ protected theorem eqOn : EqOn (Prod.fst ∘ e) proj e.source := fun _x hx => e.c theorem mem_source : x ∈ e.source ↔ proj x ∈ e.baseSet := by rw [e.source_eq, mem_preimage] +@[simp, mfld_simps] theorem coe_fst' (ex : proj x ∈ e.baseSet) : (e x).1 = proj x := e.coe_fst (e.mem_source.2 ex) @@ -458,10 +463,12 @@ theorem proj_symm_apply' {b : B} {x : F} (hx : b ∈ e.baseSet) : theorem proj_surjOn_baseSet [Nonempty F] : Set.SurjOn proj e.source e.baseSet := e.toPretrivialization.proj_surjOn_baseSet +@[simp, mfld_simps] theorem apply_symm_apply {x : B × F} (hx : x ∈ e.target) : e (e.toOpenPartialHomeomorph.symm x) = x := e.toOpenPartialHomeomorph.right_inv hx +@[simp, mfld_simps] theorem apply_symm_apply' {b : B} {x : F} (hx : b ∈ e.baseSet) : e (e.toOpenPartialHomeomorph.symm (b, x)) = (b, x) := e.toPretrivialization.apply_symm_apply' hx @@ -636,13 +643,13 @@ protected theorem continuousOn : ContinuousOn e' e'.source := theorem coe_mem_source : ↑y ∈ e'.source ↔ b ∈ e'.baseSet := e'.mem_source -@[simp, mfld_simps] theorem coe_coe_fst (hb : b ∈ e'.baseSet) : (e' y).1 = b := e'.coe_fst (e'.mem_source.2 hb) theorem mk_mem_target {y : F} : (b, y) ∈ e'.target ↔ b ∈ e'.baseSet := e'.toPretrivialization.mem_target +@[simp, mfld_simps] theorem symm_apply_apply {x : TotalSpace F E} (hx : x ∈ e'.source) : e'.toOpenPartialHomeomorph.symm (e' x) = x := e'.toPartialEquiv.left_inv hx @@ -674,10 +681,12 @@ theorem mk_symm (e : Trivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) ( TotalSpace.mk b (e.symm b y) = e.toOpenPartialHomeomorph.symm (b, y) := e.toPretrivialization.mk_symm hb y +@[simp, mfld_simps] theorem symm_proj_apply (e : Trivialization F (π F E)) (z : TotalSpace F E) (hz : z.proj ∈ e.baseSet) : e.symm z.proj (e z).2 = z.2 := e.toPretrivialization.symm_proj_apply z hz +@[simp, mfld_simps] theorem symm_apply_apply_mk (e : Trivialization F (π F E)) {b : B} (hb : b ∈ e.baseSet) (y : E b) : e.symm b (e ⟨b, y⟩).2 = y := e.symm_proj_apply ⟨b, y⟩ hb @@ -734,6 +743,7 @@ theorem coordChange_apply_snd (e₁ e₂ : Trivialization F proj) {p : Z} (h : p e₁.coordChange e₂ (proj p) (e₁ p).snd = (e₂ p).snd := by rw [coordChange, e₁.symm_apply_mk_proj (e₁.mem_source.2 h)] +@[simp, mfld_simps] theorem coordChange_same_apply (e : Trivialization F proj) {b : B} (h : b ∈ e.baseSet) (x : F) : e.coordChange e b x = x := by rw [coordChange, e.apply_symm_apply' h] @@ -891,7 +901,7 @@ noncomputable def piecewiseLe [LinearOrder B] [OrderTopology B] (e e' : Triviali e.piecewiseLeOfEq (e'.transFiberHomeomorph (e'.coordChangeHomeomorph e He' He)) a He He' <| by rintro p rfl ext1 - · simp [e.coe_fst', e'.coe_fst', *] + · simp [*] · simp [coordChange_apply_snd, *] open Classical in From e40890d54d8e461debe1412556a6b8a2d15c3366 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Tue, 24 Feb 2026 19:23:10 +0100 Subject: [PATCH 428/441] chore: cherry-pick local frames changes --- Mathlib/Algebra/Module/Equiv/Basic.lean | 24 + .../Manifold/VectorBundle/LocalFrame.lean | 513 ++++++++---------- 2 files changed, 240 insertions(+), 297 deletions(-) diff --git a/Mathlib/Algebra/Module/Equiv/Basic.lean b/Mathlib/Algebra/Module/Equiv/Basic.lean index 3f4e8a80ae09ba..fb9235b79f1be9 100644 --- a/Mathlib/Algebra/Module/Equiv/Basic.lean +++ b/Mathlib/Algebra/Module/Equiv/Basic.lean @@ -321,6 +321,30 @@ end AddEquiv namespace LinearMap +/-- Pointwise application of a family of linear forms to a family of vectors -/ +def piApply {V : M → Type*} [CommSemiring R] [∀ x, AddCommMonoid (V x)] [∀ x, Module R (V x)] : + (Π x : M, V x →ₗ[R] R) →ₗ[R] (Π x : M, V x) →ₗ[R] M → R where + toFun e := + { toFun s x := e x (s x) + map_add' := by intros; ext; simp + map_smul' := by intros; ext; simp } + map_add' := by intros; ext; simp + map_smul' := by intros; ext; simp + +@[simp] +theorem piApply_apply {V : M → Type*} + [CommSemiring R] [∀ x, AddCommMonoid (V x)] [∀ x, Module R (V x)] + (e : Π x : M, V x →ₗ[R] R) (s : Π x : M, V x) : + piApply e s = fun x ↦ e x (s x) := + rfl + +@[simp] +theorem piApply_apply_apply {V : M → Type*} + [CommSemiring R] [∀ x, AddCommMonoid (V x)] [∀ x, Module R (V x)] + (e : Π x : M, V x →ₗ[R] R) (s : Π x : M, V x) (x : M) : + piApply e s x = e x (s x) := + rfl + variable (R S M) variable [Semiring R] [Semiring S] [AddCommMonoid M] [Module R M] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index dc3860b5708ae1..66e765ff945959 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -44,41 +44,43 @@ smooth on the trivialisation domain. 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 → 𝕜`. + `hs.coeff i` is a family of fiberwise linear maps `Π x, V x →ₗ[𝕜] 𝕜`. + The coefficient function of a section `t` is `(LinearMap.piApply (hs.coeff i)) t`. * `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`. + for each section `t` we have `t = ∑ i, (LinearMap.piApply (hs.coeff i) t) • sᵢ` near `x`. +* `IsLocalFrameOn.coeff_sum_eq hs t hx` proves that + `t x = ∑ i, hs.coeff i x (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` + `(LinearMap.piApply (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_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 +In the following lemmas, let `e` be a compatible local trivialisation of `V`, and `b` a basis of +the model fiber `F`. +* `Trivialization.basisAt e b`: for each `x ∈ e.baseSet`, + return the basis of `V x` induced by `e` and `b` +* `e.localFrame b`: the local frame on `V` induced by `e` and `b`. + Use `e.localFrame b i` to access the i-th section in that frame. +* `e.contMDiffOn_localFrame_baseSet`: each section `e.localFrame b i` is smooth on `e.baseSet` +* `e.localFrame_coeff b i` describes the `i`-th coefficient of sections of `V` w.r.t. + `e.localFrame b`: it is a family of fiberwise linear maps `Π x, V x →ₗ[𝕜] 𝕜`, and the coefficient + function of a section `s` is `(LinearMap.piApply (e.localFrame_coeff b i)) s`. +* `e.eventually_eq_localFrame_sum_coeff_smul b`: near `x`, we have + `s = ∑ i, (LinearMap.piApply (e.localFrame_coeff b i) s) • e.localFrame b i` +* `e.localFrame_coeff_congr b`: the coefficient `e.localFrame_coeff b i` of `s` in the local frame induced by `e` and `b` at `x` only depends on `s` at `x`. -* `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` +* `e.contMDiffOn_localFrame_coeff`: if `s` is a `C^k` section, each coefficient + `(LinearMap.piApply (e.localFrame_coeff b i) s)` is `C^k` on `e.baseSet` +* `e.contMDiffAt_iff_localFrame_coeff b`: a section `s` is `C^k` at `x ∈ e.baseSet` iff all of its frame coefficients are -* `b.contMDiffOn_iff_localFrame_coeff e`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` +* `e.contMDiffOn_iff_localFrame_coeff b`: a section `s` is `C^k` on an open set `t ⊆ e.baseSet` iff all of its frame coefficients are A local frame can be used to extend any single vector `v : V x` to a section which is smooth near @@ -93,24 +95,10 @@ A local frame can be used to extend any single vector `v : V x` to a section whi `v ↦ localExtensionON b e v` is a linear map. -In the following lemmas, let `e` be a compatible local trivialisation of `V`, and `b` a basis of -the model fiber `F`. -* `Trivialization.basisAt e b`: for each `x ∈ e.baseSet`, - return the basis of `V x` induced by `e` and `b` -* `e.localFrame b`: the local frame on `V` induced by `e` and `b`. - Use `e.localFrame b i` to access the i-th section in that frame. -* `e.contMDiffOn_localFrame_baseSet`: each section `e.localFrame b i` is smooth on `e.baseSet` - -## TODO +## Note -Strengthen the proof of smoothness in terms of the local frame coefficients. -* `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 +This file proves smoothness criteria in terms of coefficients for local frames induced by a +trivialization. A fully frame-intrinsic converse for `IsLocalFrameOn` will be added later. ## Implementation notes @@ -217,101 +205,98 @@ alias fintype_of_finiteDimensional := fintypeOfFiniteDimensional 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. -/ -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 - by_cases hx : x ∈ u <;> simp [hx] - map_smul' c s := by - ext x - by_cases hx : x ∈ u <;> simp [hx] +def coeff (hs : IsLocalFrameOn I F n s u) (i : ι) : Π x : M, (V x →ₗ[𝕜] 𝕜) := fun x ↦ + if hx : x ∈ u then (hs.toBasisAt hx).coord i else 0 variable {x : M} @[simp] -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 +lemma coeff_apply_of_notMem (hs : IsLocalFrameOn I F n s u) (hx : x ∉ u) (i : ι) : + hs.coeff i x = 0 := by simp [coeff, hx] @[simp] 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 + hs.coeff i x (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 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 + t x = ∑ i, hs.coeff i x (t x) • (s i x) := by simpa [coeff, hx] using (Basis.sum_repr (hs.toBasisAt hx) (t x)).symm +lemma eq_of_coeff_eq [Finite ι] (hs : IsLocalFrameOn I F n s u) (hx : x ∈ u) + {t t' : Π x : M, V x} + (h : ∀ i, hs.coeff i x (t x) = hs.coeff i x (t' x)) : + t x = t' x := by + let : Fintype ι := Fintype.ofFinite ι + calc + t x = ∑ i, hs.coeff i x (t x) • (s i x) := hs.coeff_sum_eq t hx + _ = ∑ i, hs.coeff i x (t' x) • (s i x) := by simp [h] + _ = t' x := (hs.coeff_sum_eq t' hx).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.coeff i t) • (s i x)` near `x`. -/ +set `u` around `x`, we have `t = ∑ i, hs.coeff i x (t x) • (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') := + ∀ᶠ x' in 𝓝 x, t x' = ∑ i, hs.coeff i x' (t x') • (s i x') := eventually_of_mem hu'' fun _ hx ↦ hs.coeff_sum_eq _ hx 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 [coeff, hxe] - congr - · simp [coeff, hxe] + hs.coeff i x (t x) = hs.coeff i x (t' x) := by + by_cases hxe : x ∈ u <;> simp [coeff, hxe, htt'] /-- If `s` and `s'` are local frames which are equal at `x`, a section `t` has equal frame coefficients in them. -/ 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.coeff i t x = hs'.coeff i t x := by + hs.coeff i x (t x) = hs'.coeff i x (t x) := by by_cases hxe : x ∈ u · simp [coeff, hxe] - simp_all [toBasisAt] + simp_all only [toBasisAt] · 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_coeff [VectorBundle 𝕜 F V] [FiniteDimensional 𝕜 F] (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 := by - have := fintypeOfFiniteDimensional hs hx - exact ⟨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 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] + t x = t' x ↔ ∀ i, hs.coeff i x (t x) = hs.coeff i x (t' x) := by + let := fintypeOfFiniteDimensional hs hx + exact ⟨fun h i ↦ hs.coeff_congr h i, fun h ↦ hs.eq_of_coeff_eq hx h⟩ 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_coeff [FiniteDimensional 𝕜 F] (h : ∀ i, CMDiff[u] n (hs.coeff i t)) : +lemma contMDiffOn_of_coeff [FiniteDimensional 𝕜 F] + (h : ∀ i, CMDiff[u] n ((LinearMap.piApply (hs.coeff i)) t)) : CMDiff[u] n (T% t) := by rcases u.eq_empty_or_nonempty with rfl | ⟨x, hx⟩; · simp have := fintypeOfFiniteDimensional hs hx - have this (i) : CMDiff[u] n (T% (hs.coeff i t • s i)) := + have this (i) : CMDiff[u] n (T% ((LinearMap.piApply (hs.coeff i)) t • s i)) := (h i).smul_section (hs.contMDiffOn i) - have almost : CMDiff[u] n (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) := + have almost : CMDiff[u] n (T% (fun x ↦ ∑ i, ((LinearMap.piApply (hs.coeff i)) t) x • s i x)) := .sum_section fun i _ ↦ this i apply almost.congr intro y hy - simp [hs.coeff_sum_eq t hy] + simpa using congrArg (TotalSpace.mk' F y) (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_coeff [FiniteDimensional 𝕜 F] - (h : ∀ i, CMDiffAt n (hs.coeff i t) x) (hu : u ∈ 𝓝 x) : CMDiffAt n (T% t) x := by + (h : ∀ i, CMDiffAt n ((LinearMap.piApply (hs.coeff i)) t) x) (hu : u ∈ 𝓝 x) : + CMDiffAt n (T% t) x := by have := fintypeOfFiniteDimensional hs (mem_of_mem_nhds hu) - have almost : CMDiffAt n (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) x := + have almost : CMDiffAt n (T% (fun x ↦ ∑ i, ((LinearMap.piApply (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_coeff_aux [FiniteDimensional 𝕜 F] (h : ∀ i, CMDiffAt n (hs.coeff i t) x) +lemma contMDiffAt_of_coeff_aux [FiniteDimensional 𝕜 F] + (h : ∀ i, CMDiffAt n ((LinearMap.piApply (hs.coeff i)) t) x) (hu : IsOpen u) (hx : x ∈ u) : CMDiffAt n (T% t) x := by have := fintypeOfFiniteDimensional hs hx exact hs.contMDiffAt_of_coeff h (hu.mem_nhds hx) @@ -322,31 +307,34 @@ 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_coeff [FiniteDimensional 𝕜 F] (h : ∀ i, MDiff[u] (hs.coeff i t)) : +lemma mdifferentiableOn_of_coeff [FiniteDimensional 𝕜 F] + (h : ∀ i, MDiff[u] ((LinearMap.piApply (hs.coeff i)) t)) : MDiff[u] (T% t) := by rcases u.eq_empty_or_nonempty with rfl | ⟨x, hx⟩; · simp have := fintypeOfFiniteDimensional hs hx - have this (i) : MDiff[u] (T% (hs.coeff i t • s i)) := + have this (i) : MDiff[u] (T% ((LinearMap.piApply (hs.coeff i)) t • s i)) := (h i).smul_section ((hs.contMDiffOn i).mdifferentiableOn one_ne_zero) - have almost : MDiff[u] (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) := + have almost : MDiff[u] (T% (fun x ↦ ∑ i, hs.coeff i x (t x) • s i x)) := .sum_section (fun i _ hx ↦ this i _ hx) apply almost.congr intro y hy - simp [hs.coeff_sum_eq t hy] + simpa using congrArg (TotalSpace.mk' F y) (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_coeff [FiniteDimensional 𝕜 F] - (h : ∀ i, MDiffAt (hs.coeff i t) x) (hu : u ∈ 𝓝 x) : MDiffAt (T% t) x := by + (h : ∀ i, MDiffAt ((LinearMap.piApply (hs.coeff i)) t) x) (hu : u ∈ 𝓝 x) : + MDiffAt (T% t) x := by have := fintypeOfFiniteDimensional hs (mem_of_mem_nhds hu) - have almost : MDiffAt (T% (fun x ↦ ∑ i, (hs.coeff i t) x • s i x)) x := + have almost : MDiffAt (T% (fun x ↦ ∑ i, hs.coeff i x (t x) • s i x)) x := .sum_section (fun i ↦ (h i).smul_section <| ((hs.contMDiffOn i).mdifferentiableOn one_ne_zero).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_coeff_aux [FiniteDimensional 𝕜 F] (h : ∀ i, MDiffAt (hs.coeff i t) x) +lemma mdifferentiableAt_of_coeff_aux [FiniteDimensional 𝕜 F] + (h : ∀ i, MDiffAt ((LinearMap.piApply (hs.coeff i)) t) x) (hu : IsOpen u) (hx : x ∈ u) : MDiffAt (T% t) x := hs.mdifferentiableAt_of_coeff h (hu.mem_nhds hx) @@ -356,152 +344,118 @@ end IsLocalFrameOn end IsLocalFrame -namespace Module.Basis +namespace Trivialization -variable {ι : Type*} {x : M} -variable [VectorBundle 𝕜 F V] +variable [VectorBundle 𝕜 F V] [ContMDiffVectorBundle n F V I] {ι : Type*} {x : M} + (e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)) [MemTrivializationAtlas e] + (b : Basis ι 𝕜 F) -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 (Trivialization.linearEquivAt (R := 𝕜) e x hx).symm +/-- Given a compatible local trivialisation `e` of `V` and a basis `b` of the model fiber `F`, +return the corresponding basis of `V x`. -/ +def basisAt (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 - -/-- Each local frame `s^i ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, +/-- The local frame on `V` induced by a compatible local trivialization `e` of `V` and a basis +`b` of the model fiber `F`. Use `e.localFrame b i` to access the `i`-th section in that frame. + +If `x` is outside of `e.baseSet`, this returns the junk value 0. -/ +def localFrame : ι → (x : M) → V x := + fun i x ↦ if hx : x ∈ e.baseSet then e.basisAt b hx i else 0 + +@[simp] +lemma localFrame_apply_of_mem_baseSet {i : ι} (hx : x ∈ e.baseSet) : + e.localFrame b i x = e.basisAt b hx i := by + simp [localFrame, hx] + +lemma localFrame_apply_of_notMem {i : ι} (hx : x ∉ e.baseSet) : e.localFrame b i x = 0 := by + simp [localFrame, hx] + +/-- Each local frame `{sᵢ} ∈ Γ(E)` of a `C^k` vector bundle, defined by a local trivialisation `e`, is `C^k` on `e.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 +lemma contMDiffOn_localFrame_baseSet (i : ι) : CMDiff[e.baseSet] n (T% (e.localFrame b i)) := by rw [e.contMDiffOn_section_baseSet_iff] apply (contMDiffOn_const (c := b i)).congr intro y hy - simp [localFrame, hy, localFrame_toBasis_at] + simp [hy, basisAt] variable (I) in /-- `b.localFrame e i` is indeed a local frame on `e.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 - contMDiffOn i := b.contMDiffOn_localFrame_baseSet _ e i +lemma isLocalFrameOn_localFrame_baseSet : IsLocalFrameOn I F n (e.localFrame b) e.baseSet where + contMDiffOn i := e.contMDiffOn_localFrame_baseSet _ b i linearIndependent := by intro x hx - convert (b.localFrame_toBasis_at e hx).linearIndependent - simp [localFrame, hx, localFrame_toBasis_at] + convert (e.basisAt b hx).linearIndependent + simp [hx, basisAt] generating := by intro x hx - convert (b.localFrame_toBasis_at e hx).span_eq.ge - simp [localFrame, hx, localFrame_toBasis_at] - -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 := - (b.localFrame_isLocalFrameOn_baseSet I n e).contMDiffAt e.open_baseSet hx _ + convert (e.basisAt b hx).span_eq.ge + simp [hx, basisAt] -@[simp] -lemma localFrame_apply_of_mem_baseSet - (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)) - [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 : ι} (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) (i : ι) (hx : x ∈ e.baseSet) : - b.localFrame_toBasis_at e hx i = b.localFrame e i x := by simp [hx] +lemma _root_.contMDiffAt_localFrame_of_mem (i : ι) (hx : x ∈ e.baseSet) : + CMDiffAt n (T% (e.localFrame b i)) x := + (e.isLocalFrameOn_localFrame_baseSet I n b).contMDiffAt e.open_baseSet hx _ 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. -/ -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).coeff i +def localFrame_coeff (i : ι) : Π x : M, (V x →ₗ[𝕜] 𝕜) := + (e.isLocalFrameOn_localFrame_baseSet I 1 b).coeff i -variable {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} +variable {e b} +variable {x x' : M} variable (e b) in @[simp] -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 +lemma localFrame_coeff_apply_of_notMem_baseSet (hx : x ∉ e.baseSet) (i : ι) : + e.localFrame_coeff I b i x = 0 := by simpa [localFrame_coeff] using - (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_apply_of_notMem hx s i + (e.isLocalFrameOn_localFrame_baseSet I 1 b).coeff_apply_of_notMem hx i variable (e b) in @[simp] 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.coeff_apply_of_mem hx s i -- XXX better variable name! + (localFrame_coeff I e b i x) (s x) = (e.basisAt b hx).repr (s x) i := by + have he := e.isLocalFrameOn_localFrame_baseSet I 1 b + have hbasis : e.basisAt b hx = he.toBasisAt hx := by + ext j + simp [IsLocalFrameOn.toBasisAt, localFrame, basisAt, hx] + simp [localFrame_coeff, IsLocalFrameOn.coeff, hx, hbasis] --- TODO: better name? -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 {s s' : Π x : M, V x} -variable (b) in +lemma eq_sum_localFrame_coeff_smul [Fintype ι] (hx : x' ∈ e.baseSet) : + s x' = ∑ i, e.localFrame_coeff I b i x' (s x') • e.localFrame b i x' := + (isLocalFrameOn_localFrame_baseSet I 1 e b).coeff_sum_eq s hx + +variable (e 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_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⟩ +of `V` around `x`, we have +`s = ∑ i, (LinearMap.piApply (b.localFrame_coeff e i) s) • b.localFrame e i` near `x`. -/ +lemma eventually_eq_localFrame_sum_coeff_smul [Fintype ι] (hxe : x ∈ e.baseSet) : + ∀ᶠ x' in 𝓝 x, s x' = ∑ i, e.localFrame_coeff I b i x' (s x') • e.localFrame b i x' := + eventually_nhds_iff.mpr ⟨e.baseSet, fun _ ↦ e.eq_sum_localFrame_coeff_smul, e.open_baseSet, hxe⟩ +variable (e b) 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) : - 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_coeff, hxe] - congr - · simp [localFrame_coeff, hxe] - -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 - simp only [localFrame_coeff] - exact (localFrame_isLocalFrameOn_baseSet I 1 e b).coeff_apply_zero_at hs i +lemma localFrame_coeff_congr {i : ι} (hss' : s x = s' x) : + e.localFrame_coeff I b i x (s x) = e.localFrame_coeff I b i x (s' x) := by + simpa using (isLocalFrameOn_localFrame_baseSet I 1 e b).coeff_congr hss' i variable {n} +variable (e) 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_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] +lemma localFrame_coeff_eq_coeff (hxe : x ∈ e.baseSet) {i : ι} : + e.localFrame_coeff I b i x (s x) = b.repr (e ((T% s) x)).2 i := by + simp [e.localFrame_coeff_apply_of_mem_baseSet b hxe, basisAt] -end Module.Basis +end Trivialization /-! # 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 @@ -510,96 +464,73 @@ in a local frame induced by a local trivialisation are. In many contexts, this s proven in `OrthonormalFrame.lean`). -/ -variable {ι : Type*} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {b : Basis ι 𝕜 F} {x : M} - [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] +variable [VectorBundle 𝕜 F V] [ContMDiffVectorBundle 1 F V I] + {e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)} [MemTrivializationAtlas e] + {ι : Type*} (b : Basis ι 𝕜 F) {s : Π x : M, V x} {t : Set M} {k : WithTop ℕ∞} {x x' : M} + [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] [ContMDiffVectorBundle k F V I] --- TODO: can this be proven more generally, for any 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_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_coeff I e i s) x := by +lemma contMDiffAt_localFrame_coeff (hxe : x ∈ e.baseSet) (hs : CMDiffAt k (T% s) x) (i : ι) : + CMDiffAt k ((LinearMap.piApply (e.localFrame_coeff I b 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. + -- step 1: on e.baseSet, we know compute the coefficient very well + let aux := fun x ↦ b.repr (e ((T% s) x)).2 i + -- Since `e.baseSet` is open, this is sufficient. 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 - simp [aux, Basis.localFrame_coeff_eq_coeff hy] + simp [aux, e.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 + have h₁ : CMDiffAt k (fun x ↦ (e ((T% s) x)).2) x := by + simpa using (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 →ₗ[𝕜] 𝕜 := { - 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₁ + let breprl : F →ₗ[𝕜] 𝕜 := + { toFun v := b.repr v i + map_add' m m' := by simp + map_smul' m x := by simp } + have : ContMDiffAt 𝓘(𝕜, F) 𝓘(𝕜) k breprl.toContinuousLinearMap (e ((T% s) x)).2 := + contMDiffAt_iff_contDiffAt.mpr <| by fun_prop + exact this.comp x h₁ /-- 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) - {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_coeff I e i s) := - fun _ hx ↦ (contMDiffAt_localFrame_coeff (ht' hx) b +lemma contMDiffOn_localFrame_coeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + (hs : CMDiff[t] k (T% s)) (i : ι) : + CMDiff[t] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := + fun _ hx ↦ (contMDiffAt_localFrame_coeff b (ht' hx) (hs.contMDiffAt (ht.mem_nhds hx)) i).contMDiffWithinAt /-- 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_coeff I e i s) := +lemma contMDiffOn_baseSet_localFrame_coeff (hs : CMDiff[e.baseSet] k (T% s)) (i : ι) : + CMDiff[e.baseSet] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := contMDiffOn_localFrame_coeff 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_coeff e i s` in a local frame near `x` is -/ -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' := - ⟨fun h i ↦ contMDiffAt_localFrame_coeff hx b h i, - fun hi ↦ (b.localFrame_isLocalFrameOn_baseSet I k e).contMDiffAt_of_coeff hi +coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ +lemma contMDiffAt_iff_localFrame_coeff (hx : x' ∈ e.baseSet) : + CMDiffAt k (T% s) x' ↔ ∀ i, CMDiffAt k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x' := + ⟨fun h i ↦ contMDiffAt_localFrame_coeff b hx h i, + fun hi ↦ (e.isLocalFrameOn_localFrame_baseSet I k b).contMDiffAt_of_coeff hi (e.open_baseSet.mem_nhds hx)⟩ /-- 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 [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 - 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_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' - have almost : CMDiff[t] k (T% rhs) := .sum_section fun i _ ↦ this i - apply almost.congr - intro y hy - simpa using b.localFrame_coeff_sum_eq s (ht' hy) +coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ +lemma contMDiffOn_iff_localFrame_coeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) : + CMDiff[t] k (T% s) ↔ ∀ i, CMDiff[t] k ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := by + refine ⟨fun h i ↦ contMDiffOn_localFrame_coeff b ht ht' h _, fun h x hx ↦ ?_⟩ + exact (contMDiffAt_iff_localFrame_coeff b (ht' hx)).mpr + (fun i ↦ (h i x hx).contMDiffAt (ht.mem_nhds hx)) |>.contMDiffWithinAt /-- 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 [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 +coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ +lemma contMDiffOn_baseSet_iff_localFrame_coeff : + CMDiff[e.baseSet] k (T% s) ↔ + ∀ i, CMDiff[e.baseSet] k ((LinearMap.piApply (e.localFrame_coeff I b 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 @@ -607,61 +538,51 @@ section MDifferentiable /-- 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 𝕜] - (hxe : x ∈ e.baseSet) (b : Basis ι 𝕜 F) {s : Π x : M, V x} (hs : MDiffAt (T% s) x) (i : ι) : - MDiffAt (b.localFrame_coeff I e i s) x := by +lemma mdifferentiableAt_localFrame_coeff + (hxe : x ∈ e.baseSet) (hs : MDiffAt (T% s) x) (i : ι) : + MDiffAt ((LinearMap.piApply (e.localFrame_coeff I b 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. + -- step 1: on `e.baseSet`, we know the coefficient very well + let aux := fun x ↦ b.repr (e ((T% s) x)).2 i + -- Since `e.baseSet` is open, this is sufficient. 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 - simp [aux, Basis.localFrame_coeff_eq_coeff hy] + simp [aux, e.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 + have h₁ : MDiffAt (fun x ↦ (e ((T% s) x)).2) x := by + simpa using (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 →ₗ[𝕜] 𝕜 := { - 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 : MDifferentiableAt 𝓘(𝕜, F) 𝓘(𝕜) basL (e (s x)).2 := - mdifferentiableAt_iff_differentiableAt.mpr (basL.differentiable _) - exact hbas.comp x h₁ + let breprl : F →ₗ[𝕜] 𝕜 := + { toFun v := b.repr v i + map_add' m m' := by simp + map_smul' m x := by simp } + have : MDifferentiableAt 𝓘(𝕜, F) 𝓘(𝕜) breprl.toContinuousLinearMap (e ((T% s) x)).2 := + mdifferentiableAt_iff_differentiableAt.mpr <| by fun_prop + exact this.comp x h₁ /-- 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) - {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_coeff I e i s) := - fun _ hx ↦ (mdifferentiableAt_localFrame_coeff (ht' hx) b +lemma mdifferentiableOn_localFrame_coeff (ht : IsOpen t) (ht' : t ⊆ e.baseSet) + (hs : MDiff[t] (T% s)) (i : ι) : MDiff[t] ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := + fun _ hx ↦ (mdifferentiableAt_localFrame_coeff b (ht' hx) (hs.mdifferentiableAt (ht.mem_nhds hx)) i).mdifferentiableWithinAt /-- 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 𝕜] - (b : Basis ι 𝕜 F) {s : Π x : M, V x} - (hs : MDiff[e.baseSet] (T% s)) (i : ι) : - MDiff[e.baseSet] (b.localFrame_coeff I e i s) := +lemma mdifferentiableOn_baseSet_localFrame_coeff (hs : MDiff[e.baseSet] (T% s)) (i : ι) : + MDiff[e.baseSet] ((LinearMap.piApply (e.localFrame_coeff I b i)) s) := mdifferentiableOn_localFrame_coeff b e.open_baseSet (subset_refl _) hs _ /-- 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 [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 ↦ - (b.localFrame_isLocalFrameOn_baseSet I 1 e).mdifferentiableAt_of_coeff_aux hi e.open_baseSet hx⟩ +coefficients `(LinearMap.piApply (b.localFrame_coeff e i) s)` in a local frame near `x` is -/ +lemma mdifferentiableAt_iff_localFrame_coeff (hx : x' ∈ e.baseSet) : + MDiffAt (T% s) x' ↔ ∀ i, MDiffAt ((LinearMap.piApply (e.localFrame_coeff I b i)) s) x' := + ⟨fun h i ↦ mdifferentiableAt_localFrame_coeff b hx h i, fun hi ↦ + (e.isLocalFrameOn_localFrame_baseSet I 1 b).mdifferentiableAt_of_coeff_aux hi e.open_baseSet hx⟩ end MDifferentiable @@ -670,12 +591,13 @@ end -- local extension of a vector field in a trivialisation's base set section localExtensionOn -variable {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} - {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F V → M)} - [MemTrivializationAtlas e] {x x' : M} +variable {e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)} [MemTrivializationAtlas e] + {ι : Type*} [Fintype ι] {b : Basis ι 𝕜 F} {x x' : M} + [VectorBundle 𝕜 F V] open scoped Classical in -/- Extend a vector `v ∈ V x` to a section `s` of the bundle `V` which is smooth near `x`, + +/-- 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`. The details of this extension are unspecified (and could be subject to change). @@ -691,15 +613,12 @@ 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) [VectorBundle 𝕜 F V] +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' := - fun x' ↦ if hx : x ∈ e.baseSet then - ∑ i, (b.localFrame_toBasis_at e hx).repr v i • b.localFrame e i x' + fun x' ↦ if hx : x ∈ e.baseSet then ∑ i, (e.basisAt b hx).repr v i • e.localFrame b i x' else 0 -variable [VectorBundle 𝕜 F V] - variable (b e) in @[simp] lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : @@ -710,8 +629,8 @@ variable (b) in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ 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 + e.localFrame_coeff I b i (localExtensionOn b e v) x' = + e.localFrame_coeff I b i (localExtensionOn b e v) x := by simp [localExtensionOn, hx, hx'] -- By construction, localExtensionOn is a linear map. @@ -738,7 +657,7 @@ lemma localExtensionOn_smul (a : 𝕜) (v : V x) : · 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)] + rw [mul_smul a (((e.basisAt b hx).repr v) i)] variable (F) in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -748,7 +667,7 @@ lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace -- constant, hence smoothness follows. rw [contMDiffOn_baseSet_iff_localFrame_coeff b] intro i - apply (contMDiffOn_const (c := (b.localFrame_coeff I e i) (localExtensionOn b e v) x)).congr + apply (contMDiffOn_const (c := (e.localFrame_coeff I b i) (localExtensionOn b e v) x)).congr intro y hy rw [localExtensionOn_localFrame_coeff b hx hy v i] From 7fc4aa3df23251cbc890148ba02c03b44fd4de52 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Feb 2026 19:38:53 +0100 Subject: [PATCH 429/441] refactor: make localExtensionOn a linear map instead This simplifies a few proofs; one proof is still broken --- .../Manifold/VectorBundle/LocalFrame.lean | 65 ++++++++----------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 66e765ff945959..90eda5ec49961c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -596,7 +596,6 @@ variable {e : Trivialization F (TotalSpace.proj : TotalSpace F V → M)} [MemTri [VectorBundle 𝕜 F V] 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`. @@ -615,9 +614,19 @@ constructions on covariant derivatives (and in this context, the value at `s` at -- 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' := - fun x' ↦ if hx : x ∈ e.baseSet then ∑ i, (e.basisAt b hx).repr v i • e.localFrame b i x' - else 0 + {x : M} : V x →ₗ[𝕜] ((x' : M) → V x') where + toFun v := open scoped Classical in + fun x' ↦ if hx : x ∈ e.baseSet then ∑ i, (e.basisAt b hx).repr v i • e.localFrame b i x' else 0 + map_add' v v' := by + ext x' + by_cases hx: x ∈ e.baseSet; swap + · simp [hx] + · simp [hx, add_smul, Finset.sum_add_distrib] + map_smul' a v := by + ext x' + by_cases hx: x ∈ e.baseSet; swap + · simp [hx] + · simp +contextual [hx, Finset.smul_sum, mul_smul a (((e.basisAt b hx).repr v) _)] variable (b e) in @[simp] @@ -625,39 +634,19 @@ lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : (localExtensionOn b e v) x = v := by simp [localExtensionOn, hx] +-- TODO: fix this proof! variable (b) in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ -lemma localExtensionOn_localFrame_coeff [ContMDiffVectorBundle 1 F V I] - (hx : x ∈ e.baseSet) (hx' : x' ∈ e.baseSet) (v : V x) (i : ι) : - e.localFrame_coeff I b i (localExtensionOn b e v) x' = - e.localFrame_coeff I b 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 (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 := 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 (a • v) = a • localExtensionOn b e v := by - ext x' - by_cases hx: x ∈ e.baseSet; swap - · simp [hx, localExtensionOn] - · 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 (((e.basisAt b hx).repr v) i)] +lemma localExtensionOnL_localFrame_coeff [ContMDiffVectorBundle 1 F V I] + (hx : x ∈ e.baseSet) (hx' : x' ∈ e.baseSet) (v : V x) (i : ι) (y : M) : + (Trivialization.localFrame_coeff I e b i y) ((localExtensionOn b e) v y) = + (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x) := by +-- statement used to be +-- e.localFrame_coeff I b i (LinearMap.piApply (localExtensionOn b e v)) x' = +-- e.localFrame_coeff I b i (localExtensionOn b e v) x := by + simp [localExtensionOn, hx] + -- XXX: original proof passed hx' and was done now + sorry variable (F) in lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace 𝕜] @@ -667,8 +656,10 @@ lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace -- constant, hence smoothness follows. rw [contMDiffOn_baseSet_iff_localFrame_coeff b] intro i - apply (contMDiffOn_const (c := (e.localFrame_coeff I b i) (localExtensionOn b e v) x)).congr + simp only [LinearMap.piApply_apply] + apply (contMDiffOn_const + (c := (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x))).congr intro y hy - rw [localExtensionOn_localFrame_coeff b hx hy v i] + rw [localExtensionOnL_localFrame_coeff b hx hy v i] end localExtensionOn From 8f3bcb0a171a196086268e99043bba990fd939b6 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 25 Feb 2026 19:48:38 +0100 Subject: [PATCH 430/441] Fix the build; comment one case of defeq abuse. --- .../CovariantDerivative/Basic.lean | 31 +++++++------ .../CovariantDerivative/LeviCivita.lean | 38 ++++++++-------- .../CovariantDerivative/Prelim.lean | 9 ++-- .../CovariantDerivative/Torsion.lean | 33 +++++++------- .../Manifold/VectorBundle/LocalFrame.lean | 4 +- .../VectorBundle/OrthonormalFrame.lean | 25 +++++------ .../Manifold/VectorBundle/Tensoriality.lean | 43 ++++++++++--------- 7 files changed, 95 insertions(+), 88 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 40ea18ae43651c..9e67e63adff8e9 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -889,17 +889,18 @@ end IsCovariantDerivativeOn section to_trivialization -variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] +namespace Trivialization +variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] noncomputable -def Trivialization.pushCovDer +def 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 omit [MemTrivializationAtlas e] in -lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] +lemma 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)} @@ -920,7 +921,7 @@ lemma Trivialization.pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensio 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 +lemma pushCovDer_isCovariantDerivativeOn [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] {u : Set M} (hu : u ⊆ e.baseSet) (hcov : IsCovariantDerivativeOn F cov u) : @@ -929,19 +930,19 @@ 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 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 + unfold pushCovDer 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 (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hσ - unfold Trivialization.pushCovDer + unfold pushCovDer rw [← e.map_smul (hu hx), ← hcov.smul_const_σ a hX hs hx] congr ext y @@ -954,7 +955,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 [← e.map_add ℝ (hu hx)] congr rw [← hcov.addσ hX hs hs' hx] @@ -965,7 +966,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] @@ -977,7 +978,7 @@ lemma Trivialization.pushCovDer_isCovariantDerivativeOn rw [e.apply_mk_symm (hu hx)] variable {e} in -lemma Trivialization.coordChangeL_pushCovDer +lemma coordChangeL_pushCovDer [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] @@ -987,7 +988,7 @@ lemma Trivialization.coordChangeL_pushCovDer {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 + unfold pushCovDer let σ := (fun x' ↦ e.symm x' (s x')) rw [coordChangeL_apply e e' hx] refold_let σ @@ -1017,7 +1018,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'] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] @@ -1048,7 +1049,7 @@ lemma Trivialization.coordChangeL_mem_horiz -- This is PAIIIIINNNN variable {e} in -lemma Trivialization.coordChangeL_coordChangeL +lemma coordChangeL_coordChangeL [VectorBundle ℝ F V] {e' : Trivialization F (π F V)} [MemTrivializationAtlas e'] {x : M} (hx : x ∈ e.baseSet ∩ e'.baseSet) (v : F) : @@ -1078,7 +1079,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'] [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I] @@ -1102,6 +1103,8 @@ lemma Trivialization.coordChangeL_mem_horiz_iff · convert hu using 2 apply inter_comm +end Trivialization + end to_trivialization section horiz diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 9ff0a689e542cb..8c52dbaa064c32 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -531,7 +531,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 @@ -709,10 +708,10 @@ lemma congr_of_forall_product [FiniteDimensional ℝ E] 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 + have h₁ : ⟪X, real i⟫ x = hframe.coeff i x (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 + have h₂ : ⟪X', real i⟫ x = hframe.coeff i x (X' x) := by rw [hframe.coeff_eq_inner' _ hx] simp [real, real_inner_comm] rw [← h₁, ← h₂, h (real i)] @@ -823,7 +822,7 @@ 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.coeff i σ x • Z i x := by + _ = ∑ i, hZ.coeff i x (σ 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 @@ -906,7 +905,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.coeff k (f (s i) (s j)) + (LinearMap.piApply (hs.coeff k)) (f (s i) (s j)) -- special case of `foobar` below; needed? lemma ChristoffelSymbol.sum_eq @@ -932,21 +931,22 @@ lemma eq_product_apply [Fintype ι] 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] + dsimp [ChristoffelSymbol] -- simplify the piApply in the definition above + rw [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 Y x = ∑ k, - letI S₁ := ∑ i, ∑ j, (hs.coeff i X) * (hs.coeff j Y) * (ChristoffelSymbol I f hs i j 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) Y x • s i x := by + 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 Y x = f X (fun x ↦ ∑ i, (hs.coeff i) Y x • s i x) x := by + have : f X Y x = f X (fun x ↦ ∑ i, hs.coeff i x (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 @@ -992,7 +992,7 @@ 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] + ext; simp [ChristoffelSymbol] @[simp] lemma christoffelSymbol_zero_apply (U : Set M) {ι : Type*} {s : ι → (x : M) → TangentSpace I x} @@ -1009,13 +1009,14 @@ variable {U : Set M} {ι : Type*} [Fintype ι] {s : ι → (x : M) → TangentSp /-- 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 ι] +lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ι : Type*} [Finite ι] [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 + have := Fintype.ofFinite ι 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 @@ -1046,11 +1047,10 @@ lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional ℝ E] [IsManifol -- 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)) + ((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)) + have hs (x) := (t x).isLocalFrameOn_localFrame_baseSet I 1 (Basis.ofVectorSpace ℝ E) -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! rw [isTorsionFreeOn_iff_christoffelSymbols (ι := (↑(Basis.ofVectorSpaceIndex ℝ E))) I hf] @@ -1059,7 +1059,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 + 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 @@ -1074,7 +1074,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x simp only [lcCandidateAux, hE, ↓reduceDIte] letI t := trivializationAt E (TangentSpace I) x; - letI hs := (Basis.ofVectorSpace ℝ E).localFrame_isLocalFrameOn_baseSet I 1 t + letI hs := t.isLocalFrameOn_localFrame_baseSet I 1 (Basis.ofVectorSpace ℝ E) 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 @@ -1084,7 +1084,7 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x intro x' hx' i j set t := trivializationAt E (TangentSpace I) x set b := (Basis.ofVectorSpace ℝ E) - set s := b.localFrame t + 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 @@ -1125,7 +1125,9 @@ theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional ℝ E] (x set sij := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x' rw [inner_smul_left, inner_smul_left] congr - simp [leviCivitaRhs'] + simp? [leviCivitaRhs'] says + simp only [one_div, leviCivitaRhs', Pi.smul_apply, Pi.add_apply, Pi.sub_apply, smul_eq_mul, + mul_eq_mul_left_iff, inv_eq_zero, OfNat.ofNat_ne_zero, or_false] 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 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index c892eb43f4cd48..517b3f3964f84c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -331,15 +331,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 @@ -781,6 +781,3 @@ lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} · simp end linear_algebra_isCompl - - - diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean index 75ec9921d70510..84b37aba789f3b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -248,15 +248,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.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 := by 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 @@ -265,38 +265,41 @@ 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) hx hsi hsi' + have := hf.torsion_smul_right_apply (X := X) (Y := s i) + (f := (LinearMap.piApply (hs.coeff i)) Y) hx hsi hsi' + dsimp at this 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] + {ι : Type*} [Finite ι] [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 + have := Fintype.ofFinite ι 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 • ∑ 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 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 90eda5ec49961c..357245c16469f4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -637,7 +637,7 @@ lemma localExtensionOn_apply_self (hx : x ∈ e.baseSet) (v : V x) : -- TODO: fix this proof! variable (b) in /-- A local extension has constant frame coefficients within its defining trivialisation. -/ -lemma localExtensionOnL_localFrame_coeff [ContMDiffVectorBundle 1 F V I] +lemma localExtensionOn_localFrame_coeff [ContMDiffVectorBundle 1 F V I] (hx : x ∈ e.baseSet) (hx' : x' ∈ e.baseSet) (v : V x) (i : ι) (y : M) : (Trivialization.localFrame_coeff I e b i y) ((localExtensionOn b e) v y) = (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x) := by @@ -660,6 +660,6 @@ lemma contMDiffOn_localExtensionOn [FiniteDimensional 𝕜 F] [CompleteSpace apply (contMDiffOn_const (c := (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x))).congr intro y hy - rw [localExtensionOnL_localFrame_coeff b hx hy v i] + rw [localExtensionOn_localFrame_coeff b hx hy v i] end localExtensionOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean index 6f84fe2a8b6278..40bbe8f86cc012 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -106,15 +106,15 @@ 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} +variable [Finite ι] (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 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 := Fintype.ofFinite ι 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 @@ -189,21 +190,21 @@ namespace Module.Basis variable {b : Basis ι ℝ F} {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E → B)} - [MemTrivializationAtlas e] {x : B} -- (hx : x ∈ e.baseSet) + [MemTrivializationAtlas e] {x : B} 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.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..e8e4c370b175d6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -89,26 +89,26 @@ 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 - have hφ {σ : (x : M) → V x} - (hσ : MDiffAt (T% σ) x) : - φ σ x = φ (fun x' ↦ ∑ i, (c i) σ x' • s i x') x := by + 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' (σ 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 +149,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 From cb6eec1beb0c0562dbe9f42d8a3da052fdfb1977 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 17:00:09 +0000 Subject: [PATCH 431/441] Fix merge --- .../CovariantDerivative/Basic.lean | 5 +- .../CovariantDerivative/Prelim.lean | 75 ++++++++++--------- .../Manifold/VectorBundle/LocalFrame.lean | 2 +- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 9e67e63adff8e9..9025998193574d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -889,7 +889,7 @@ end IsCovariantDerivativeOn section to_trivialization -namespace Trivialization +namespace Bundle.Trivialization variable (e : Trivialization F (π F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] @@ -1016,7 +1016,6 @@ 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 {e} in lemma coordChangeL_mem_horiz [FiniteDimensional ℝ E] [T2Space M] [IsManifold I ∞ M] [FiniteDimensional ℝ F] @@ -1103,7 +1102,7 @@ lemma coordChangeL_mem_horiz_iff · convert hu using 2 apply inter_comm -end Trivialization +end Bundle.Trivialization end to_trivialization diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 517b3f3964f84c..4ffa54c2aaf17a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -376,22 +376,25 @@ theorem contDiff_extend end extend +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 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 @@ -402,41 +405,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 @@ -450,7 +453,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 @@ -458,7 +461,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] @@ -468,7 +471,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 @@ -477,7 +480,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 @@ -497,14 +500,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' @@ -520,19 +523,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 @@ -555,8 +558,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 @@ -565,7 +567,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 @@ -580,18 +582,18 @@ 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) @[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 @@ -603,7 +605,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) : @@ -611,7 +613,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) : @@ -622,7 +624,7 @@ lemma Trivialization.mfderiv_proj_fst_deriv rfl -- TODO: understand why `simp` does not handle `ContinuousLinearMap.fst` @[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) : @@ -647,9 +649,8 @@ lemma Trivialization.mfderiv_proj_derivInv_apply simp rfl - @[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 @@ -665,14 +666,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 @@ -681,7 +682,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) : @@ -694,7 +695,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 @@ -709,7 +710,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) : @@ -735,14 +736,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*} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 59b189799bc842..16743c15ea6d1d 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -455,7 +455,7 @@ lemma localFrame_coeff_eq_coeff (hxe : x ∈ e.baseSet) {i : ι} : e.localFrame_coeff I b i x (s x) = b.repr (e ((T% s) x)).2 i := by simp [e.localFrame_coeff_apply_of_mem_baseSet b hxe, basisAt] -end Trivialization +end Bundle.Trivialization /-! # 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 From dbb45101dcf6da843771c78f28f0bcd9b1c913ab Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:08:47 +0000 Subject: [PATCH 432/441] [pre-commit.ci lite] apply automatic fixes --- .../Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index 225d1df7e40e6c..f49af45412bf96 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -377,4 +377,3 @@ lemma CovariantDerivative.orbit_geodVF {X : Π x : M, TangentSpace I x} rw [ht'.proj_acceleration cov ht] end geodesics - From d86d379f532a0593c5abb52f46f4501d2c206f03 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Sat, 28 Feb 2026 20:19:59 +0100 Subject: [PATCH 433/441] chore: mfderiv% more; annotate a few failing cases --- .../CovariantDerivative/Basic.lean | 34 ++++++------- .../CovariantDerivative/LeviCivita.lean | 20 ++++---- .../CovariantDerivative/Prelim.lean | 48 +++++++++---------- 3 files changed, 49 insertions(+), 53 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 9025998193574d..07e7aef1f15e0b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -68,7 +68,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 _).toFun (mfderiv I 𝓘(𝕜) g x (X x))) • σ x + f X (g • σ) x = (g • f X σ) x + ((bar _).toFun (mfderiv% 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 @@ -273,7 +273,7 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] 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 + + f i x • (bar (g x)) ((mfderiv% g x) (X x)) • σ x) := by congr ext i rw [(h i).leibniz hX hσ hg] @@ -281,12 +281,12 @@ def affineCombination' {ι : Type*} {s : Finset ι} [Nonempty s] 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 + + ∑ i ∈ s, f i x • (bar (g x)) ((mfderiv% 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 + (bar (g x)) ((mfderiv% 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 + set B := (bar (g x)) ((mfderiv% 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 @@ -331,6 +331,7 @@ variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : IsCovariantDerivativeOn F (V := Trivial M F) + -- TODO: mfderiv% does not work here; `s` is a section into the trivial bundle (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 @@ -349,7 +350,7 @@ noncomputable def trivial [IsManifold I 1 M] : 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) + letI d : F := mfderiv% s x (X x) d + A x (X x) (s x)) univ := trivial I M F |>.add_one_form A @@ -593,7 +594,7 @@ lemma congr_σ_smoothBumpFunction [T2Space M] [IsManifold I ∞ M] _ = 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] + rw [show mfderiv I 𝓘(ℝ) 1 x = 0 by apply mfderiv_const] left rfl @@ -652,8 +653,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 _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) - - (f x • cov' X σ x + ((bar _).toFun <| mfderiv I 𝓘(ℝ) f x (X x)) • σ x) := by + _ = (f x • cov X σ x + ((bar _).toFun <| mfderiv% f x (X x)) • σ x) + - (f x • cov' X σ x + ((bar _).toFun <| mfderiv% 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] @@ -789,7 +790,7 @@ lemma exists_one_form {cov : (Π x : M, TangentSpace I x) → (M → F) → (M ∃ (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) + letI d : F := mfderiv% σ 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σ @@ -805,7 +806,7 @@ 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} (hX : MDiffAt (T% X) x) (hσ : MDiffAt (T% σ) x) (hx : x ∈ s := by trivial) : - letI d : F := mfderiv I 𝓘(ℝ, F) σ x (X x) + letI d : F := mfderiv% σ 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σ @@ -814,7 +815,7 @@ lemma _root_.CovariantDerivative.exists_one_form ∃ (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) + letI d : F := mfderiv% σ x (X x) cov X σ x = d + A x (X x) (σ x) := by simpa using cov.isCovariantDerivativeOn.exists_one_form @@ -839,7 +840,7 @@ lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) 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 + cov X σ x = hcov.projection x (σ x) (X x, mfderiv% σ x (X x)) := by simpa using hcov.eq_one_form hX hσ noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : @@ -861,7 +862,7 @@ lemma mem_horiz_iff_exists (hcov : IsCovariantDerivativeOn F cov s) {x : M} {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% σ x u = v ∧ cov (extend I E u) σ x = 0 := by constructor · intro huv @@ -1191,12 +1192,11 @@ 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 + cov X σ x = cov.proj (σ x) (mfderiv% (T% σ) x (X 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?) + -- FIXME `mfderiv%` fails on the 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 hcov := cov.isCovariantDerivativeOn_pushCovDer t diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 8c52dbaa064c32..7e73a85e5df803 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -396,18 +396,18 @@ 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 + letI dfZ : ℝ := (mfderiv% f x) (Z x); + inner ℝ (Y x) ((mfderiv% 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 + letI dfZ : ℝ := (mfderiv% f x) (Y x); + inner ℝ (Z x) ((mfderiv% 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] - set dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) - set dfZ : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Z x) + set dfY : ℝ := (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 @@ -539,7 +539,7 @@ lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M → ℝ} set F := ⟪X, mlieBracket I Z Y⟫ x set G1 := ⟪Y, Z⟫ x set G2 := ⟪X, Y⟫ x - set dfx := (mfderiv I 𝓘(ℝ, ℝ) f x) + set dfx := (mfderiv% 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 @@ -616,9 +616,9 @@ lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M → ℝ} -- 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) + -- letI dfX : ℝ := (mfderiv% f x) (X x) -- set G := dfX * ⟪Y, Z⟫ x - -- letI dfY : ℝ := (mfderiv I 𝓘(ℝ, ℝ) f x) (Y x) + -- letI dfY : ℝ := (mfderiv% f x) (Y x) -- set H := dfY * ⟪X, Z⟫ x ring @@ -833,7 +833,7 @@ lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional ℝ 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 + + ∑ i, ((bar (g x)) ((mfderiv% 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 diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 4ffa54c2aaf17a..7e08b5d349b00c 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -85,10 +85,10 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] 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 + (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 @@ -97,11 +97,11 @@ lemma injective_mfderiv_of_eventually_leftInverse 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 + (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,7 +110,7 @@ lemma surjective_mfderiv_of_eventually_rightInverse 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 + mfderiv% (a • s) x v = a • mfderiv% s x v := by by_cases hs : MDiffAt s x · have hs' := hs.const_smul a suffices @@ -134,9 +134,9 @@ 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 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 @@ -229,7 +229,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. @@ -246,22 +246,20 @@ 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 + (φ 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φ @@ -275,7 +273,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 @@ -715,19 +713,17 @@ lemma mfderiv_comp_section {σ : Π 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 + (e.deriv I (σ x)).toLinearMap ((mfderiv% T%σ x) u) = (u, mfderiv% 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) := + have : mfderiv% (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 + have : mfderiv% (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) + change mfderiv% (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 = _ From a565735cc72836442576c64c8acfc3be47481e76 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 17:29:09 +0000 Subject: [PATCH 434/441] Small clean-ups and tweaks --- .../CovariantDerivative/Prelim.lean | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 7e08b5d349b00c..d3bc18d8332e78 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -67,7 +67,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 @@ -84,7 +84,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -- 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) + (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 @@ -96,7 +96,7 @@ lemma injective_mfderiv_of_eventually_leftInverse -- 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) + (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 @@ -109,6 +109,7 @@ lemma surjective_mfderiv_of_eventually_rightInverse variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] +-- 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 @@ -125,12 +126,13 @@ 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) : @@ -258,8 +260,7 @@ lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] rw [injective_iff_map_eq_zero] at this have := map_zero (mfderiv% ψ x') grind - rcases map_of_loc_one_jet_spec (𝕜 := 𝕜) - (φ x) (mfderiv% φ x u) (ψ x') (mfderiv% ψ 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φ @@ -348,7 +349,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 @@ -406,7 +407,7 @@ variable {E : B → Type*} [TopologicalSpace (TotalSpace 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⟩ + 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)] @@ -430,7 +431,7 @@ 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 + FiberBundle.continuous_proj F E |>.continuousAt <| e.baseSet_mem_nhds hv lemma fst_comp_eventuallyEq {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : @@ -559,7 +560,7 @@ 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 + 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) @@ -636,7 +637,7 @@ lemma mfderiv_proj_derivInv_apply 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⟩ + 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 @@ -777,4 +778,4 @@ lemma LinearEquiv.comap_isCompl {R R₂ M M₂ : Type*} · simp · simp -end linear_algebra_isCompl +end linear_algebra_isCompl From af905869dd8f6c2a4000a25e87f2f7014d16c513 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 17:40:25 +0000 Subject: [PATCH 435/441] Annotate some lemmas getting upstreamed --- .../Manifold/VectorBundle/CovariantDerivative/Prelim.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index d3bc18d8332e78..68d09b6d6aca7e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -81,7 +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 +-- unused; could move to `SpecificFunctions` lemma injective_mfderiv_of_eventually_leftInverse {f : M → M'} (x : M) {g : M' → M} (hg : MDiffAt g (f x)) (hf : MDiffAt f x) @@ -93,7 +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 +-- 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 : MDiffAt g y) (hf : MDiffAt f x) From 5b16147995edee35a71eaeb1fd7909d743512332 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 21:35:19 +0000 Subject: [PATCH 436/441] Golf using new simp lemmas --- .../CovariantDerivative/Prelim.lean | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index 68d09b6d6aca7e..b286ff9aa1468e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -395,8 +395,8 @@ lemma baseSet_prod_univ_mem_nhds {v : Z} 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 + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp + using by simp [(mem_target e).2 hp.1] end any_proj @@ -408,7 +408,7 @@ 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 + simp [hx] lemma injective_symm [(x : B) → Zero (E x)] {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : @@ -419,7 +419,7 @@ lemma injective_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⟩ + fun u ↦ ⟨(e u).2, by simp [*]⟩ lemma bijective_symm [(x : B) → Zero (E x)] {v : TotalSpace F E} (hv : v.proj ∈ e.baseSet) : @@ -442,7 +442,7 @@ 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 + by simp [(mem_source e).mpr hw] end fiber_bundle @@ -462,8 +462,7 @@ lemma eq_of {x : B} {v v' : E x} @[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] + filter_upwards [e.baseSet_mem_nhds hx] with y hy using by simp [hy] variable [(b : B) → TopologicalSpace (E b)] [FiberBundle F E] @@ -473,8 +472,7 @@ 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)] + filter_upwards [e.baseSet_mem_nhds hb] with y hy using by simp [*] -- FIXME super weird elaborator bug: removing the -- omitted assumption from the variable line breaks the lemma @@ -598,6 +596,8 @@ lemma derivInv_deriv (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 [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 @@ -632,13 +632,12 @@ lemma mfderiv_proj_derivInv_apply 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)] + have eq : e.invFun (e v) = v := by simp [((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 + 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 @@ -656,8 +655,7 @@ lemma deriv_derivInv 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)] + have : e.invFun (e v) = v := by simp [(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 From 8571471ee53e9b225dc3cb838f859a6c7d7e10f3 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 21:35:19 +0000 Subject: [PATCH 437/441] Golf using new simp lemmas --- .../Manifold/VectorBundle/CovariantDerivative/Basic.lean | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index 07e7aef1f15e0b..c965273c51e952 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -912,9 +912,8 @@ lemma pushCovDer_ofSect [FiniteDimensional ℝ E] [FiniteDimensional ℝ F] (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) - · 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σ + · exact fun y hy ↦ by simp [hy] --FIXME extract as lemma? + · rwa [(e.symm_apply_apply_mk_eventuallyEq hx σ).mdifferentiableAt_iff] unfold pushCovDer rw [this] @@ -993,9 +992,7 @@ lemma coordChangeL_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) + have : e.symm x (e ⟨x, cov X σ x⟩).2 = cov X σ x := by simp [hx.1] rw [this] -- TODO: extract lemma? have : ∀ x' ∈ e.baseSet ∩ e'.baseSet, σ x' = From 9e8ded07f05e338cf336fc061f040178390124c9 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Mon, 2 Mar 2026 21:45:01 +0000 Subject: [PATCH 438/441] chore: general golfs using these lemmas --- Mathlib/Geometry/Manifold/VectorBundle/Hom.lean | 5 +---- Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean | 6 ++---- Mathlib/Topology/FiberBundle/Constructions.lean | 4 ++-- Mathlib/Topology/VectorBundle/Hom.lean | 4 +--- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index dea744880414bd..090fe8851e7ff6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -197,10 +197,7 @@ lemma ContMDiffWithinAt.clm_apply_of_inCoordinates exact FiberBundle.mem_baseSet_trivializationAt' (b₂ m₀) filter_upwards [A, A'] with m hm h'm rw [inCoordinates_eq hm h'm] - simp only [coe_comp', ContinuousLinearEquiv.coe_coe, Trivialization.continuousLinearEquivAt_apply, - Trivialization.continuousLinearEquivAt_symm_apply, Function.comp_apply] - congr - rw [Trivialization.symm_apply_apply_mk (trivializationAt F₁ E₁ (b₁ m₀)) hm (v m)] + simp [*] /-- Consider a `C^n` map `v : M → E₁` to a vector bundle, over a base map `b₁ : M → B₁`, and another base map `b₂ : M → B₂`. Given linear maps `ϕ m : E₁ (b₁ m) → E₂ (b₂ m)` depending smoothly diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index 5695687ec5a071..0d16e126a229a0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -649,10 +649,8 @@ lemma MDifferentiableWithinAt.clm_apply_of_inCoordinates exact FiberBundle.mem_baseSet_trivializationAt' (b₂ m₀) filter_upwards [A, A'] with m hm h'm rw [inCoordinates_eq hm h'm] - simp only [coe_comp', ContinuousLinearEquiv.coe_coe, Trivialization.continuousLinearEquivAt_apply, - Trivialization.continuousLinearEquivAt_symm_apply, Function.comp_apply] - congr - rw [Trivialization.symm_apply_apply_mk (trivializationAt F₁ E₁ (b₁ m₀)) hm (v m)] + simp [hm] + /-- Consider a differentiable map `v : M → E₁` to a vector bundle, over a basemap `b₁ : M → B₁`, and another basemap `b₂ : M → B₂`. Given linear maps `ϕ m : E₁ (b₁ m) → E₂ (b₂ m)` depending diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index 6945408397a7b8..ea3ff754950fb6 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -169,14 +169,14 @@ theorem Prod.left_inv {x : TotalSpace (F₁ × F₂) (E₁ ×ᵇ E₂)} Prod.invFun' e₁ e₂ (Prod.toFun' e₁ e₂ x) = x := by obtain ⟨x, v₁, v₂⟩ := x obtain ⟨h₁ : x ∈ e₁.baseSet, h₂ : x ∈ e₂.baseSet⟩ := h - simp only [Prod.toFun', Prod.invFun', symm_apply_apply_mk, h₁, h₂] + simp [Prod.toFun', Prod.invFun', h₁, h₂] theorem Prod.right_inv {x : B × F₁ × F₂} (h : x ∈ (e₁.baseSet ∩ e₂.baseSet) ×ˢ (univ : Set (F₁ × F₂))) : Prod.toFun' e₁ e₂ (Prod.invFun' e₁ e₂ x) = x := by obtain ⟨x, w₁, w₂⟩ := x obtain ⟨⟨h₁ : x ∈ e₁.baseSet, h₂ : x ∈ e₂.baseSet⟩, -⟩ := h - simp only [Prod.toFun', Prod.invFun', apply_mk_symm, h₁, h₂] + simp [Prod.toFun', Prod.invFun', h₁, h₂] theorem Prod.continuous_inv_fun : ContinuousOn (Prod.invFun' e₁ e₂) ((e₁.baseSet ∩ e₂.baseSet) ×ˢ univ) := by diff --git a/Mathlib/Topology/VectorBundle/Hom.lean b/Mathlib/Topology/VectorBundle/Hom.lean index f5c2ec5cce88b1..42dec06ced46db 100644 --- a/Mathlib/Topology/VectorBundle/Hom.lean +++ b/Mathlib/Topology/VectorBundle/Hom.lean @@ -357,9 +357,7 @@ lemma ContinuousWithinAt.clm_apply_of_inCoordinates apply hb₂ apply (trivializationAt F₂ E₂ (b₂ m₀)).open_baseSet.mem_nhds exact FiberBundle.mem_baseSet_trivializationAt' (b₂ m₀) - filter_upwards [A, A'] with m hm h'm - simp [inCoordinates_eq hm h'm, - Trivialization.symm_apply_apply_mk (trivializationAt F₁ E₁ (b₁ m₀)) hm (v m)] + filter_upwards [A, A'] with m hm h'm using by simp [inCoordinates_eq hm h'm, hm] /-- Consider a continuous map `v : M → E₁` to a vector bundle, over a base map `b₁ : M → B₁`, and From fe388689399b86c817b68380aaee6bf23a8ba947 Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 10:21:16 +0000 Subject: [PATCH 439/441] Fixup --- Mathlib/Geometry/Manifold/PartitionOfUnity.lean | 2 +- Mathlib/Geometry/Manifold/VectorBundle/Misc.lean | 1 + Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) 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/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index cf6bcf546c29c3..3eb794b53d0b3f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -10,7 +10,6 @@ public import Mathlib.Geometry.Manifold.MFDeriv.Basic public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Topology.ContinuousMap.Basic -public import Mathlib.Geometry.Manifold.Notation /-! # `C^n` sections From c336d959f94ce81dec2aa5dd134ace9cfbcd1e1d Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 10:30:08 +0000 Subject: [PATCH 440/441] Fixes --- .../Manifold/VectorField/LieBracket.lean | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 9838d037f32fbf..766e8dabaf7713 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -332,6 +332,7 @@ lemma aux_computation : rw [← ContinuousLinearMap.IsInvertible.inverse_comp_of_left, ← ContinuousLinearMap.inverse_id, mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (mem_extChartAt_source x)] + · rfl exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) _ = W x := by simp @@ -350,11 +351,7 @@ lemma aux_computation2' : 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] + OpenPartialHomeomorph.toFun_eq_coe, 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) = _ @@ -363,9 +360,11 @@ lemma aux_computation2' : 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 + rw [this] + erw [ContinuousLinearMap.inverse_id] + rfl +set_option backward.isDefEq.respectTransparency false in variable (x V) in omit [CompleteSpace E] in lemma aux_computation2 : @@ -401,6 +400,7 @@ lemma aux_computation2 : rw [this, ContinuousLinearMap.inverse_id] exact rfl +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. @@ -462,6 +462,7 @@ lemma mlieBracketWithin_smul_right {f : M → 𝕜} (hf : MDifferentiableWithinA exact aux_computation2 x V exact this +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]`. @@ -474,6 +475,7 @@ lemma mlieBracket_smul_right {f : M → 𝕜} (hf : MDifferentiableAt I 𝓘( 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. @@ -487,6 +489,7 @@ lemma mlieBracketWithin_smul_left {f : M → 𝕜} (hf : MDifferentiableWithinAt 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]`. From c487a9a1d25ee47368d6e095f701fc633bb6847a Mon Sep 17 00:00:00 2001 From: Michael Rothgang Date: Wed, 4 Mar 2026 10:37:17 +0000 Subject: [PATCH 441/441] It builds now, again! --- .../VectorBundle/CovariantDerivative/Basic.lean | 10 +++++++--- .../VectorBundle/CovariantDerivative/LeviCivita.lean | 4 ++++ .../VectorBundle/CovariantDerivative/Lift.lean | 3 +++ .../VectorBundle/CovariantDerivative/Prelim.lean | 6 +++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index c965273c51e952..c13639bb638a7b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -327,6 +327,7 @@ end operations section trivial_bundle +set_option backward.isDefEq.respectTransparency false in variable (I M F) in @[simps] noncomputable def trivial [IsManifold I 1 M] : @@ -480,6 +481,7 @@ end operations 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 @@ -858,6 +860,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 ∧ @@ -1148,8 +1151,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) : @@ -1184,6 +1188,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 : Π x : M, TangentSpace I x} {σ : Π x : M, V x} (x : M) @@ -1211,7 +1216,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/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean index 7e73a85e5df803..925230013ea061 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -31,6 +31,10 @@ open scoped Bundle Manifold ContDiff @[expose] public section -- TODO: think if we want to expose all definitions! +-- TODO: investigate the need for this option, once the dust has settled and we are happy with +-- how this file has been refactored +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] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean index f49af45412bf96..83b5d8e281e722 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -231,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 @@ -339,6 +340,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₀ ↔ @@ -366,6 +368,7 @@ 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) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean index b286ff9aa1468e..562acf24f90785 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 -- 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 @@ -356,7 +357,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] @@ -602,6 +603,7 @@ lemma derivInv_deriv have comp := mfderiv_comp v D₁ D₂ rw [(invFun_comp_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp simp [deriv, derivInv, comp] + rfl @[simp] lemma derivInv_deriv_apply @@ -622,6 +624,7 @@ lemma mfderiv_proj_fst_deriv 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] @@ -647,6 +650,7 @@ lemma mfderiv_proj_derivInv_apply simp rfl +set_option backward.isDefEq.respectTransparency false in @[simp] lemma deriv_derivInv [VectorBundle ℝ F V] [ContMDiffVectorBundle 1 F V I]