Repository: HEPLean/PhysLean
Pull request #481: feat: some vector calculus
Author: login: zhikaip
Created: 2025-04-14T22:19:24Z | Merged: 2025-04-15T13:39:50Z

Attempts at doing some vector calculus. I'm not sure how to structure this, do we want this in space or in the mathematics folder?

I'm not sure what actually belongs here, The main thing I tried to do here is to  prove div_of_curl_eq_zero and ended up with a lot of helper lemmas. Please feel free to give me suggestions to clean it up or remove anything you don't see fit, it's just practice for me. Many thanks!

If this is generally ok I'll keep going.


Diff:
diff --git a/PhysLean.lean b/PhysLean.lean
index 6e4b68f56..ad0fd082a 100644
--- a/PhysLean.lean
+++ b/PhysLean.lean
@@ -3,6 +3,7 @@ import PhysLean.ClassicalMechanics.HarmonicOscillator.Basic
 import PhysLean.ClassicalMechanics.HarmonicOscillator.Solution
 import PhysLean.ClassicalMechanics.Momentum.Basic
 import PhysLean.ClassicalMechanics.Space.Basic
+import PhysLean.ClassicalMechanics.Space.VectorIdentities
 import PhysLean.ClassicalMechanics.Time.Basic
 import PhysLean.CondensedMatter.Basic
 import PhysLean.Cosmology.Basic
diff --git a/PhysLean/ClassicalMechanics/Space/Basic.lean b/PhysLean/ClassicalMechanics/Space/Basic.lean
index 85c6399b3..5ccbd0140 100644
--- a/PhysLean/ClassicalMechanics/Space/Basic.lean
+++ b/PhysLean/ClassicalMechanics/Space/Basic.lean
@@ -47,24 +47,6 @@ noncomputable def deriv [AddCommGroup M] [Module ℝ M] [TopologicalSpace M]
 @[inherit_doc deriv]
 macro "∂[" i:term "]" : term => `(deriv $i)
 
-/-- The theorem that derivatives on space commute with one another. -/
-lemma deriv_commute [NormedAddCommGroup M] [NormedSpace ℝ M]
-    (f : Space d → M) (hf : ContDiff ℝ ⊤ f) : ∂[u] (∂[v] f) = ∂[v] (∂[u] f) := by
-  have hf' : ContDiff ℝ (⊤ : ℕ∞) f := hf.of_le le_top
-  rw [contDiff_infty_iff_fderiv] at hf'
-  unfold deriv
-  ext x
-  rw [fderiv_clm_apply, fderiv_clm_apply]
-  simp only [fderiv_const, Pi.zero_apply, ContinuousLinearMap.comp_zero, zero_add,
-    ContinuousLinearMap.flip_apply]
-  rw [IsSymmSndFDerivAt.eq]
-  apply ContDiffAt.isSymmSndFDerivAt_of_omega
-  apply hf.contDiffAt
-  repeat
-    apply hf'.right.contDiffAt.differentiableAt
-    simp only [WithTop.one_le_coe, le_top]
-    apply differentiableAt_const
-
 /-- The vector calculus operator `grad`. -/
 noncomputable def grad (f : Space d → ℝ) :
   Space d → EuclideanSpace ℝ (Fin d) := fun x i =>
diff --git a/PhysLean/ClassicalMechanics/Space/VectorIdentities.lean b/PhysLean/ClassicalMechanics/Space/VectorIdentities.lean
new file mode 100644
index 000000000..b4cdf519d
--- /dev/null
+++ b/PhysLean/ClassicalMechanics/Space/VectorIdentities.lean
@@ -0,0 +1,209 @@
+/-
+Copyright (c) 2025 Zhi Kai Pong. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+Authors: Zhi Kai Pong
+-/
+import PhysLean.ClassicalMechanics.Space.Basic
+import Mathlib.Analysis.InnerProductSpace.Calculus
+
+/-!
+
+# VectorIdentities
+
+In this file we define common vector calculus identities based on `Space`.
+
+-/
+
+/-!
+
+## General auxiliary lemmas
+
+-/
+
+section
+
+variable
+  {𝕜} [NontriviallyNormedField 𝕜]
+  {X} [NormedAddCommGroup X] [NormedSpace 𝕜 X]
+  {Y} [NormedAddCommGroup Y] [NormedSpace 𝕜 Y]
+  {ι : Type*} [Fintype ι] {Y' : ι → Type*} [∀ i, NormedAddCommGroup (Y' i)]
+  [∀ i, NormedSpace 𝕜 (Y' i)] {Φ : X → ∀ i, Y' i} {Φ' : X →L[𝕜] ∀ i, Y' i} {x : X}
+
+lemma ContinousLinearMap.fderiv_pi' (h : DifferentiableAt 𝕜 Φ x):
+    fderiv 𝕜 Φ x = ContinuousLinearMap.pi fun i => (fderiv 𝕜 fun x => Φ x i) x:= by
+  apply HasFDerivAt.fderiv
+  apply hasFDerivAt_pi''
+  intro i
+  rw [differentiableAt_pi] at h
+  exact (h i).hasFDerivAt
+
+lemma ContDiff.differentiable_fderiv (f : X → Y) (hf : ContDiff 𝕜 2 f) :
+    Differentiable 𝕜 (fun x => fderiv 𝕜 f x) := by
+  have hf' : ContDiff 𝕜 (1+1) f := hf
+  rw [contDiff_succ_iff_fderiv] at hf'
+  apply hf'.right.right.differentiable
+  decide
+
+lemma fderiv_coord_eq_proj_comp (h : DifferentiableAt 𝕜 Φ x):
+    (fderiv 𝕜 fun x => Φ x i) x = (ContinuousLinearMap.proj i).comp (fderiv 𝕜 Φ x) := by
+  rw [ContinousLinearMap.fderiv_pi', ContinuousLinearMap.proj_pi]
+  apply h
+end
+
+/-!
+
+## Space.deriv lemmas
+
+-/
+
+namespace Space
+
+/-- Derivatives on space distiribute over addition. -/
+lemma deriv_add [NormedAddCommGroup M] [NormedSpace ℝ M]
+    (f1 f2 : Space d → M) (hf1 : Differentiable ℝ f1) (hf2 : Differentiable ℝ f2) :
+    ∂[u] (f1 + f2) = ∂[u] f1 + ∂[u] f2 := by
+  unfold Space.deriv
+  simp only
+  ext x
+  rw [fderiv_add']
+  simp only [ContinuousLinearMap.add_apply, Pi.add_apply]
+  repeat
+    apply Differentiable.differentiableAt
+    try apply hf1
+    try apply hf2
+
+/-- Derivatives on space distiribute coordinate-wise over addition. -/
+lemma deriv_coord_add (f1 f2 : Space d → EuclideanSpace ℝ (Fin d))
+    (hf1 : Differentiable ℝ f1) (hf2 : Differentiable ℝ f2) :
+    (∂[u] (fun x => f1 x i + f2 x i)) =
+      (∂[u] (fun x => f1 x i)) + (∂[u] (fun x => f2 x i)) := by
+  unfold Space.deriv
+  simp only
+  ext x
+  rw [fderiv_add]
+  simp only [ContinuousLinearMap.add_apply, Pi.add_apply]
+  repeat
+    apply Differentiable.differentiableAt
+    apply differentiable_euclidean.mp
+    first | apply hf1 | apply hf2
+
+/-- Derivatives on space commute with one another. -/
+lemma deriv_commute [NormedAddCommGroup M] [NormedSpace ℝ M]
+    (f : Space d → M) (hf : ContDiff ℝ 2 f) : ∂[u] (∂[v] f) = ∂[v] (∂[u] f) := by
+  unfold Space.deriv
+  ext x
+  rw [fderiv_clm_apply, fderiv_clm_apply]
+  simp only [fderiv_const, Pi.zero_apply, ContinuousLinearMap.comp_zero, zero_add,
+    ContinuousLinearMap.flip_apply]
+  rw [IsSymmSndFDerivAt.eq]
+  apply ContDiffAt.isSymmSndFDerivAt
+  exact ContDiff.contDiffAt hf
+  simp only [minSmoothness_of_isRCLikeNormedField, le_refl]
+  repeat
+  · apply Differentiable.differentiableAt
+    apply ContDiff.differentiable_fderiv
+    apply hf
+  · apply differentiableAt_const
+
+/-- Coordiate functions of fderiv is differentiable. -/
+lemma differentiable_fderiv_coord (f : Space → EuclideanSpace ℝ (Fin 3)) (hf : ContDiff ℝ 2 f) :
+    Differentiable ℝ (fderiv ℝ fun x => f x i) := by
+  have eq : (fderiv ℝ (fun x ↦ f x i))
+      = (fun x => (ContinuousLinearMap.proj i).comp (fderiv ℝ f x)) := by
+    ext x
+    rw [fderiv_coord_eq_proj_comp]
+    apply hf.differentiable
+    decide
+  rw [eq]
+  apply Differentiable.clm_comp
+  · apply differentiable_const
+  · apply ContDiff.differentiable_fderiv
+    apply hf
+
+/-- Second derivatives on space distiribute coordinate-wise over subtraction. -/
+lemma deriv_coord_2nd_sub (f : Space → EuclideanSpace ℝ (Fin 3)) (hf : ContDiff ℝ 2 f):
+    ∂[u] ((fun x => ∂[v] (fun x => f x w) x - ∂[w]  (fun x => f x v) x)) =
+    (∂[u] (∂[v] (fun x => f x w))) - (∂[u] (∂[w] (fun x => f x v))) := by
+  unfold Space.deriv
+  ext x
+  simp only [Pi.sub_apply]
+  rw [fderiv_sub]
+  simp only [ContinuousLinearMap.coe_sub', Pi.sub_apply]
+  repeat
+    apply Differentiable.differentiableAt
+    apply Differentiable.clm_apply
+    · apply differentiable_fderiv_coord
+      apply hf
+    · apply differentiable_const
+
+/-!
+
+## Vector calculus identities
+
+-/
+
+lemma div_of_curl_eq_zero (f : Space → EuclideanSpace ℝ (Fin 3)) (hf : ContDiff ℝ 2 f) :
+    ∇⬝ (∇× f) = 0 := by
+  unfold div curl Finset.sum
+  simp only [Fin.isValue, Fin.univ_val_map, List.ofFn_succ, Fin.succ_zero_eq_one,
+    Fin.succ_one_eq_two, List.ofFn_zero, Multiset.sum_coe, List.sum_cons, List.sum_nil, add_zero]
+  ext x
+  simp only [Fin.isValue, coord, basis, EuclideanSpace.basisFun_apply, PiLp.inner_apply,
+    EuclideanSpace.single_apply, RCLike.inner_apply, conj_trivial, ite_mul, one_mul, zero_mul,
+    Finset.sum_ite_eq', Finset.mem_univ, ↓reduceIte, Pi.zero_apply]
+  rw [deriv_coord_2nd_sub, deriv_coord_2nd_sub, deriv_coord_2nd_sub]
+  simp only [Fin.isValue, Pi.sub_apply]
+  rw [deriv_commute fun x => f x 0, deriv_commute fun x => f x 1,
+    deriv_commute fun x => f x 2]
+  simp only [Fin.isValue, sub_add_sub_cancel', sub_add_sub_cancel, sub_self]
+  repeat
+    try apply contDiff_euclidean.mp
+    apply hf
+
+/-!
+
+## Addition of ∇ operations
+
+-/
+
+lemma grad_add (f1 f2 : Space d → ℝ) (hf1 : Differentiable ℝ f1) (hf2 : Differentiable ℝ f2):
+    ∇ (f1 + f2) = ∇ f1 + ∇ f2 := by
+  unfold grad
+  ext x i
+  simp only [Pi.add_apply]
+  rw [deriv_add]
+  rfl
+  exact hf1
+  exact hf2
+
+lemma div_add (f1 f2 : Space → EuclideanSpace ℝ (Fin 3))
+    (hf1 : Differentiable ℝ f1) (hf2 : Differentiable ℝ f2) :
+    ∇⬝ (f1 + f2) = ∇⬝ f1 + ∇⬝ f2 := by
+  unfold div
+  simp only [Pi.add_apply]
+  ext x
+  simp only [coord, basis, EuclideanSpace.basisFun_apply, PiLp.inner_apply, PiLp.add_apply,
+    EuclideanSpace.single_apply, RCLike.inner_apply, conj_trivial, ite_mul, one_mul, zero_mul,
+    Finset.sum_ite_eq', Finset.mem_univ, ↓reduceIte, Pi.add_apply]
+  unfold Finset.sum
+  simp only [Fin.univ_val_map, List.ofFn_succ, Fin.isValue, Fin.succ_zero_eq_one,
+    Fin.succ_one_eq_two, List.ofFn_zero, Multiset.sum_coe, List.sum_cons, List.sum_nil, add_zero]
+  rw [deriv_coord_add, deriv_coord_add, deriv_coord_add]
+  simp only [Fin.isValue, Pi.add_apply]
+  ring
+  repeat (first | apply hf1 | apply hf2)
+
+lemma curl_add (f1 f2 : Space → EuclideanSpace ℝ (Fin 3))
+    (hf1 : Differentiable ℝ f1) (hf2 : Differentiable ℝ f2) :
+    ∇× (f1 + f2) = ∇× f1 + ∇× f2 := by
+  unfold curl
+  simp only [Fin.isValue, Pi.add_apply]
+  ext x i
+  fin_cases i <;>
+  · simp only [Fin.isValue, coord, basis, EuclideanSpace.basisFun_apply, PiLp.inner_apply,
+    PiLp.add_apply, EuclideanSpace.single_apply, RCLike.inner_apply, conj_trivial, ite_mul, one_mul,
+    zero_mul, Finset.sum_ite_eq', Finset.mem_univ, ↓reduceIte, Fin.zero_eta, Pi.add_apply]
+    rw [deriv_coord_add, deriv_coord_add]
+    simp only [Fin.isValue, Pi.add_apply]
+    ring
+    repeat (first | apply hf1 | apply hf2)


Reviews:
user: login: jstoobysmith
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-15T05:18:04Z
user: login: zhikaip
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-15T13:00:06Z
user: login: jstoobysmith
body: I've approved this - so feel free to merge when ready :)
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-15T13:39:04Z

Review comments:
diff_hunk: @@ -0,0 +1,209 @@
+/-
+Copyright (c) 2025 Zhi Kai Pong. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+Authors: Zhi Kai Pong
+-/
+import PhysLean.ClassicalMechanics.Space.Basic
+import Mathlib.Analysis.InnerProductSpace.Calculus
+
+/-!
+
+# VectorIdentities
+
+In this file we define common vector calculus identities based on `Space`.
+
+-/
+
+/-!
+
+## General auxiliary lemmas
+
+-/
+
+section
+
+variable
+  {𝕜} [NontriviallyNormedField 𝕜]
+  {X} [NormedAddCommGroup X] [NormedSpace 𝕜 X]
+  {Y} [NormedAddCommGroup Y] [NormedSpace 𝕜 Y]
+  {ι : Type*} [Fintype ι] {Y' : ι → Type*} [∀ i, NormedAddCommGroup (Y' i)]
+  [∀ i, NormedSpace 𝕜 (Y' i)] {Φ : X → ∀ i, Y' i} {Φ' : X →L[𝕜] ∀ i, Y' i} {x : X}
+
+lemma ContinousLinearMap.fderiv_pi' (h : DifferentiableAt 𝕜 Φ x):
+    fderiv 𝕜 Φ x = ContinuousLinearMap.pi fun i => (fderiv 𝕜 fun x => Φ x i) x:= by
+  apply HasFDerivAt.fderiv
+  apply hasFDerivAt_pi''
+  intro i
+  rw [differentiableAt_pi] at h
+  exact (h i).hasFDerivAt
+
+lemma ContDiff.differentiable_fderiv (f : X → Y) (hf : ContDiff 𝕜 2 f) :
+    Differentiable 𝕜 (fun x => fderiv 𝕜 f x) := by
+  have hf' : ContDiff 𝕜 (1+1) f := hf
+  rw [contDiff_succ_iff_fderiv] at hf'
+  apply hf'.right.right.differentiable
+  decide
+
+lemma fderiv_coord_eq_proj_comp (h : DifferentiableAt 𝕜 Φ x):
+    (fderiv 𝕜 fun x => Φ x i) x = (ContinuousLinearMap.proj i).comp (fderiv 𝕜 Φ x) := by
+  rw [ContinousLinearMap.fderiv_pi', ContinuousLinearMap.proj_pi]
+  apply h
+end
+
+/-!
+
+## Space.deriv lemmas
+
+-/
+
+open Space
path: PhysLean/ClassicalMechanics/Space/VectorIdentities.lean
user: login: jstoobysmith
body: It would be better if this was `namespace Space`.
created_at: 2025-04-15T05:16:03Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,209 @@
+/-
+Copyright (c) 2025 Zhi Kai Pong. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+Authors: Zhi Kai Pong
+-/
+import PhysLean.ClassicalMechanics.Space.Basic
+import Mathlib.Analysis.InnerProductSpace.Calculus
+
+/-!
+
+# VectorIdentities
+
+In this file we define common vector calculus identities based on `Space`.
+
+-/
+
+/-!
+
+## General auxiliary lemmas
+
+-/
+
+section
+
+variable
+  {𝕜} [NontriviallyNormedField 𝕜]
+  {X} [NormedAddCommGroup X] [NormedSpace 𝕜 X]
+  {Y} [NormedAddCommGroup Y] [NormedSpace 𝕜 Y]
+  {ι : Type*} [Fintype ι] {Y' : ι → Type*} [∀ i, NormedAddCommGroup (Y' i)]
+  [∀ i, NormedSpace 𝕜 (Y' i)] {Φ : X → ∀ i, Y' i} {Φ' : X →L[𝕜] ∀ i, Y' i} {x : X}
+
+lemma ContinousLinearMap.fderiv_pi' (h : DifferentiableAt 𝕜 Φ x):
+    fderiv 𝕜 Φ x = ContinuousLinearMap.pi fun i => (fderiv 𝕜 fun x => Φ x i) x:= by
+  apply HasFDerivAt.fderiv
+  apply hasFDerivAt_pi''
+  intro i
+  rw [differentiableAt_pi] at h
+  exact (h i).hasFDerivAt
+
+lemma ContDiff.differentiable_fderiv (f : X → Y) (hf : ContDiff 𝕜 2 f) :
+    Differentiable 𝕜 (fun x => fderiv 𝕜 f x) := by
+  have hf' : ContDiff 𝕜 (1+1) f := hf
+  rw [contDiff_succ_iff_fderiv] at hf'
+  apply hf'.right.right.differentiable
+  decide
+
+lemma fderiv_coord_eq_proj_comp (h : DifferentiableAt 𝕜 Φ x):
+    (fderiv 𝕜 fun x => Φ x i) x = (ContinuousLinearMap.proj i).comp (fderiv 𝕜 Φ x) := by
+  rw [ContinousLinearMap.fderiv_pi', ContinuousLinearMap.proj_pi]
+  apply h
+end
+
+/-!
+
+## Space.deriv lemmas
+
+-/
+
+open Space
+
+/-- Derivatives on space distiribute over addition. -/
+lemma spacederiv_add [NormedAddCommGroup M] [NormedSpace ℝ M]
path: PhysLean/ClassicalMechanics/Space/VectorIdentities.lean
user: login: jstoobysmith
body: Since the function is called `deriv` not `spacederiv`, it would be better if this was called `deriv_add`. 
The namespace will make this `Space.deriv_add`
created_at: 2025-04-15T05:17:08Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,209 @@
+/-
+Copyright (c) 2025 Zhi Kai Pong. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+Authors: Zhi Kai Pong
+-/
+import PhysLean.ClassicalMechanics.Space.Basic
+import Mathlib.Analysis.InnerProductSpace.Calculus
+
+/-!
+
+# VectorIdentities
+
+In this file we define common vector calculus identities based on `Space`.
+
+-/
+
+/-!
+
+## General auxiliary lemmas
+
+-/
+
+section
+
+variable
+  {𝕜} [NontriviallyNormedField 𝕜]
+  {X} [NormedAddCommGroup X] [NormedSpace 𝕜 X]
+  {Y} [NormedAddCommGroup Y] [NormedSpace 𝕜 Y]
+  {ι : Type*} [Fintype ι] {Y' : ι → Type*} [∀ i, NormedAddCommGroup (Y' i)]
+  [∀ i, NormedSpace 𝕜 (Y' i)] {Φ : X → ∀ i, Y' i} {Φ' : X →L[𝕜] ∀ i, Y' i} {x : X}
+
+lemma ContinousLinearMap.fderiv_pi' (h : DifferentiableAt 𝕜 Φ x):
+    fderiv 𝕜 Φ x = ContinuousLinearMap.pi fun i => (fderiv 𝕜 fun x => Φ x i) x:= by
+  apply HasFDerivAt.fderiv
+  apply hasFDerivAt_pi''
+  intro i
+  rw [differentiableAt_pi] at h
+  exact (h i).hasFDerivAt
+
+lemma ContDiff.differentiable_fderiv (f : X → Y) (hf : ContDiff 𝕜 2 f) :
+    Differentiable 𝕜 (fun x => fderiv 𝕜 f x) := by
+  have hf' : ContDiff 𝕜 (1+1) f := hf
+  rw [contDiff_succ_iff_fderiv] at hf'
+  apply hf'.right.right.differentiable
+  decide
+
+lemma fderiv_coord_eq_proj_comp (h : DifferentiableAt 𝕜 Φ x):
+    (fderiv 𝕜 fun x => Φ x i) x = (ContinuousLinearMap.proj i).comp (fderiv 𝕜 Φ x) := by
+  rw [ContinousLinearMap.fderiv_pi', ContinuousLinearMap.proj_pi]
+  apply h
+end
+
+/-!
+
+## Space.deriv lemmas
+
+-/
+
+open Space
+
+/-- Derivatives on space distiribute over addition. -/
+lemma spacederiv_add [NormedAddCommGroup M] [NormedSpace ℝ M]
path: PhysLean/ClassicalMechanics/Space/VectorIdentities.lean
user: login: jstoobysmith
body: (Same with some of the lemmas below)
created_at: 2025-04-15T05:17:26Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,209 @@
+/-
+Copyright (c) 2025 Zhi Kai Pong. All rights reserved.
+Released under Apache 2.0 license as described in the file LICENSE.
+Authors: Zhi Kai Pong
+-/
+import PhysLean.ClassicalMechanics.Space.Basic
+import Mathlib.Analysis.InnerProductSpace.Calculus
+
+/-!
+
+# VectorIdentities
+
+In this file we define common vector calculus identities based on `Space`.
+
+-/
+
+/-!
+
+## General auxiliary lemmas
+
+-/
+
+section
+
+variable
+  {𝕜} [NontriviallyNormedField 𝕜]
+  {X} [NormedAddCommGroup X] [NormedSpace 𝕜 X]
+  {Y} [NormedAddCommGroup Y] [NormedSpace 𝕜 Y]
+  {ι : Type*} [Fintype ι] {Y' : ι → Type*} [∀ i, NormedAddCommGroup (Y' i)]
+  [∀ i, NormedSpace 𝕜 (Y' i)] {Φ : X → ∀ i, Y' i} {Φ' : X →L[𝕜] ∀ i, Y' i} {x : X}
+
+lemma ContinousLinearMap.fderiv_pi' (h : DifferentiableAt 𝕜 Φ x):
+    fderiv 𝕜 Φ x = ContinuousLinearMap.pi fun i => (fderiv 𝕜 fun x => Φ x i) x:= by
+  apply HasFDerivAt.fderiv
+  apply hasFDerivAt_pi''
+  intro i
+  rw [differentiableAt_pi] at h
+  exact (h i).hasFDerivAt
+
+lemma ContDiff.differentiable_fderiv (f : X → Y) (hf : ContDiff 𝕜 2 f) :
+    Differentiable 𝕜 (fun x => fderiv 𝕜 f x) := by
+  have hf' : ContDiff 𝕜 (1+1) f := hf
+  rw [contDiff_succ_iff_fderiv] at hf'
+  apply hf'.right.right.differentiable
+  decide
+
+lemma fderiv_coord_eq_proj_comp (h : DifferentiableAt 𝕜 Φ x):
+    (fderiv 𝕜 fun x => Φ x i) x = (ContinuousLinearMap.proj i).comp (fderiv 𝕜 Φ x) := by
+  rw [ContinousLinearMap.fderiv_pi', ContinuousLinearMap.proj_pi]
+  apply h
+end
+
+/-!
+
+## Space.deriv lemmas
+
+-/
+
+open Space
+
+/-- Derivatives on space distiribute over addition. -/
+lemma spacederiv_add [NormedAddCommGroup M] [NormedSpace ℝ M]
path: PhysLean/ClassicalMechanics/Space/VectorIdentities.lean
user: login: zhikaip
body: actually this is the same issue, it wasn't letting me name `deriv_add/deriv_commute` becuase of the namespace clash, `namespace Space` works!
created_at: 2025-04-15T13:00:06Z
author_association: COLLABORATOR

PR comments:
user: login: jstoobysmith
created_at: 2025-04-15T05:15:33Z
body: This in the Space folder seems good to me :). Having lots of helper lemmas is a good thing - this is what people mean when they talk about an API, you never know when those helper lemmas will come in use. 

We could maybe put the `General auxiliary lemmas` in the Mathematics folder, but there is only a few of them, so this is not vital. 

But this is a very nice PR :). 

I'll add one or two comments two small comments to the code.
author_association: MEMBER
user: login: zhikaip
created_at: 2025-04-15T13:03:03Z
body: renamed the relevant theorems and corrected namespace
author_association: COLLABORATOR
user: login: jstoobysmith
created_at: 2025-04-15T13:05:43Z
body: Great! To fix the linter you need to import the new file you made into the PhysLean.lean file (in alphabetical order).

Otherwise this all looks good to me :).

author_association: MEMBER