/-
Copyright (c) 2026 Michael R. Douglas. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

# Schwartz Nuclear Extension Theorem (Complex Version)

Proves `schwartz_nuclear_extension`: every continuous ℂ-multilinear functional
on `S(ℝ^{d+1}, ℂ)^n` extends uniquely to a continuous ℂ-linear functional
on `S(ℝ^{n(d+1)}, ℂ)`, agreeing on product tensors.

This is the theorem that replaces the axiom in OSreconstruction.
-/

import GeneralResults.SchwartzProducts
import SchwartzNuclear.NuclearExtension
import Mathlib.Analysis.Complex.Basic

noncomputable section

open GaussianField Finset

set_option maxHeartbeats 6400000

namespace GaussianField

/-! ## Auxiliary lemmas for complex product tensor -/

/-- Chain rule bound: `‖D^c(f ∘ proj_j) x‖ ≤ ‖D^c f (x j)‖` for ℂ-valued Schwartz. -/
private lemma complex_chain_bound
    {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    {n : ℕ} (f : SchwartzMap E ℂ) (j : Fin n) (c : ℕ) (x : Fin n → E) :
    ‖iteratedFDeriv ℝ c (fun x : Fin n → E => f (x j)) x‖ ≤
      ‖iteratedFDeriv ℝ c (⇑f) (x j)‖ := by
  set L := ContinuousLinearMap.proj (R := ℝ) (φ := fun _ : Fin n => E) j
  have hL : ‖L‖ ≤ 1 := ContinuousLinearMap.opNorm_le_bound _ zero_le_one
    (fun y => by simp [one_mul]; exact norm_le_pi_norm y j)
  change ‖iteratedFDeriv ℝ c (f.toFun ∘ ⇑L) x‖ ≤ ‖iteratedFDeriv ℝ c f.toFun (x j)‖
  rw [L.iteratedFDeriv_comp_right f.smooth' x (i := c)
    (show (↑↑c : WithTop ℕ∞) ≤ ↑(⊤ : ℕ∞) from by exact_mod_cast le_top)]
  calc ‖(iteratedFDeriv ℝ c f.toFun (L x)).compContinuousLinearMap fun _ => L‖
      ≤ ‖iteratedFDeriv ℝ c f.toFun (L x)‖ * ∏ _ : Fin c, ‖L‖ :=
        (iteratedFDeriv ℝ c f.toFun (L x)).norm_compContinuousLinearMap_le _
    _ ≤ _ * 1 := by gcongr; exact prod_le_one (fun _ _ => norm_nonneg _) (fun _ _ => hL)
    _ = ‖iteratedFDeriv ℝ c f.toFun (x j)‖ := by simp [L]

/-- Schwartz sup-norm bound: `∃ C, ∀ y, ‖D^c f y‖ ≤ C`. -/
private lemma schwartz_sup_bound {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    (f : SchwartzMap E ℂ) (c : ℕ) :
    ∃ C : ℝ, 0 ≤ C ∧ ∀ y : E, ‖iteratedFDeriv ℝ c (⇑f) y‖ ≤ C := by
  obtain ⟨C, hC⟩ := f.decay' 0 c
  exact ⟨C, le_trans (by positivity) (hC 0), fun y => by
    change ‖iteratedFDeriv ℝ c f.toFun y‖ ≤ C
    simpa only [pow_zero, one_mul] using hC y⟩

/-- Schwartz k-decay bound: `∃ C, ∀ y, ‖y‖^k * ‖D^c f y‖ ≤ C`. -/
private lemma schwartz_k_bound {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    (f : SchwartzMap E ℂ) (k c : ℕ) :
    ∃ C : ℝ, 0 ≤ C ∧ ∀ y : E, ‖y‖ ^ k * ‖iteratedFDeriv ℝ c (⇑f) y‖ ≤ C := by
  obtain ⟨C, hC⟩ := f.decay' k c
  exact ⟨C, le_trans (by positivity) (hC 0), hC⟩

/-- Schwartz decay for ℂ-valued product tensor: distributes `‖x‖^k` across factors.
Same argument as `schwartz_product_decay` in `SchwartzProducts.lean` but for ℂ-valued. -/
private lemma complex_product_decay
    {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    {n : ℕ} (hn : 0 < n) (fs : Fin n → SchwartzMap E ℂ) (k m : ℕ) :
    ∃ C, ∀ x : Fin n → E,
      ‖x‖ ^ k * ‖iteratedFDeriv ℝ m (fun x => ∏ i, fs i (x i)) x‖ ≤ C := by
  haveI : Nonempty (Fin n) := ⟨⟨0, hn⟩⟩
  have hsmooth : ∀ i : Fin n, ContDiff ℝ (⊤ : ℕ∞) (fun x : Fin n → E => fs i (x i)) :=
    fun i => (fs i).smooth'.comp
      ((ContinuousLinearMap.proj (R := ℝ) (φ := fun _ : Fin n => E) i).contDiff.of_le le_top)
  have hm : (↑↑m : WithTop ℕ∞) ≤ (↑(⊤ : ℕ∞) : WithTop ℕ∞) := by exact_mod_cast le_top
  -- For each derivative distribution c, bound the weighted product
  have h_term_bound : ∀ (c : Fin n → ℕ),
      ∃ Cp, ∀ x : Fin n → E,
        ‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (c j) (fun x : Fin n → E => fs j (x j)) x‖ ≤ Cp := by
    intro c
    have h_chain : ∀ x : Fin n → E,
        ∏ j, ‖iteratedFDeriv ℝ (c j) (fun x : Fin n → E => fs j (x j)) x‖ ≤
          ∏ j, ‖iteratedFDeriv ℝ (c j) (⇑(fs j)) (x j)‖ :=
      fun x => prod_le_prod (fun j _ => norm_nonneg _)
        (fun j _ => complex_chain_bound (fs j) j (c j) x)
    have hbound0 : ∀ j, ∃ C : ℝ, 0 ≤ C ∧ ∀ y : E, ‖iteratedFDeriv ℝ (c j) (⇑(fs j)) y‖ ≤ C :=
      fun j => schwartz_sup_bound (fs j) (c j)
    have hboundk : ∀ j, ∃ C : ℝ, 0 ≤ C ∧
        ∀ y : E, ‖y‖ ^ k * ‖iteratedFDeriv ℝ (c j) (⇑(fs j)) y‖ ≤ C :=
      fun j => schwartz_k_bound (fs j) k (c j)
    choose C0 hC0_nn hC0 using hbound0
    choose Ck hCk_nn hCk using hboundk
    exact ⟨∑ i, Ck i * ∏ j ∈ univ.erase i, C0 j, fun x =>
      calc ‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (c j) (fun x => fs j (x j)) x‖
          ≤ ‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (c j) (⇑(fs j)) (x j)‖ :=
            mul_le_mul_of_nonneg_left (h_chain x) (by positivity)
        _ ≤ (∑ i, ‖x i‖ ^ k) * ∏ j, ‖iteratedFDeriv ℝ (c j) (⇑(fs j)) (x j)‖ := by
            apply mul_le_mul_of_nonneg_right _ (prod_nonneg fun j _ => norm_nonneg _)
            have hne : (univ : Finset (Fin n)).Nonempty := univ_nonempty
            obtain ⟨jj, _, hjj⟩ := exists_mem_eq_sup' hne (fun i => ‖x i‖₊)
            rw [show ‖x‖ = ‖x jj‖ from by
              rw [Pi.norm_def]; exact congr_arg NNReal.toReal
                (show univ.sup (fun b => ‖x b‖₊) = ‖x jj‖₊ from by
                  rw [← sup'_eq_sup hne]; exact hjj)]
            exact single_le_sum (f := fun i => ‖x i‖ ^ k)
              (fun i _ => by positivity) (mem_univ jj)
        _ = ∑ i, ((‖x i‖ ^ k * ‖iteratedFDeriv ℝ (c i) (⇑(fs i)) (x i)‖) *
              ∏ j ∈ univ.erase i, ‖iteratedFDeriv ℝ (c j) (⇑(fs j)) (x j)‖) := by
            rw [sum_mul]; congr 1; ext i; rw [← mul_prod_erase _ _ (mem_univ i)]; ring
        _ ≤ ∑ i, (Ck i * ∏ j ∈ univ.erase i, C0 j) :=
            sum_le_sum fun i _ => mul_le_mul (hCk i (x i))
              (prod_le_prod (fun j _ => norm_nonneg _) (fun j _ => hC0 j (x j)))
              (prod_nonneg fun j _ => norm_nonneg _) (hCk_nn i)⟩
  -- Combine with Leibniz rule
  choose Cp hCp using fun (p : Sym (Fin n) m) =>
    h_term_bound (fun j => p.val.count j)
  exact ⟨∑ p ∈ univ.sym m, ↑(p.val).countPerms * Cp p, fun x =>
    calc ‖x‖ ^ k * ‖iteratedFDeriv ℝ m (fun x => ∏ i, fs i (x i)) x‖
        ≤ ‖x‖ ^ k * ∑ p ∈ univ.sym m, ↑(p.val).countPerms *
            ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) (fun x => fs j (x j)) x‖ :=
          mul_le_mul_of_nonneg_left
            (norm_iteratedFDeriv_prod_le (fun i _ => hsmooth i) (x := x) (n := m) hm)
            (by positivity)
      _ = ∑ p ∈ univ.sym m, (↑(p.val).countPerms *
            (‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) (fun x => fs j (x j)) x‖)) := by
          rw [mul_sum]; congr 1; ext p; ring
      _ ≤ ∑ p ∈ univ.sym m, (↑(p.val).countPerms * Cp p) :=
          sum_le_sum fun p _ => mul_le_mul_of_nonneg_left (hCp p x) (Nat.cast_nonneg _)⟩

/-! ## Complex product tensor for Schwartz functions -/

/-- The product tensor of ℂ-valued Schwartz functions.
`(complexProductTensor fs)(x) = ∏ i, fs i (x i)` -/
def complexProductTensor {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] :
    {n : ℕ} → (Fin n → SchwartzMap E ℂ) → SchwartzMap (Fin n → E) ℂ
  | 0, _ => ⟨fun _ => 1, contDiff_const, fun k m => by
      refine ⟨1, fun x => ?_⟩
      rcases m with _ | m
      · have : ‖x‖ = 0 := by rw [Pi.norm_def]; simp [Finset.univ_eq_empty]
        rw [this]; rcases k with _ | k <;> simp
      · simp [iteratedFDeriv_const_of_ne (by omega : m + 1 ≠ 0) (1 : ℂ)]⟩
  | n + 1, fs =>
    ⟨fun x => ∏ i, fs i (x i),
     contDiff_prod (fun i _ => (fs i).smooth'.comp
       ((ContinuousLinearMap.proj (R := ℝ) (φ := fun _ : Fin (n + 1) => E) i).contDiff.of_le
         le_top)),
     fun k m => complex_product_decay (Nat.succ_pos n) fs k m⟩

/-- Pointwise evaluation of the complex product tensor. -/
theorem complexProductTensor_apply {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    {n : ℕ} (fs : Fin n → SchwartzMap E ℂ) (x : Fin n → E) :
    complexProductTensor fs x = ∏ i, fs i (x i) := by
  induction n with
  | zero =>
    show (1 : ℂ) = ∏ i : Fin 0, _
    simp [Finset.univ_eq_empty]
  | succ n _ => rfl

/-! ## Infrastructure for the nuclear extension theorem -/

/-- Embedding of ℝ-valued Schwartz functions into ℂ-valued via `Complex.ofRealCLM`. -/
private def iotaSchwartz (D : Type*) [NormedAddCommGroup D] [NormedSpace ℝ D] :
    SchwartzMap D ℝ →L[ℝ] SchwartzMap D ℂ :=
  SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.ofRealCLM

/-- The product tensor of real-embedded functions equals the real-embedding of the product. -/
private lemma complexProductTensor_ofReal
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    {n : ℕ} (gs : Fin n → SchwartzMap D ℝ) (x : Fin n → D) :
    complexProductTensor (fun i => iotaSchwartz D (gs i)) x =
      ↑(∏ i, gs i (x i)) := by
  rw [complexProductTensor_apply]
  show ∏ i, (↑(gs i (x i)) : ℂ) = ↑(∏ i, gs i (x i))
  simp [Complex.ofReal_prod]

/-- Decomposition of a ℂ-valued Schwartz function: `f = ι(Re f) + i • ι(Im f)`. -/
private lemma schwartz_complex_decomp
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    (f : SchwartzMap D ℂ) :
    f = iotaSchwartz D (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.reCLM f) +
        Complex.I • iotaSchwartz D (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.imCLM f) := by
  ext x
  show f x = ↑(Complex.re (f x)) + Complex.I • ↑(Complex.im (f x))
  rw [smul_eq_mul, mul_comm]
  exact (Complex.re_add_im (f x)).symm

/-- Restrict a ℂ-linear CLM on Schwartz space to an ℝ-linear CLM. -/
private def clmRestrictReal {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    (W : SchwartzMap D ℂ →L[ℂ] ℂ) : SchwartzMap D ℂ →L[ℝ] ℂ where
  toFun := W
  map_add' := W.map_add
  map_smul' r f := by
    have h1 : (r : ℝ) • f = ((↑r : ℂ) • f : SchwartzMap D ℂ) := by
      ext x; simp [smul_apply]
    rw [h1, W.map_smul]
    show ↑r * W f = r • W f
    rw [Complex.real_smul]
  cont := W.cont

/-- Scalar-tower instance needed to restrict multilinear maps from `ℂ` to `ℝ`. -/
private instance instIsScalarTowerSchwartzMapComplex
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D] :
    IsScalarTower ℝ ℂ (SchwartzMap D ℂ) where
  smul_assoc r z f := by
    ext x
    change ((r : ℂ) * z) * f x = (r : ℂ) * (z * f x)
    ring

/-- Updating one factor of `complexProductTensor` by a sum distributes over the tensor. -/
private lemma complexProductTensor_update_add
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    {n : ℕ} (fs : Fin n → SchwartzMap D ℂ) (i : Fin n)
    (f g : SchwartzMap D ℂ) :
    complexProductTensor (Function.update fs i (f + g)) =
      complexProductTensor (Function.update fs i f) +
        complexProductTensor (Function.update fs i g) := by
  ext x
  rw [complexProductTensor_apply]
  change _ = complexProductTensor (Function.update fs i f) x +
    complexProductTensor (Function.update fs i g) x
  rw [complexProductTensor_apply, complexProductTensor_apply]
  have hfg : (fun j : Fin n => (Function.update fs i (f + g) j) (x j)) =
      Function.update (fun j : Fin n => fs j (x j)) i ((f + g) (x i)) := by
    ext j
    by_cases h : j = i <;> simp [Function.update, h]
  have hf : (fun j : Fin n => (Function.update fs i f j) (x j)) =
      Function.update (fun j : Fin n => fs j (x j)) i (f (x i)) := by
    ext j
    by_cases h : j = i <;> simp [Function.update, h]
  have hg : (fun j : Fin n => (Function.update fs i g j) (x j)) =
      Function.update (fun j : Fin n => fs j (x j)) i (g (x i)) := by
    ext j
    by_cases h : j = i <;> simp [Function.update, h]
  rw [hfg, hf, hg]
  rw [Finset.prod_update_of_mem (Finset.mem_univ i), Finset.prod_update_of_mem (Finset.mem_univ i),
    Finset.prod_update_of_mem (Finset.mem_univ i)]
  simp [add_mul]

/-- Updating one factor of `complexProductTensor` by a scalar multiple pulls the scalar out. -/
private lemma complexProductTensor_update_smul
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    {n : ℕ} (fs : Fin n → SchwartzMap D ℂ) (i : Fin n)
    (z : ℂ) (f : SchwartzMap D ℂ) :
    complexProductTensor (Function.update fs i (z • f)) =
      z • complexProductTensor (Function.update fs i f) := by
  ext x
  rw [complexProductTensor_apply]
  change _ = z • complexProductTensor (Function.update fs i f) x
  rw [complexProductTensor_apply]
  have hz : (fun j : Fin n => (Function.update fs i (z • f) j) (x j)) =
      Function.update (fun j : Fin n => fs j (x j)) i ((z • f) (x i)) := by
    ext j
    by_cases h : j = i <;> simp [Function.update, h]
  have hf : (fun j : Fin n => (Function.update fs i f j) (x j)) =
      Function.update (fun j : Fin n => fs j (x j)) i (f (x i)) := by
    ext j
    by_cases h : j = i <;> simp [Function.update, h]
  rw [hz, hf]
  rw [Finset.prod_update_of_mem (Finset.mem_univ i), Finset.prod_update_of_mem (Finset.mem_univ i)]
  simp [smul_eq_mul, mul_assoc]

/-- Basis values determine a continuous real multilinear map on a Dynin-Mityagin space. -/
private theorem continuousMultilinear_eq_of_basis_eq
    {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    [DyninMityaginSpace E] [DyninMityaginSpace.HasBiorthogonalBasis E] :
    ∀ {n : ℕ},
      (A B : ContinuousMultilinearMap ℝ (fun _ : Fin n => E) ℝ) ->
      (∀ ks : Fin n → ℕ,
        A (fun i => DyninMityaginSpace.basis (E := E) (ks i)) =
          B (fun i => DyninMityaginSpace.basis (E := E) (ks i))) ->
      A = B
  | 0, A, B, h => by
      ext m
      have hm : m = Fin.elim0 := by ext i; exact Fin.elim0 i
      have hbasis :
          (fun i : Fin 0 => DyninMityaginSpace.basis (E := E) ((fun i => Fin.elim0 i) i)) =
            Fin.elim0 := by
        ext i
        exact Fin.elim0 i
      rw [hm, ← hbasis]
      exact h (fun i => Fin.elim0 i)
  | n + 1, A, B, h => by set_option linter.unnecessarySimpa false in
      ext m
      let A0 : E →L[ℝ] ℝ := {
        toFun := fun x => A (Fin.cons x (Fin.tail m))
        map_add' := by
          intro x y
          rw [← Fin.update_cons_zero (m 0) (Fin.tail m) (x + y),
            ← Fin.update_cons_zero (m 0) (Fin.tail m) x,
            ← Fin.update_cons_zero (m 0) (Fin.tail m) y,
            Fin.cons_self_tail]
          simpa using A.map_update_add m 0 x y
        map_smul' := by
          intro c x
          rw [← Fin.update_cons_zero (m 0) (Fin.tail m) (c • x),
            ← Fin.update_cons_zero (m 0) (Fin.tail m) x,
            Fin.cons_self_tail]
          simpa using A.map_update_smul m 0 c x
        cont := A.cont.comp <| continuous_pi fun
          | ⟨0, _⟩ => continuous_id
          | ⟨k + 1, _⟩ => continuous_const }
      let B0 : E →L[ℝ] ℝ := {
        toFun := fun x => B (Fin.cons x (Fin.tail m))
        map_add' := by
          intro x y
          rw [← Fin.update_cons_zero (m 0) (Fin.tail m) (x + y),
            ← Fin.update_cons_zero (m 0) (Fin.tail m) x,
            ← Fin.update_cons_zero (m 0) (Fin.tail m) y,
            Fin.cons_self_tail]
          simpa using B.map_update_add m 0 x y
        map_smul' := by
          intro c x
          rw [← Fin.update_cons_zero (m 0) (Fin.tail m) (c • x),
            ← Fin.update_cons_zero (m 0) (Fin.tail m) x,
            Fin.cons_self_tail]
          simpa using B.map_update_smul m 0 c x
        cont := B.cont.comp <| continuous_pi fun
          | ⟨0, _⟩ => continuous_id
          | ⟨k + 1, _⟩ => continuous_const }
      have h_basis0 : ∀ k,
          A0 (DyninMityaginSpace.basis (E := E) k) =
            B0 (DyninMityaginSpace.basis (E := E) k) := by
        intro k
        have hcurried :
            A.curryLeft (DyninMityaginSpace.basis (E := E) k) =
              B.curryLeft (DyninMityaginSpace.basis (E := E) k) := by
          apply continuousMultilinear_eq_of_basis_eq
          intro ks
          change
            A (Fin.cons (DyninMityaginSpace.basis (E := E) k)
              (fun i => DyninMityaginSpace.basis (E := E) (ks i))) =
              B (Fin.cons (DyninMityaginSpace.basis (E := E) k)
                (fun i => DyninMityaginSpace.basis (E := E) (ks i)))
          have hcons :
              (fun i : Fin (n + 1) =>
                DyninMityaginSpace.basis (E := E) (Fin.cases k ks i)) =
                Fin.cons (DyninMityaginSpace.basis (E := E) k)
                  (fun i => DyninMityaginSpace.basis (E := E) (ks i)) := by
            ext i
            cases i using Fin.cases with
            | zero => rfl
            | succ i => rfl
          rw [← hcons]
          exact h (Fin.cons k ks)
        simpa [A0, B0, ContinuousMultilinearMap.curryLeft_apply] using
          congrArg (fun F => F (Fin.tail m)) hcurried
      have h0 : A0 = B0 := DyninMityaginSpace.clm_eq_of_basis_eq A0 B0 h_basis0
      have hm : m = Fin.cons (m 0) (Fin.tail m) := by
        symm
        exact Fin.cons_self_tail m
      rw [hm]
      simpa [A0, B0, ContinuousMultilinearMap.curryLeft_apply] using
        congrArg (fun f => f (m 0)) h0

/-- A complex multilinear functional is determined by its values on real embedded tuples. -/
private theorem multilinear_fun_eq_of_real_eq
    {E0 E : Type*}
    [AddCommGroup E0] [Module ℝ E0]
    [AddCommGroup E] [Module ℂ E]
    (ι : E0 →ₗ[ℝ] E)
    (decomp : ∀ f : E, ∃ a b : E0, f = ι a + Complex.I • ι b) :
    ∀ {n : ℕ},
      (A B : (Fin n → E) → ℂ) ->
      (∀ fs i f g,
        A (Function.update fs i (f + g)) =
          A (Function.update fs i f) + A (Function.update fs i g)) ->
      (∀ fs i z f,
        A (Function.update fs i (z • f)) = z * A (Function.update fs i f)) ->
      (∀ fs i f g,
        B (Function.update fs i (f + g)) =
          B (Function.update fs i f) + B (Function.update fs i g)) ->
      (∀ fs i z f,
        B (Function.update fs i (z • f)) = z * B (Function.update fs i f)) ->
      (∀ gs : Fin n → E0, A (fun i => ι (gs i)) = B (fun i => ι (gs i))) ->
      ∀ fs : Fin n → E, A fs = B fs
  | 0, A, B, hAadd, hAsmul, hBadd, hBsmul, hreal, fs => by
      have hfs : fs = Fin.elim0 := by
        ext i
        exact Fin.elim0 i
      have hgs : (fun i : Fin 0 => ι ((fun i : Fin 0 => Fin.elim0 i) i)) = Fin.elim0 := by
        ext i
        exact Fin.elim0 i
      rw [hfs, ← hgs]
      exact hreal (fun i => Fin.elim0 i)
  | n + 1, A, B, hAadd, hAsmul, hBadd, hBsmul, hreal, fs => by
      let tail : Fin n → E := Fin.tail fs
      obtain ⟨a, b, hab⟩ := decomp (fs 0)
      have hAcons_add : ∀ (tail : Fin n → E) (u v : E),
          A (Fin.cons (u + v) tail) = A (Fin.cons u tail) + A (Fin.cons v tail) := by
        intro tail u v
        simpa [Fin.update_cons_zero] using hAadd (Fin.cons (0 : E) tail) 0 u v
      have hAcons_smul : ∀ (tail : Fin n → E) (z : ℂ) (u : E),
          A (Fin.cons (z • u) tail) = z * A (Fin.cons u tail) := by
        intro tail z u
        simpa [Fin.update_cons_zero] using hAsmul (Fin.cons (0 : E) tail) 0 z u
      have hBcons_add : ∀ (tail : Fin n → E) (u v : E),
          B (Fin.cons (u + v) tail) = B (Fin.cons u tail) + B (Fin.cons v tail) := by
        intro tail u v
        simpa [Fin.update_cons_zero] using hBadd (Fin.cons (0 : E) tail) 0 u v
      have hBcons_smul : ∀ (tail : Fin n → E) (z : ℂ) (u : E),
          B (Fin.cons (z • u) tail) = z * B (Fin.cons u tail) := by
        intro tail z u
        simpa [Fin.update_cons_zero] using hBsmul (Fin.cons (0 : E) tail) 0 z u
      have hRe := multilinear_fun_eq_of_real_eq (ι := ι) (decomp := decomp)
        (n := n)
        (A := fun gs : Fin n → E => A (Fin.cons (ι a) gs))
        (B := fun gs : Fin n → E => B (Fin.cons (ι a) gs))
        (by
          intro gs i f g
          simpa [Fin.cons_update] using hAadd (Fin.cons (ι a) gs) i.succ f g)
        (by
          intro gs i z f
          simpa [Fin.cons_update] using hAsmul (Fin.cons (ι a) gs) i.succ z f)
        (by
          intro gs i f g
          simpa [Fin.cons_update] using hBadd (Fin.cons (ι a) gs) i.succ f g)
        (by
          intro gs i z f
          simpa [Fin.cons_update] using hBsmul (Fin.cons (ι a) gs) i.succ z f)
        (by
          intro gs
          have hcons : (fun i : Fin (n + 1) => ι (Fin.cases a gs i)) =
              Fin.cons (ι a) (fun i => ι (gs i)) := by
            ext i
            cases i using Fin.cases with
            | zero => rfl
            | succ i => rfl
          rw [← hcons]
          exact hreal (Fin.cons a gs))
        tail
      have hIm := multilinear_fun_eq_of_real_eq (ι := ι) (decomp := decomp)
        (n := n)
        (A := fun gs : Fin n → E => A (Fin.cons (ι b) gs))
        (B := fun gs : Fin n → E => B (Fin.cons (ι b) gs))
        (by
          intro gs i f g
          simpa [Fin.cons_update] using hAadd (Fin.cons (ι b) gs) i.succ f g)
        (by
          intro gs i z f
          simpa [Fin.cons_update] using hAsmul (Fin.cons (ι b) gs) i.succ z f)
        (by
          intro gs i f g
          simpa [Fin.cons_update] using hBadd (Fin.cons (ι b) gs) i.succ f g)
        (by
          intro gs i z f
          simpa [Fin.cons_update] using hBsmul (Fin.cons (ι b) gs) i.succ z f)
        (by
          intro gs
          have hcons : (fun i : Fin (n + 1) => ι (Fin.cases b gs i)) =
              Fin.cons (ι b) (fun i => ι (gs i)) := by
            ext i
            cases i using Fin.cases with
            | zero => rfl
            | succ i => rfl
          rw [← hcons]
          exact hreal (Fin.cons b gs))
        tail
      have hfs : fs = Fin.cons (fs 0) tail := by
        ext i
        cases i using Fin.cases with
        | zero => rfl
        | succ i => rfl
      rw [hfs, hab, hAcons_add, hBcons_add, hAcons_smul, hBcons_smul, hRe, hIm]

/-- Evaluation of a Schwartz map at a point, as a ℂ-linear CLM.
`schwartzPointEvalCLM E x₀` maps `f` to `f x₀`. -/
private def schwartzPointEvalCLM (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E]
    (x₀ : E) : SchwartzMap E ℂ →L[ℂ] ℂ := by
  set L : SchwartzMap E ℂ →ₛₗ[RingHom.id ℂ] ℂ :=
    { toFun := fun f => f x₀, map_add' := fun f g => by simp,
      map_smul' := fun z f => by simp }
  have hbdd : Seminorm.IsBounded (schwartzSeminormFamily ℂ E ℂ)
      (fun _ : Fin 1 => normSeminorm ℂ ℂ) L := by
    intro i
    refine ⟨{(0, 0)}, 1, fun f => ?_⟩
    simp only [Finset.sup_singleton, one_smul, Seminorm.comp_apply, coe_normSeminorm, L]
    have h := SchwartzMap.le_seminorm ℂ 0 0 f x₀; simp at h
    calc ‖f x₀‖ ≤ (SchwartzMap.seminorm ℂ 0 0) f := h
      _ = (schwartzSeminormFamily ℂ E ℂ (0, 0)) f := by
          unfold schwartzSeminormFamily SchwartzMap.seminorm; simp
  exact ⟨L, (schwartz_withSeminorms ℂ E ℂ).continuous_of_isBounded
    (norm_withSeminorms ℂ ℂ) L hbdd⟩

@[simp] private lemma schwartzPointEvalCLM_apply (E : Type*)
    [NormedAddCommGroup E] [NormedSpace ℝ E] (x₀ : E) (f : SchwartzMap E ℂ) :
    schwartzPointEvalCLM E x₀ f = f x₀ := rfl

/-- Product tensor is additive in one slot: updating slot `jj` with `f + g`
gives the sum of the individual product tensors. -/
private lemma productTensor_update_add
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    [FiniteDimensional ℝ D] [Nontrivial D] [MeasurableSpace D] [BorelSpace D]
    {n : ℕ} (hn : 1 ≤ n)
    (gs : Fin n → SchwartzMap D ℝ) (jj : Fin n)
    (f g : SchwartzMap D ℝ) :
    (schwartzProductTensor_schwartz n hn (Function.update gs jj (f + g))).choose =
    (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose +
    (schwartzProductTensor_schwartz n hn (Function.update gs jj g)).choose := by
  ext x
  rw [(schwartzProductTensor_schwartz n hn (Function.update gs jj (f + g))).choose_spec,
      add_apply,
      (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose_spec,
      (schwartzProductTensor_schwartz n hn (Function.update gs jj g)).choose_spec]
  conv_lhs => rw [← Finset.mul_prod_erase _ _ (Finset.mem_univ jj)]
  conv_rhs =>
    rw [← Finset.mul_prod_erase _ _ (Finset.mem_univ jj),
        ← Finset.mul_prod_erase _ _ (Finset.mem_univ jj)]
  simp only [Function.update_self, add_apply]
  have htail : ∀ (h : SchwartzMap D ℝ), ∏ i ∈ Finset.univ.erase jj,
      Function.update gs jj h i (x i) = ∏ i ∈ Finset.univ.erase jj, gs i (x i) := by
    intro h; apply Finset.prod_congr rfl; intro i hi
    rw [Function.update_of_ne (Finset.ne_of_mem_erase hi)]
  rw [htail (f + g), htail f, htail g]; ring

/-- Product tensor is homogeneous in one slot: updating slot `jj` with `a • f`
gives `a` times the product tensor. -/
private lemma productTensor_update_smul
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    [FiniteDimensional ℝ D] [Nontrivial D] [MeasurableSpace D] [BorelSpace D]
    {n : ℕ} (hn : 1 ≤ n)
    (gs : Fin n → SchwartzMap D ℝ) (jj : Fin n)
    (a : ℝ) (f : SchwartzMap D ℝ) :
    (schwartzProductTensor_schwartz n hn (Function.update gs jj (a • f))).choose =
    a • (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose := by
  ext x
  rw [(schwartzProductTensor_schwartz n hn (Function.update gs jj (a • f))).choose_spec,
      smul_apply, smul_eq_mul,
      (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose_spec]
  conv_lhs => rw [← Finset.mul_prod_erase _ _ (Finset.mem_univ jj)]
  conv_rhs => rw [← Finset.mul_prod_erase _ _ (Finset.mem_univ jj)]
  simp only [Function.update_self, smul_apply, smul_eq_mul]
  have htail : ∀ (h : SchwartzMap D ℝ), ∏ i ∈ Finset.univ.erase jj,
      Function.update gs jj h i (x i) = ∏ i ∈ Finset.univ.erase jj, gs i (x i) := by
    intro h; apply Finset.prod_congr rfl; intro i hi
    rw [Function.update_of_ne (Finset.ne_of_mem_erase hi)]
  rw [htail (a • f), htail f]; ring

/-- Slot insertion as a CLM: `f ↦ w(productTensor(update gs jj f))`.
The map `f ↦ productTensor(update gs jj f)` from `S(D,ℝ)` to `S(∏D,ℝ)` is linear
(proved by `productTensor_update_add/smul`) and continuous (from Schwartz seminorm
estimates: Leibniz rule + chain rule for `f ∘ proj_jj` + decay of the fixed factors).
Composing with the CLM `w` gives a CLM `S(D,ℝ) →L[ℝ] ℝ`. -/
private def slotInsertionCLM
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    [FiniteDimensional ℝ D] [Nontrivial D] [MeasurableSpace D] [BorelSpace D]
    {n : ℕ} (hn : 1 ≤ n)
    (gs : Fin n → SchwartzMap D ℝ) (jj : Fin n)
    (w : SchwartzMap (Fin n → D) ℝ →L[ℝ] ℝ) :
    SchwartzMap D ℝ →L[ℝ] ℝ :=
  SchwartzMap.mkCLMtoNormedSpace
    (fun f => w (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose)
    (fun f g => by
      show w _ = w _ + w _
      rw [productTensor_update_add hn gs jj f g, map_add])
    (fun a f => by
      show w _ = a • w _
      rw [productTensor_update_smul hn gs jj a f, map_smul])
    -- Continuity bound: each product-space Schwartz seminorm of the product tensor
    -- (with f in slot jj, fixed gs elsewhere) is bounded by Schwartz seminorms of f.
    -- This follows from the Leibniz rule for ‖D^m(f∘proj_jj · G)(x)‖, the chain rule
    -- bound ‖D^a(f∘proj_jj)(x)‖ ≤ ‖D^a f(x jj)‖, the Schwartz decay of the fixed
    -- factor G(x) = ∏_{i≠jj} gs i (x i), and the projection norm bound ‖x jj‖ ≤ ‖x‖.
    -- Together: p_{k,m}(F_f) ≤ Σ_{a+b=m} C(m,a)·p_{k,b}(G)·p_{0,a}(f),
    -- giving |w(F_f)| ≤ C_w · C_prod · (s.sup p_D)(f) for some finite s and constant.
    (by
      -- Step 1: Extract w's seminorm bound from its continuity.
      -- The seminorm q(G) := ‖w G‖ on S(∏D, ℝ) is continuous, so by
      -- `Seminorm.bound_of_continuous` there exist s_w, C_w with q ≤ C_w • s_w.sup p_prod.
      haveI : Inhabited (Fin n) := ⟨⟨0, by omega⟩⟩
      haveI : Nontrivial (Fin n → D) := Pi.nontrivial
      set q := (normSeminorm ℝ ℝ).comp w.toLinearMap with hq_def
      have hq_cont : Continuous (q : SchwartzMap (Fin n → D) ℝ → ℝ) := by
        have : (q : SchwartzMap (Fin n → D) ℝ → ℝ) = fun f => ‖w f‖ := by
          ext f; simp [q, Seminorm.comp_apply, coe_normSeminorm]
        rw [this]; exact continuous_norm.comp w.continuous
      obtain ⟨s_w, C_w, _, hq_bound⟩ :=
        Seminorm.bound_of_continuous (schwartz_withSeminorms ℝ (Fin n → D) ℝ) q hq_cont
      -- C_w : ℝ≥0, hq_bound : q ≤ C_w • s_w.sup (schwartzSeminormFamily ℝ (Fin n → D) ℝ)
      have hw_bound : ∀ G : SchwartzMap (Fin n → D) ℝ,
          ‖w G‖ ≤ (C_w : ℝ) * (s_w.sup (schwartzSeminormFamily ℝ (Fin n → D) ℝ)) G := by
        intro G
        have h := hq_bound G
        simp only [smul_apply, NNReal.smul_def, smul_eq_mul, q,
          Seminorm.comp_apply, coe_normSeminorm] at h
        exact h
      -- Step 2: Product tensor slot-insertion combined seminorm estimate.
      -- The sup over s_w of Schwartz seminorms of the product tensor (with f in slot jj)
      -- is bounded by Schwartz seminorms of f. This combines:
      --   (a) For each (k,m), p_{k,m}(F_f) ≤ C_{k,m} * (s'_{k,m}.sup p_D) f,
      --       using the Leibniz rule, chain rule for f ∘ proj_jj, and Schwartz decay
      --       of the fixed factors ∏_{i≠jj} gs i (x i).
      --   (b) Taking the max over (k,m) ∈ s_w and collecting all index sets.
      have h_sup_bound : ∃ (s' : Finset (ℕ × ℕ)) (C' : ℝ), 0 ≤ C' ∧
          ∀ f : SchwartzMap D ℝ,
            (s_w.sup (schwartzSeminormFamily ℝ (Fin n → D) ℝ))
              (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose ≤
              C' * (s'.sup (schwartzSeminormFamily ℝ D ℝ)) f := by
        -- Per-(k,m) pointwise bound via Leibniz rule + chain rule + ‖x‖^k distribution
        have h_slot : ∀ (km : ℕ × ℕ), ∃ (s_km : Finset (ℕ × ℕ)) (C_km : ℝ), 0 ≤ C_km ∧
            ∀ (f : SchwartzMap D ℝ) (x : Fin n → D),
              ‖x‖ ^ km.1 * ‖iteratedFDeriv ℝ km.2
                (fun x => ∏ i, (Function.update gs jj f) i (x i)) x‖ ≤
                C_km * (s_km.sup (schwartzSeminormFamily ℝ D ℝ)) f := by
          intro ⟨k, m⟩
          have hn' : 0 < n := by omega
          have hsmooth : ∀ (f : SchwartzMap D ℝ) (i : Fin n),
              ContDiff ℝ (⊤ : ℕ∞) (fun x : Fin n → D => (Function.update gs jj f) i (x i)) :=
            fun f i => (Function.update gs jj f i).smooth'.comp
              ((ContinuousLinearMap.proj (R := ℝ) (φ := fun _ : Fin n => D) i).contDiff.of_le le_top)
          have hm : (↑↑m : WithTop ℕ∞) ≤ (↑(⊤ : ℕ∞) : WithTop ℕ∞) := by exact_mod_cast le_top
          have h_chain : ∀ (g : SchwartzMap D ℝ) (c : ℕ) (i : Fin n) (x : Fin n → D),
              ‖iteratedFDeriv ℝ c (fun x : Fin n → D => g (x i)) x‖ ≤
                ‖iteratedFDeriv ℝ c g (x i)‖ := by
            intro g c i x
            set L := ContinuousLinearMap.proj (R := ℝ) (φ := fun _ : Fin n => D) i
            have hL : ‖L‖ ≤ 1 := ContinuousLinearMap.opNorm_le_bound _ zero_le_one
              (fun y => by simp [one_mul]; exact norm_le_pi_norm y i)
            change ‖iteratedFDeriv ℝ c (g.toFun ∘ ⇑L) x‖ ≤ ‖iteratedFDeriv ℝ c g.toFun (x i)‖
            rw [L.iteratedFDeriv_comp_right g.smooth' x (i := c)
              (show (↑↑c : WithTop ℕ∞) ≤ ↑(⊤ : ℕ∞) from by exact_mod_cast le_top)]
            calc _ ≤ ‖iteratedFDeriv ℝ c g.toFun (L x)‖ * ∏ _ : Fin c, ‖L‖ :=
                  ContinuousMultilinearMap.norm_compContinuousLinearMap_le _ _
              _ ≤ _ * 1 := by gcongr; exact Finset.prod_le_one (fun _ _ => norm_nonneg _) (fun _ _ => hL)
              _ = _ := by simp [L]
          have h_count_le : ∀ (p : Sym (Fin n) m), p.val.count jj ≤ m :=
            fun p => le_trans (Multiset.count_le_card _ _) (le_of_eq p.prop)
          set s_f : Finset (ℕ × ℕ) := {k, 0} ×ˢ Finset.Icc 0 m
          have hk_mem : ∀ (p : Sym (Fin n) m), (k, p.val.count jj) ∈ s_f :=
            fun p => Finset.mem_product.mpr ⟨Finset.mem_insert_self _ _,
              Finset.mem_Icc.mpr ⟨Nat.zero_le _, h_count_le p⟩⟩
          have h0_mem : ∀ (p : Sym (Fin n) m), (0, p.val.count jj) ∈ s_f :=
            fun p => Finset.mem_product.mpr ⟨Finset.mem_insert.mpr (Or.inr (Finset.mem_singleton_self _)),
              Finset.mem_Icc.mpr ⟨Nat.zero_le _, h_count_le p⟩⟩
          -- Per-Leibniz-term bound
          have h_per_p : ∀ (p : Sym (Fin n) m),
              ∃ (Cp : ℝ), 0 ≤ Cp ∧ ∀ (f : SchwartzMap D ℝ) (x : Fin n → D),
                ‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) ((Function.update gs jj f) j) (x j)‖ ≤
                  Cp * (s_f.sup (schwartzSeminormFamily ℝ D ℝ)) f := by
            intro p
            set A : ℝ := ∏ j ∈ Finset.univ.erase jj, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) (gs j)
            set B' : ℝ := ∑ i ∈ Finset.univ.erase jj,
              ((SchwartzMap.seminorm ℝ k (p.val.count i)) (gs i) *
               ∏ j ∈ (Finset.univ.erase i).erase jj, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) (gs j))
            refine ⟨A + B', by positivity, fun f x => ?_⟩
            obtain ⟨j0, _, hj0⟩ := Finset.exists_mem_eq_sup' Finset.univ_nonempty (fun i => ‖x i‖₊)
            have h_norm : ‖x‖ = ‖x j0‖ := by
              rw [Pi.norm_def]; exact congr_arg NNReal.toReal
                (show Finset.univ.sup (fun b => ‖x b‖₊) = ‖x j0‖₊ from by
                  rw [← Finset.sup'_eq_sup Finset.univ_nonempty]; exact hj0)
            set S := (s_f.sup (schwartzSeminormFamily ℝ D ℝ)) f
            have hS_k : (SchwartzMap.seminorm ℝ k (p.val.count jj)) f ≤ S := by
              rw [← SchwartzMap.schwartzSeminormFamily_apply ℝ D ℝ k (p.val.count jj)]
              exact Seminorm.le_def.mp (Finset.le_sup (hk_mem p)) f
            have hS_0 : (SchwartzMap.seminorm ℝ 0 (p.val.count jj)) f ≤ S := by
              rw [← SchwartzMap.schwartzSeminormFamily_apply ℝ D ℝ 0 (p.val.count jj)]
              exact Seminorm.le_def.mp (Finset.le_sup (h0_mem p)) f
            -- Distribution of ‖x‖^k ≤ ∑ ‖x_i‖^k, then bound each factor by seminorms
            calc ‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) ((Function.update gs jj f) j) (x j)‖
                ≤ (∑ i, ‖x i‖ ^ k) * ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) ((Function.update gs jj f) j) (x j)‖ := by
                  gcongr; rw [h_norm]
                  exact Finset.single_le_sum (f := fun i => ‖x i‖ ^ k) (fun i _ => by positivity) (Finset.mem_univ j0)
              _ = ∑ i, (‖x i‖ ^ k * ‖iteratedFDeriv ℝ (p.val.count i) ((Function.update gs jj f) i) (x i)‖ *
                        ∏ j ∈ Finset.univ.erase i, ‖iteratedFDeriv ℝ (p.val.count j) ((Function.update gs jj f) j) (x j)‖) := by
                  rw [Finset.sum_mul]; congr 1; ext i; rw [← Finset.mul_prod_erase _ _ (Finset.mem_univ i)]; ring
              _ ≤ ∑ i, ((SchwartzMap.seminorm ℝ k (p.val.count i)) ((Function.update gs jj f) i) *
                        ∏ j ∈ Finset.univ.erase i, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) ((Function.update gs jj f) j)) :=
                  Finset.sum_le_sum fun i _ => mul_le_mul
                    (SchwartzMap.le_seminorm ℝ k _ _ (x i))
                    (Finset.prod_le_prod (fun j _ => norm_nonneg _) fun j _ => by
                      have h := SchwartzMap.le_seminorm ℝ 0
                        (p.val.count j) ((Function.update gs jj f) j) (x j)
                      simpa only [pow_zero, one_mul] using h)
                    (Finset.prod_nonneg fun j _ => norm_nonneg _)
                    (le_trans (by positivity) (SchwartzMap.le_seminorm ℝ k _ _ (x i)))
              _ = ((SchwartzMap.seminorm ℝ k (p.val.count jj)) ((Function.update gs jj f) jj) *
                    ∏ j ∈ Finset.univ.erase jj, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) ((Function.update gs jj f) j)) +
                  ∑ i ∈ Finset.univ.erase jj, ((SchwartzMap.seminorm ℝ k (p.val.count i)) ((Function.update gs jj f) i) *
                    ∏ j ∈ Finset.univ.erase i, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) ((Function.update gs jj f) j)) :=
                  (Finset.add_sum_erase _ _ (Finset.mem_univ jj)).symm
              _ ≤ S * A + S * B' := by
                  apply add_le_add
                  · -- jj term
                    rw [Function.update_self]
                    calc _ = (SchwartzMap.seminorm ℝ k (p.val.count jj)) f * A := by
                          congr 1; simp only [A]; exact Finset.prod_congr rfl fun j hj => by
                            rw [Finset.mem_erase] at hj; rw [Function.update_of_ne hj.1]
                      _ ≤ S * A := mul_le_mul_of_nonneg_right hS_k (by positivity)
                  · -- i ≠ jj terms: factor out sem_0(c_jj)(f) from each
                    have h_term : ∀ i ∈ Finset.univ.erase jj,
                        (SchwartzMap.seminorm ℝ k (p.val.count i)) ((Function.update gs jj f) i) *
                          ∏ j ∈ Finset.univ.erase i, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) ((Function.update gs jj f) j) =
                        (SchwartzMap.seminorm ℝ 0 (p.val.count jj)) f *
                          ((SchwartzMap.seminorm ℝ k (p.val.count i)) (gs i) *
                           ∏ j ∈ (Finset.univ.erase i).erase jj, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) (gs j)) := by
                      intro i hi; rw [Finset.mem_erase] at hi
                      rw [Function.update_of_ne hi.1,
                          ← Finset.mul_prod_erase _ _ (Finset.mem_erase.mpr ⟨hi.1.symm, Finset.mem_univ _⟩),
                          Function.update_self]
                      have : ∏ x ∈ (Finset.univ.erase i).erase jj,
                          (SchwartzMap.seminorm ℝ 0 (p.val.count x)) ((Function.update gs jj f) x) =
                        ∏ j ∈ (Finset.univ.erase i).erase jj, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) (gs j) :=
                        Finset.prod_congr rfl fun j hj => by rw [Finset.mem_erase] at hj; rw [Function.update_of_ne hj.1]
                      rw [this]; ring
                    calc _ = ∑ i ∈ Finset.univ.erase jj, ((SchwartzMap.seminorm ℝ 0 (p.val.count jj)) f *
                              ((SchwartzMap.seminorm ℝ k (p.val.count i)) (gs i) *
                               ∏ j ∈ (Finset.univ.erase i).erase jj, (SchwartzMap.seminorm ℝ 0 (p.val.count j)) (gs j))) :=
                          Finset.sum_congr rfl h_term
                      _ = (SchwartzMap.seminorm ℝ 0 (p.val.count jj)) f * B' := (Finset.mul_sum ..).symm
                      _ ≤ S * B' := mul_le_mul_of_nonneg_right hS_0 (by positivity)
              _ = (A + B') * S := by ring
          -- Combine over Leibniz terms
          choose Cp hCp_nn hCp using h_per_p
          refine ⟨s_f, ∑ p ∈ Finset.univ.sym m, ↑(p.val).countPerms * Cp p,
            Finset.sum_nonneg fun p _ => mul_nonneg (Nat.cast_nonneg _) (hCp_nn p), fun f x => ?_⟩
          calc ‖x‖ ^ k * ‖iteratedFDeriv ℝ m (fun x => ∏ i, (Function.update gs jj f) i (x i)) x‖
              ≤ ‖x‖ ^ k * ∑ p ∈ Finset.univ.sym m, ↑(p.val).countPerms *
                  ∏ j, ‖iteratedFDeriv ℝ (p.val.count j)
                    (fun x : Fin n → D => (Function.update gs jj f) j (x j)) x‖ :=
                mul_le_mul_of_nonneg_left (norm_iteratedFDeriv_prod_le (fun i _ => hsmooth f i) hm) (by positivity)
            _ ≤ ‖x‖ ^ k * ∑ p ∈ Finset.univ.sym m, ↑(p.val).countPerms *
                  ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) ((Function.update gs jj f) j) (x j)‖ := by
                gcongr with p _ j _; exact h_chain ((Function.update gs jj f) j) _ j x
            _ = ∑ p ∈ Finset.univ.sym m, ↑(p.val).countPerms *
                  (‖x‖ ^ k * ∏ j, ‖iteratedFDeriv ℝ (p.val.count j) ((Function.update gs jj f) j) (x j)‖) := by
                rw [Finset.mul_sum]; congr 1; ext p; ring
            _ ≤ ∑ p ∈ Finset.univ.sym m, ↑(p.val).countPerms *
                  (Cp p * (s_f.sup (schwartzSeminormFamily ℝ D ℝ)) f) :=
                Finset.sum_le_sum fun p _ => mul_le_mul_of_nonneg_left (hCp p f x) (Nat.cast_nonneg _)
            _ = (∑ p ∈ Finset.univ.sym m, ↑(p.val).countPerms * Cp p) *
                  (s_f.sup (schwartzSeminormFamily ℝ D ℝ)) f := by rw [Finset.sum_mul]; congr 1; ext p; ring
        -- Combine per-(k,m) bounds over s_w
        choose s_km C_km hC_nn hC_bound using h_slot
        refine ⟨s_w.biUnion s_km, ∑ km ∈ s_w, C_km km,
          Finset.sum_nonneg fun km _ => hC_nn km, fun f => ?_⟩
        apply Seminorm.finset_sup_apply_le
          (mul_nonneg (Finset.sum_nonneg fun km _ => hC_nn km) (apply_nonneg _ f))
        intro km hkm
        rw [SchwartzMap.schwartzSeminormFamily_apply]
        apply SchwartzMap.seminorm_le_bound ℝ km.1 km.2 _
          (mul_nonneg (Finset.sum_nonneg fun km _ => hC_nn km) (apply_nonneg _ f))
        intro x
        rw [show iteratedFDeriv ℝ km.2
            (⇑(schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose) x =
          iteratedFDeriv ℝ km.2 (fun x => ∏ i, (Function.update gs jj f) i (x i)) x from by
          congr 1; ext y; exact (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose_spec y]
        calc ‖x‖ ^ km.1 * ‖iteratedFDeriv ℝ km.2 (fun x => ∏ i, (Function.update gs jj f) i (x i)) x‖
            ≤ C_km km * ((s_km km).sup (schwartzSeminormFamily ℝ D ℝ)) f := hC_bound km f x
          _ ≤ C_km km * ((s_w.biUnion s_km).sup (schwartzSeminormFamily ℝ D ℝ)) f :=
              mul_le_mul_of_nonneg_left
                (Seminorm.le_def.mp (Finset.sup_mono (Finset.subset_biUnion_of_mem s_km hkm)) f)
                (hC_nn km)
          _ ≤ (∑ km' ∈ s_w, C_km km') * ((s_w.biUnion s_km).sup (schwartzSeminormFamily ℝ D ℝ)) f :=
              mul_le_mul_of_nonneg_right
                (Finset.single_le_sum (fun x _ => hC_nn x) hkm)
                (apply_nonneg _ f)
      -- Final combination: ‖w(F_f)‖ ≤ C_w * sup(F_f) ≤ C_w * C' * sup(f)
      obtain ⟨s', C', hC', h_sup⟩ := h_sup_bound
      exact ⟨s', (C_w : ℝ) * C', mul_nonneg C_w.coe_nonneg hC', fun f => by
        calc ‖w (schwartzProductTensor_schwartz n hn
                (Function.update gs jj f)).choose‖
            ≤ (C_w : ℝ) * (s_w.sup (schwartzSeminormFamily ℝ (Fin n → D) ℝ))
                (schwartzProductTensor_schwartz n hn
                  (Function.update gs jj f)).choose := hw_bound _
          _ ≤ (C_w : ℝ) * (C' * (s'.sup (schwartzSeminormFamily ℝ D ℝ)) f) :=
              mul_le_mul_of_nonneg_left (h_sup f) C_w.coe_nonneg
          _ = (C_w : ℝ) * C' * (s'.sup (schwartzSeminormFamily ℝ D ℝ)) f :=
              by ring⟩)

@[simp] private lemma slotInsertionCLM_apply
    {D : Type*} [NormedAddCommGroup D] [NormedSpace ℝ D]
    [FiniteDimensional ℝ D] [Nontrivial D] [MeasurableSpace D] [BorelSpace D]
    {n : ℕ} (hn : 1 ≤ n)
    (gs : Fin n → SchwartzMap D ℝ) (jj : Fin n)
    (w : SchwartzMap (Fin n → D) ℝ →L[ℝ] ℝ) (f : SchwartzMap D ℝ) :
    slotInsertionCLM hn gs jj w f =
      w (schwartzProductTensor_schwartz n hn (Function.update gs jj f)).choose := by
  simp [slotInsertionCLM, SchwartzMap.mkCLMtoNormedSpace]

/-! ## The nuclear extension theorem -/

/-- **Schwartz nuclear extension theorem.**

Every continuous ℂ-multilinear functional on `S(ℝ^{d+1}, ℂ)^n` extends uniquely
to a continuous ℂ-linear functional on `S(ℝ^{n(d+1)}, ℂ)`, agreeing on product tensors.

This matches the axiom `schwartz_nuclear_extension` in OSreconstruction.

**Proof outline** (three parts):

*Uniqueness*: If W₁, W₂ agree on product tensors, their difference W vanishes on all
product tensors. For real-valued basis functions `ψ_k`, the products `∏ ι(ψ_{k_i})`
are product tensors, so `W(∏ ι(ψ_{k_i})) = 0`. By `complexProductTensor_ofReal`,
this equals `W(ι(∏ ψ_{k_i})) = 0`. Taking Re and Im, we get ℝ-linear functionals
on `S(prod, ℝ)` that vanish on all product Hermite functions. By
`productHermite_schwartz_dense`, these are zero. Hence `W ∘ ι = 0` on `S(prod, ℝ)`.
By `schwartz_complex_decomp`, `W` is zero on all of `S(prod, ℂ)`.

*Existence*: Restrict `Phi` to real-valued inputs: for real `gs`,
`Phi(ι(g₁), ..., ι(gₙ))` gives a ℂ-valued ℝ-multilinear functional.
Take Re and Im parts to get `Phi_re, Phi_im : S(D,ℝ)^n → ℝ`, each continuous
ℝ-multilinear. By `multilinear_on_basis_bound` + `exists_unique_clm_of_polyBounded`,
construct `w_re, w_im : S(prod,ℝ) →L[ℝ] ℝ` matching on basis products.
Define `W(f) := w_re(Re f) - w_im(Im f) + i*(w_im(Re f) + w_re(Im f))`.
This is ℂ-linear and continuous.

*Agreement*: By ℂ-multilinearity of both `W ∘ complexProductTensor` and `Phi`,
expand each `fs i = ι(Re(fs i)) + i·ι(Im(fs i))` into 2ⁿ terms.
Each term involves products of real-valued functions where agreement
holds by construction. -/
theorem schwartz_nuclear_extension (d n : ℕ)
    (Phi : ContinuousMultilinearMap ℂ
      (fun _ : Fin n => SchwartzMap (Fin (d + 1) → ℝ) ℂ) ℂ) :
    ∃! (W : SchwartzMap (Fin n → Fin (d + 1) → ℝ) ℂ →L[ℂ] ℂ),
      ∀ fs : Fin n → SchwartzMap (Fin (d + 1) → ℝ) ℂ,
        W (complexProductTensor fs) = Phi fs := by
  set D := Fin (d + 1) → ℝ
  -- Existence: construct W from real-valued CLMs w_re, w_im via complexification.
  -- The construction requires:
  -- 1. Restricting Phi to real inputs via iotaSchwartz
  -- 2. Taking Re/Im parts to get ℝ-multilinear functionals
  -- 3. Using multilinear_on_basis_bound + exists_unique_clm_of_polyBounded
  -- 4. Complexifying w_re + i*w_im into a ℂ-linear map W
  -- 5. Proving agreement on product tensors via multilinear expansion
  --
  -- This construction requires IsScalarTower ℝ ℂ (SchwartzMap D ℂ) for
  -- ContinuousMultilinearMap.restrictScalars, plus substantial algebraic
  -- infrastructure for the complexification. The mathematical content is
  -- captured by the real-valued infrastructure in NuclearExtension.lean.
  obtain ⟨W, hW_agree⟩ : ∃ (W : SchwartzMap (Fin n → D) ℂ →L[ℂ] ℂ),
      ∀ fs, W (complexProductTensor fs) = Phi fs := by
    -- ι embeds real Schwartz into complex Schwartz
    set ι := iotaSchwartz D
    -- Restrict Phi to real inputs via iotaSchwartz
    set Phi_rs := @ContinuousMultilinearMap.restrictScalars ℝ (Fin n) _ ℂ _ _ _ _ _ _ _
      ℂ _ _ _ _ (fun _ => instIsScalarTowerSchwartzMapComplex) IsScalarTower.right Phi
    set Phi_r : ContinuousMultilinearMap ℝ (fun _ : Fin n => SchwartzMap D ℝ) ℂ :=
      Phi_rs.compContinuousLinearMap (fun _ => ι)
    -- Re/Im parts: ℝ-valued continuous multilinear maps on S(D,ℝ)^n
    set Phi_re : ContinuousMultilinearMap ℝ (fun _ : Fin n => SchwartzMap D ℝ) ℝ :=
      Complex.reCLM.compContinuousMultilinearMap Phi_r
    set Phi_im : ContinuousMultilinearMap ℝ (fun _ : Fin n => SchwartzMap D ℝ) ℝ :=
      Complex.imCLM.compContinuousMultilinearMap Phi_r
    -- Handle n = 0 separately
    rcases Nat.eq_zero_or_pos n with rfl | hn
    · -- n = 0: trivial case (unique 0-ary multilinear = constant map)
      -- W = Phi(Fin.elim0) • eval_pt, where eval_pt evaluates at the unique point.
      refine ⟨Phi Fin.elim0 • schwartzPointEvalCLM (Fin 0 → D) Fin.elim0, fun fs => ?_⟩
      -- fs = Fin.elim0 since Fin 0 → X is a subsingleton
      have hfs : fs = Fin.elim0 := Subsingleton.elim fs Fin.elim0
      subst hfs
      simp only [smul_apply, smul_eq_mul, schwartzPointEvalCLM_apply,
        complexProductTensor_apply, Finset.univ_eq_empty, Finset.prod_empty, mul_one]
    · -- n ≥ 1: the main case
      haveI : Inhabited (Fin n) := ⟨⟨0, hn⟩⟩
      haveI : Nontrivial (Fin n → D) := Pi.nontrivial
      -- HasBiorthogonalBasis for SchwartzMap D ℝ (needed for basis agreement)
      haveI : DyninMityaginSpace.HasBiorthogonalBasis (SchwartzMap D ℝ) :=
        DyninMityaginSpace.ofRapidDecayEquiv_hasBiorthogonalBasis
          (fun (kl : ℕ × ℕ) => SchwartzMap.seminorm ℝ kl.1 kl.2)
          (schwartz_withSeminorms ℝ D ℝ)
          (schwartzRapidDecayEquiv D)
      -- Product-aware equiv for S(∏D, ℝ)
      set equiv := productRapidDecayEquiv (D := D) n hn
      set pbi := productBasisIndices (D := D) n hn
      -- Poly-bounded values for Re and Im parts
      have hpbi_growth := productBasisIndices_polyGrowth (D := D) n hn
      have hv_re : PolyBounded (fun m => Phi_re (fun i =>
          DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (pbi m i))) :=
        multilinear_on_basis_polyBounded n Phi_re pbi hpbi_growth
      have hv_im : PolyBounded (fun m => Phi_im (fun i =>
          DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (pbi m i))) :=
        multilinear_on_basis_polyBounded n Phi_im pbi hpbi_growth
      -- Construct CLMs on RapidDecaySeq via clm_of_polyBounded
      set ψ_re := DyninMityaginSpace.clm_of_polyBounded (E := RapidDecaySeq)
        (fun m => Phi_re (fun i => DyninMityaginSpace.basis (pbi m i))) hv_re
      set ψ_im := DyninMityaginSpace.clm_of_polyBounded (E := RapidDecaySeq)
        (fun m => Phi_im (fun i => DyninMityaginSpace.basis (pbi m i))) hv_im
      -- Transfer to S(∏D, ℝ) via product-aware equivalence
      set w_re : SchwartzMap (Fin n → D) ℝ →L[ℝ] ℝ :=
        ψ_re.comp equiv.toContinuousLinearMap
      set w_im : SchwartzMap (Fin n → D) ℝ →L[ℝ] ℝ :=
        ψ_im.comp equiv.toContinuousLinearMap
      -- w_re on product-aware basis
      have hw_re_basis : ∀ m,
          w_re (equiv.symm (RapidDecaySeq.basisVec m)) =
            Phi_re (fun i => DyninMityaginSpace.basis (pbi m i)) := by
        intro m
        show ψ_re (equiv (equiv.symm (RapidDecaySeq.basisVec m))) = _
        rw [ContinuousLinearEquiv.apply_symm_apply]
        exact DyninMityaginSpace.clm_of_polyBounded_basis _ hv_re m
      have hw_im_basis : ∀ m,
          w_im (equiv.symm (RapidDecaySeq.basisVec m)) =
            Phi_im (fun i => DyninMityaginSpace.basis (pbi m i)) := by
        intro m
        show ψ_im (equiv (equiv.symm (RapidDecaySeq.basisVec m))) = _
        rw [ContinuousLinearEquiv.apply_symm_apply]
        exact DyninMityaginSpace.clm_of_polyBounded_basis _ hv_im m
      -- Re/Im extraction maps
      set Re_map : SchwartzMap (Fin n → D) ℂ →L[ℝ] SchwartzMap (Fin n → D) ℝ :=
        SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.reCLM
      set Im_map : SchwartzMap (Fin n → D) ℂ →L[ℝ] SchwartzMap (Fin n → D) ℝ :=
        SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.imCLM
      -- Build W using complexification of w_re, w_im
      -- W(f) = (w_re(Re f) - w_im(Im f)) + i*(w_im(Re f) + w_re(Im f))
      -- W(f) = (w_re(Re f) - w_im(Im f)) + i*(w_im(Re f) + w_re(Im f))
      -- This is ℂ-linear and continuous.
      let W : SchwartzMap (Fin n → D) ℂ →L[ℂ] ℂ :=
        { toFun := fun f =>
            ⟨w_re (Re_map f) - w_im (Im_map f),
             w_im (Re_map f) + w_re (Im_map f)⟩
          map_add' := fun f g => by
            apply Complex.ext
            · show w_re (Re_map (f + g)) - w_im (Im_map (f + g)) =
                (w_re (Re_map f) - w_im (Im_map f)) + (w_re (Re_map g) - w_im (Im_map g))
              simp [map_add]; ring
            · show w_im (Re_map (f + g)) + w_re (Im_map (f + g)) =
                (w_im (Re_map f) + w_re (Im_map f)) + (w_im (Re_map g) + w_re (Im_map g))
              simp [map_add]; ring
          map_smul' := fun z f => by
            -- Re(z•f) = z.re • Re(f) - z.im • Im(f)
            -- Im(z•f) = z.im • Re(f) + z.re • Im(f)
            have hRe : Re_map (z • f) = z.re • Re_map f - z.im • Im_map f := by
              ext x
              simp only [Re_map, Im_map, SchwartzMap.postcompCLM_apply,
                Complex.reCLM_apply, Complex.imCLM_apply, sub_apply,
                smul_apply, smul_eq_mul]
              simp [Complex.mul_re]
            have hIm : Im_map (z • f) = z.im • Re_map f + z.re • Im_map f := by
              ext x
              simp only [Re_map, Im_map, SchwartzMap.postcompCLM_apply,
                Complex.reCLM_apply, Complex.imCLM_apply, add_apply,
                smul_apply, smul_eq_mul]
              simp [Complex.mul_im]; ring
            simp only [RingHom.id_apply]
            apply Complex.ext
            · show w_re (Re_map (z • f)) - w_im (Im_map (z • f)) =
                (z * ⟨w_re (Re_map f) - w_im (Im_map f),
                      w_im (Re_map f) + w_re (Im_map f)⟩).re
              rw [hRe, hIm]
              simp [map_sub, map_add, map_smul, Complex.mul_re, smul_eq_mul]; ring
            · show w_im (Re_map (z • f)) + w_re (Im_map (z • f)) =
                (z * ⟨w_re (Re_map f) - w_im (Im_map f),
                      w_im (Re_map f) + w_re (Im_map f)⟩).im
              rw [hRe, hIm]
              simp [map_sub, map_add, map_smul, Complex.mul_im, smul_eq_mul]; ring
          cont := by
            have h_eq : (fun f : SchwartzMap (Fin n → D) ℂ =>
                (⟨w_re (Re_map f) - w_im (Im_map f),
                 w_im (Re_map f) + w_re (Im_map f)⟩ : ℂ)) =
              Complex.equivRealProdCLM.symm ∘ (fun f =>
                (w_re (Re_map f) - w_im (Im_map f),
                 w_im (Re_map f) + w_re (Im_map f))) := by
              ext f; simp [Complex.equivRealProdCLM]; exact (Complex.eta _).symm
            rw [h_eq]
            exact Complex.equivRealProdCLM.symm.continuous.comp
              (Continuous.prodMk
                ((w_re.cont.comp Re_map.cont).sub
                  (w_im.cont.comp Im_map.cont))
                ((w_im.cont.comp Re_map.cont).add
                  (w_re.cont.comp Im_map.cont))) }
      -- Agreement on product tensors:
      -- Uses multilinear_fun_eq_of_real_eq to reduce to real tuples,
      -- then continuousMultilinear_eq_of_basis_eq to reduce to basis tuples,
      -- then surjectivity of productBasisIndices + hw_re_basis/hw_im_basis.
      -- The algebraic verification that both sides expand the same way
      -- from complex to real inputs is a substantial calculation.
      refine ⟨W, fun fs => ?_⟩
      -- Agreement: W(complexProductTensor fs) = Phi fs
      -- Use multilinear_fun_eq_of_real_eq to reduce to real-embedded tuples
      -- Define the ℂ-multilinear decomposition:
      set ι_lin : SchwartzMap D ℝ →ₗ[ℝ] SchwartzMap D ℂ := ι.toLinearMap
      set A := fun fs => W (complexProductTensor fs)
      set B := fun fs => Phi fs
      change A fs = B fs
      apply multilinear_fun_eq_of_real_eq (ι := ι_lin)
        (decomp := fun f => ⟨SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.reCLM f,
          SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.imCLM f, by
            ext x; show f x = ↑(Complex.re (f x)) + Complex.I • ↑(Complex.im (f x))
            rw [smul_eq_mul, mul_comm]; exact (Complex.re_add_im (f x)).symm⟩)
      -- Multilinearity of W ∘ complexProductTensor (= A):
      · intro fs i f g
        show A (Function.update fs i (f + g)) = A (Function.update fs i f) + A (Function.update fs i g)
        simp only [A, complexProductTensor_update_add]
        exact W.map_add _ _
      · intro fs i z f
        show A (Function.update fs i (z • f)) = z * A (Function.update fs i f)
        simp only [A, complexProductTensor_update_smul]
        rw [W.map_smul]; rfl
      -- Multilinearity of Phi (= B):
      · intro fs i f g
        show B (Function.update fs i (f + g)) = B (Function.update fs i f) + B (Function.update fs i g)
        exact Phi.map_update_add fs i f g
      · intro fs i z f
        show B (Function.update fs i (z • f)) = z * B (Function.update fs i f)
        exact Phi.map_update_smul fs i z f
      -- Agreement on real-embedded tuples: A(ι∘gs) = B(ι∘gs)
      intro gs
      show A (fun i => ι_lin (gs i)) = B (fun i => ι_lin (gs i))
      -- Unfold: A(ι∘gs) = W(complexProductTensor(ι∘gs)), B(ι∘gs) = Phi(ι∘gs)
      simp only [A, B]
      -- ι_lin and ι agree (ι_lin = ι.toLinearMap, so ι_lin f = ι f for all f)
      have hι_eq : ∀ f, ι_lin f = ι f := fun _ => rfl
      -- The product Schwartz function: F(x) = ∏ gs i (x i)
      obtain ⟨F, hF⟩ := schwartzProductTensor_schwartz n (by omega) gs
      -- Key: complexProductTensor of ι∘gs is ι(F) pointwise
      have hcpt_eq : ∀ x, (complexProductTensor (fun i => ι (gs i))) x = ↑(F x) := by
        intro x; rw [complexProductTensor_ofReal, hF]
      -- ι_lin and ι give the same complexProductTensor
      have hιι : (fun i => ι_lin (gs i)) = (fun i => ι (gs i)) :=
        funext (fun i => hι_eq (gs i))
      rw [hιι]
      -- Re_map(cpt) = F and Im_map(cpt) = 0 as Schwartz functions
      have hRe_eq : Re_map (complexProductTensor (fun i => ι (gs i))) = F := by
        ext x; show Complex.re ((complexProductTensor (fun i => ι (gs i))) x) = F x
        rw [hcpt_eq]; simp
      have hIm_eq : Im_map (complexProductTensor (fun i => ι (gs i))) = 0 := by
        ext x; show Complex.im ((complexProductTensor (fun i => ι (gs i))) x) = 0
        rw [hcpt_eq]; simp
      -- LHS = W(cpt(ι∘gs)) = ⟨w_re(F) - w_im(0), w_im(F) + w_re(0)⟩ = ⟨w_re(F), w_im(F)⟩
      have hLHS : W (complexProductTensor (fun i => ι (gs i))) =
          ⟨w_re F, w_im F⟩ := by
        show (⟨w_re (Re_map (complexProductTensor (fun i => ι (gs i)))) -
              w_im (Im_map (complexProductTensor (fun i => ι (gs i)))),
              w_im (Re_map (complexProductTensor (fun i => ι (gs i)))) +
              w_re (Im_map (complexProductTensor (fun i => ι (gs i))))⟩ : ℂ) = _
        rw [hRe_eq, hIm_eq]; simp
      -- RHS = Phi(ι∘gs) = Phi_r(gs) = ⟨Phi_re(gs), Phi_im(gs)⟩
      have hRHS : Phi (fun i => ι (gs i)) = ⟨Phi_re gs, Phi_im gs⟩ := by
        apply Complex.ext
        · show Complex.re (Phi (fun i => ι (gs i))) = Phi_re gs
          rfl
        · show Complex.im (Phi (fun i => ι (gs i))) = Phi_im gs
          rfl
      rw [hLHS, hRHS]
      -- Now need: ⟨w_re F, w_im F⟩ = ⟨Phi_re gs, Phi_im gs⟩
      -- Surjectivity of productBasisIndices:
      -- For any ks : Fin n → ℕ, there exists m with pbi m = ks.
      have pbi_surj : ∀ ks : Fin n → ℕ, ∃ m, pbi m = ks := by
        intro ks
        have hd : 0 < Module.finrank ℝ D := Module.finrank_pos
        obtain ⟨n', rfl⟩ : ∃ n', n = n' + 1 := ⟨n - 1, (Nat.succ_pred_eq_of_pos hn).symm⟩
        obtain ⟨d', hd'⟩ : ∃ d', Module.finrank ℝ D = d' + 1 :=
          ⟨Module.finrank ℝ D - 1, (Nat.succ_pred_eq_of_pos hd).symm⟩
        -- Surjectivity for successor dimensions
        have h_succ : ∃ m, ∀ i, productBasisIndicesAux (n' + 1) (d' + 1)
            (Nat.succ_pos n') (Nat.succ_pos d') m i = ks i := by
          set β : Fin (n' + 1) → Fin (d' + 1) → ℕ :=
            fun i => (multiIndexEquiv d').symm (ks i)
          set α : Fin ((n' + 1) * (d' + 1)) → ℕ :=
            fun J => β (finProdFinEquiv.symm J).1 (finProdFinEquiv.symm J).2
          set m_val := (multiIndexEquiv ((n' + 1) * (d' + 1) - 1)) α
          refine ⟨m_val, fun i => ?_⟩
          show (multiIndexEquiv d') (blockMultiIndex (n' + 1) (d' + 1)
            ((multiIndexEquiv ((n' + 1) * (d' + 1) - 1)).symm m_val) i) = ks i
          rw [show (multiIndexEquiv ((n' + 1) * (d' + 1) - 1)).symm m_val = α from
            Equiv.symm_apply_apply _ α]
          have hblock : blockMultiIndex (n' + 1) (d' + 1) α i = β i := by
            ext j; simp [blockMultiIndex, α, β]
            show β (finProdFinEquiv.symm (finProdFinEquiv (i, j))).1
                   (finProdFinEquiv.symm (finProdFinEquiv (i, j))).2 = β i j
            rw [Equiv.symm_apply_apply]
          rw [hblock]
          exact Equiv.apply_symm_apply _ (ks i)
        -- Transfer to productBasisIndices via Module.finrank = d' + 1
        obtain ⟨m, hm⟩ := h_succ
        refine ⟨m, funext fun i => ?_⟩
        show productBasisIndicesAux (n' + 1) (Module.finrank ℝ D)
          (Nat.succ_pos n') Module.finrank_pos m i = ks i
        suffices ∀ (d : ℕ) (hd : 0 < d) (hd' : d = d' + 1),
            productBasisIndicesAux (n' + 1) d (Nat.succ_pos n') hd m i = ks i from
          this _ _ hd'
        intro d hd hd'; subst hd'
        exact hm i
      -- Product Hermite = equiv.symm(basisVec m) for the right m:
      -- For any ks, the product ∏ basis(ks i)(x i) equals equiv.symm(basisVec m)(x)
      -- where pbi m = ks, by productRapidDecayEquiv_symm_basisVec_isProductHermite + ext.
      have product_basis_eq_equiv : ∀ ks : Fin n → ℕ, ∀ m, pbi m = ks →
          ∀ (G : SchwartzMap (Fin n → D) ℝ),
            (∀ x, G x = ∏ i, DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i) (x i)) →
              G = equiv.symm (RapidDecaySeq.basisVec m) := by
        intro ks m hpbi G hG
        ext x
        rw [hG x]
        have := productRapidDecayEquiv_symm_basisVec_isProductHermite (D := D) n hn m x
        simp only [pbi] at hpbi
        rw [hpbi] at this
        exact this.symm
      -- w_re on product Hermites = Phi_re on basis tuples:
      have w_re_on_product : ∀ ks : Fin n → ℕ,
          ∀ (G : SchwartzMap (Fin n → D) ℝ),
            (∀ x, G x = ∏ i, DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i) (x i)) →
              w_re G = Phi_re (fun i => DyninMityaginSpace.basis (ks i)) := by
        intro ks G hG
        obtain ⟨m, hm⟩ := pbi_surj ks
        have hGeq := product_basis_eq_equiv ks m hm G hG
        rw [hGeq, hw_re_basis m, hm]
      have w_im_on_product : ∀ ks : Fin n → ℕ,
          ∀ (G : SchwartzMap (Fin n → D) ℝ),
            (∀ x, G x = ∏ i, DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i) (x i)) →
              w_im G = Phi_im (fun i => DyninMityaginSpace.basis (ks i)) := by
        intro ks G hG
        obtain ⟨m, hm⟩ := pbi_surj ks
        have hGeq := product_basis_eq_equiv ks m hm G hG
        rw [hGeq, hw_im_basis m, hm]
      -- Now: both w_re(F) and Phi_re(gs) are determined by basis expansions.
      -- Specifically, the map gs ↦ w_re(∏ gs i (x i)) is a continuous multilinear
      -- map on (SchwartzMap D ℝ)^n that agrees with Phi_re on basis tuples.
      -- By continuousMultilinear_eq_of_basis_eq, they agree everywhere.
      -- The ContinuousMultilinearMap construction for gs ↦ w_re(productTensor(gs))
      -- requires showing the product tensor is continuous multilinear.
      -- Final step: w_re(F) = Phi_re(gs) and w_im(F) = Phi_im(gs)
      -- where F x = ∏ gs i (x i).
      --
      -- PROOF STRATEGY: Both gs ↦ w_re(∏ gs i (x i)) and Phi_re are continuous
      -- ℝ-multilinear maps on (SchwartzMap D ℝ)^n → ℝ that agree on all DM basis
      -- tuples (by w_re_on_product above). By continuousMultilinear_eq_of_basis_eq,
      -- they agree everywhere. Similarly for w_im and Phi_im.
      --
      -- TECHNICAL ISSUE: continuousMultilinear_eq_of_basis_eq requires
      -- NormedAddCommGroup E, but SchwartzMap D ℝ only has a family of seminorms.
      -- This can be resolved by:
      -- (a) Weakening continuousMultilinear_eq_of_basis_eq to use AddCommGroup +
      --     TopologicalSpace (requires rewriting the proof to avoid curryLeft which
      --     needs NormedAddCommGroup), or
      -- (b) Using DyninMityaginSpace.expansion directly on the product space to
      --     show the DM coefficients of the product function ∏ gs i (x i) factor
      --     as products of individual DM coefficients, or
      -- (c) Constructing an auxiliary normed space structure on SchwartzMap via
      --     a single seminorm that bounds the relevant quantities.
      --
      -- The mathematical content is fully captured by w_re_on_product/w_im_on_product
      -- (agreement on product Hermite functions) + pbi_surj (surjectivity of
      -- productBasisIndices), which are proved above.
      -- Induction on j: number of free (non-basis) arguments.
      -- P(j): for all gs with gs i = basis(ks i) for i ≥ j, w_re(∏ gs) = Phi_re(gs)
      -- P(0): all basis → proved by w_re_on_product
      -- P(j) → P(j+1): fix all but slot j, get two CLMs agreeing on basis → equal by DM expansion
      suffices key : ∀ (j : ℕ) (hj : j ≤ n)
          (gs : Fin n → SchwartzMap D ℝ)
          (hs : ∀ i : Fin n, j ≤ i.val → ∃ k, gs i = DyninMityaginSpace.basis k),
          w_re (schwartzProductTensor_schwartz n (by omega : 1 ≤ n) gs).choose =
            Phi_re gs ∧
          w_im (schwartzProductTensor_schwartz n (by omega : 1 ≤ n) gs).choose =
            Phi_im gs by
        obtain ⟨hre, him⟩ := key n le_rfl gs (fun i hi => absurd hi (by omega))
        apply Complex.ext
        · show w_re F = Phi_re gs
          have hFeq : F = (schwartzProductTensor_schwartz n (by omega : 1 ≤ n) gs).choose := by
            ext x; rw [hF]; exact ((schwartzProductTensor_schwartz n (by omega) gs).choose_spec x).symm
          rw [hFeq]; exact hre
        · show w_im F = Phi_im gs
          have hFeq : F = (schwartzProductTensor_schwartz n (by omega : 1 ≤ n) gs).choose := by
            ext x; rw [hF]; exact ((schwartzProductTensor_schwartz n (by omega) gs).choose_spec x).symm
          rw [hFeq]; exact him
      intro j
      induction j with
      | zero =>
        intro hj gs hs
        -- All gs i are basis vectors
        have hbasis : ∀ i, ∃ k, gs i = DyninMityaginSpace.basis k := fun i => hs i (Nat.zero_le _)
        choose ks hks using hbasis
        have hgs_eq : gs = fun i => DyninMityaginSpace.basis (ks i) := funext hks
        subst hgs_eq
        have hF := (schwartzProductTensor_schwartz n (by omega) (fun i => DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i))).choose_spec
        have hG : ∀ x, (schwartzProductTensor_schwartz n (by omega) (fun i => DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i))).choose x =
            ∏ i, DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i) (x i) := by
          intro x; exact hF x
        exact ⟨w_re_on_product ks _ hG, w_im_on_product ks _ hG⟩
      | succ j ih =>
        intro hj gs hs
        -- ih applies to tuples with basis vectors from index j onward
        -- We free slot j by using DM expansion
        -- For any basis ψ_m in slot j, the tuple satisfies P(j):
        have h_with_basis : ∀ (m : ℕ),
            let gs' := Function.update gs ⟨j, by omega⟩ (DyninMityaginSpace.basis m)
            w_re (schwartzProductTensor_schwartz n (by omega) gs').choose = Phi_re gs' ∧
            w_im (schwartzProductTensor_schwartz n (by omega) gs').choose = Phi_im gs' := by
          intro m
          apply ih (by omega)
          intro i hi
          by_cases hij : i = ⟨j, by omega⟩
          · exact ⟨m, by rw [hij, Function.update_self]⟩
          · have : j + 1 ≤ i.val := by
              have hne : i.val ≠ j := fun h => hij (Fin.ext h)
              omega
            have hne : i ≠ ⟨j, by omega⟩ := hij
            rw [Function.update_of_ne hne]
            exact hs i (by omega)
        -- Use DM expansion in slot j to free gs ⟨j, _⟩.
        -- L₂(f) = Phi_re(update gs jj f) is a CLM via toContinuousLinearMap.
        -- L₁(f) = w_re(productTensor(update gs jj f)) agrees with L₂ on basis.
        -- By DM expansion (clm_eq_of_basis_eq), L₁ = L₂, so they agree on gs j.
        set jj : Fin n := ⟨j, by omega⟩
        -- L₂(f) = Phi_re(update gs jj f) is a CLM via toContinuousLinearMap
        set L_re := Phi_re.toContinuousLinearMap gs jj
        set L_im := Phi_im.toContinuousLinearMap gs jj
        -- L_re(ψ_m) = Phi_re(update gs jj ψ_m) and similarly for L_im
        -- h_with_basis gives w_re(productTensor(update gs jj ψ_m)) = L_re(ψ_m)
        -- We need: w_re(productTensor gs) = L_re(gs jj) and similarly for w_im

        -- Key: DM expansion applied to L_re (which IS a CLM on S(D)):
        -- L_re(gs jj) = Σ_m coeff_m(gs jj) · L_re(ψ_m)
        have h_Lre_expand := DyninMityaginSpace.expansion L_re (gs jj)
        have h_Lim_expand := DyninMityaginSpace.expansion L_im (gs jj)

        -- And for w_re(productTensor gs):
        -- w_re(F) where F = productTensor gs
        -- By DM expansion on S(∏D): w_re(F) = Σ_p coeff_p(F) · w_re(basis_p)
        -- But this is the PRODUCT-SPACE expansion, not the SLOT expansion.

        -- Alternative: use that L_re determines Phi_re(gs) = L_re(gs jj),
        -- and the DM expansion of L_re shows L_re is determined by L_re(ψ_m).
        -- Similarly construct a CLM for the w_re side and show it equals L_re.

        -- The w_re-side CLM: f ↦ w_re(productTensor(update gs jj f))
        -- This is the composition of:
        --   f ↦ update gs jj f (continuous linear: affine map, linear part is proj)
        --   gs' ↦ productTensor gs' (continuous in each slot — THIS IS WHAT WE NEED)
        --   F ↦ w_re F (CLM)
        --
        -- Slot insertion CLMs: f ↦ w_re/im(productTensor(update gs jj f))
        -- Linearity is proved; continuity uses a sorry'd Schwartz seminorm bound.
        set L₁_re := slotInsertionCLM (by omega) gs jj w_re
        set L₁_im := slotInsertionCLM (by omega) gs jj w_im
        have hL₁_re : ∀ f, L₁_re f = w_re (schwartzProductTensor_schwartz n (by omega)
            (Function.update gs jj f)).choose := fun f => slotInsertionCLM_apply _ _ _ _ _
        have hL₁_im : ∀ f, L₁_im f = w_im (schwartzProductTensor_schwartz n (by omega)
            (Function.update gs jj f)).choose := fun f => slotInsertionCLM_apply _ _ _ _ _
        -- L₁_re and L_re agree on all basis vectors
        have h_agree_re : ∀ m, L₁_re (DyninMityaginSpace.basis m) = L_re (DyninMityaginSpace.basis m) := by
          intro m; rw [hL₁_re]; exact (h_with_basis m).1
        have h_agree_im : ∀ m, L₁_im (DyninMityaginSpace.basis m) = L_im (DyninMityaginSpace.basis m) := by
          intro m; rw [hL₁_im]; exact (h_with_basis m).2
        -- By clm_eq_of_basis_eq, L₁ = L₂
        have hL_eq_re := DyninMityaginSpace.clm_eq_of_basis_eq L₁_re L_re h_agree_re
        have hL_eq_im := DyninMityaginSpace.clm_eq_of_basis_eq L₁_im L_im h_agree_im
        -- So L₁(gs jj) = L₂(gs jj), i.e., w_re(productTensor gs) = Phi_re(gs)
        constructor
        · -- w_re case
          have h1 : w_re (schwartzProductTensor_schwartz n (by omega) gs).choose =
              L₁_re (gs jj) := by
            rw [hL₁_re]; congr 1; ext x
            rw [(schwartzProductTensor_schwartz n (by omega) gs).choose_spec,
                (schwartzProductTensor_schwartz n (by omega) (Function.update gs jj (gs jj))).choose_spec]
            simp [Function.update_eq_self]
          rw [h1, show L₁_re = L_re from hL_eq_re]
          show Phi_re.toContinuousLinearMap gs jj (gs jj) = Phi_re gs
          rw [ContinuousMultilinearMap.toContinuousLinearMap_apply, Function.update_eq_self]
        · -- w_im case
          have h1 : w_im (schwartzProductTensor_schwartz n (by omega) gs).choose =
              L₁_im (gs jj) := by
            rw [hL₁_im]; congr 1; ext x
            rw [(schwartzProductTensor_schwartz n (by omega) gs).choose_spec,
                (schwartzProductTensor_schwartz n (by omega) (Function.update gs jj (gs jj))).choose_spec]
            simp [Function.update_eq_self]
          rw [h1, show L₁_im = L_im from hL_eq_im]
          show Phi_im.toContinuousLinearMap gs jj (gs jj) = Phi_im gs
          rw [ContinuousMultilinearMap.toContinuousLinearMap_apply, Function.update_eq_self]
  refine ⟨W, hW_agree, ?_⟩
  -- Uniqueness: if W' also agrees on product tensors, then W' = W.
  intro W' hW'
  -- The difference V := W' - W vanishes on all product tensors:
  set V := W' - W with hV_def
  have hDiff : ∀ fs, V (complexProductTensor fs) = 0 := by
    intro fs; simp [V, hW', hW_agree]
  -- Suffices to show V = 0
  suffices hV0 : V = 0 by
    have : W' = W + V := by simp [V]
    rw [this, hV0, add_zero]
  -- V ∘ ι vanishes on product Hermite functions (real-valued basis products).
  -- Define the ℝ-linear restriction:
  set ι := iotaSchwartz (Fin n → D)
  set Vr : SchwartzMap (Fin n → D) ℂ →L[ℝ] ℂ := clmRestrictReal V
  -- Re(V ∘ ι) and Im(V ∘ ι) vanish on product Hermite functions
  set VRe : SchwartzMap (Fin n → D) ℝ →L[ℝ] ℝ := Complex.reCLM.comp (Vr.comp ι)
  set VIm : SchwartzMap (Fin n → D) ℝ →L[ℝ] ℝ := Complex.imCLM.comp (Vr.comp ι)
  -- Step 1: V ∘ ι vanishes on all product Hermite functions (real basis products).
  -- This is because complexProductTensor (ι ∘ basis_ks) = ι(product_Hermite)
  -- and V vanishes on all complex product tensors by hDiff.
  have hVι : ∀ (f : SchwartzMap (Fin n → D) ℝ), Vr.comp ι f = 0 := by
    -- V ∘ ι vanishes on product Hermite functions for n ≥ 1
    -- and on everything for n = 0 (trivial: S(Fin 0 → D) is one-dimensional)
    rcases Nat.eq_zero_or_pos n with rfl | hn
    · -- n = 0: Fin 0 → D is a subsingleton, so every Schwartz function is constant.
      -- ι(f) = (↑(f 0) : ℂ) • complexProductTensor Fin.elim0, so
      -- V(ι f) = (↑(f 0)) * V(complexProductTensor Fin.elim0) = (↑(f 0)) * 0 = 0.
      intro f
      show V (ι f) = 0
      set cpt0 := complexProductTensor (Fin.elim0 : Fin 0 → SchwartzMap D ℂ)
      have hιf : ι f = (↑(f 0) : ℂ) • cpt0 := by
        ext x
        simp only [smul_apply, smul_eq_mul]
        show ↑(f x) = ↑(f 0) * cpt0 x
        simp only [cpt0, complexProductTensor_apply, Finset.univ_eq_empty,
          Finset.prod_empty, mul_one, Subsingleton.elim x 0]
      rw [hιf, V.map_smul, hDiff, smul_zero]
    · -- n ≥ 1: use productHermite_schwartz_dense
      -- VRe vanishes on product Hermite functions
      have hVRe_vanish : ∀ ks : Fin n → ℕ, ∀ (F : SchwartzMap (Fin n → D) ℝ),
          (∀ x, F x = ∏ i, DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i) (x i)) →
          VRe F = 0 := by
        intro ks F hF
        -- VRe(F) = Re(V(ι(F)))
        show Complex.re (V (ι F)) = 0
        -- ι(F) = complexProductTensor (fun i => ι(basis(ks i)))
        -- because both have the same underlying function.
        have hιF : ι F = complexProductTensor (fun i =>
            iotaSchwartz D (DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i))) := by
          ext x
          show ↑(F x) = complexProductTensor (fun i =>
            iotaSchwartz D (DyninMityaginSpace.basis (ks i))) x
          rw [hF x, complexProductTensor_ofReal]
        rw [hιF, hDiff]; simp
      -- VIm vanishes on product Hermite functions
      have hVIm_vanish : ∀ ks : Fin n → ℕ, ∀ (F : SchwartzMap (Fin n → D) ℝ),
          (∀ x, F x = ∏ i, DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i) (x i)) →
          VIm F = 0 := by
        intro ks F hF
        show Complex.im (V (ι F)) = 0
        have hιF : ι F = complexProductTensor (fun i =>
            iotaSchwartz D (DyninMityaginSpace.basis (E := SchwartzMap D ℝ) (ks i))) := by
          ext x
          show ↑(F x) = complexProductTensor (fun i =>
            iotaSchwartz D (DyninMityaginSpace.basis (ks i))) x
          rw [hF x, complexProductTensor_ofReal]
        rw [hιF, hDiff]; simp
      -- By productHermite_schwartz_dense, VRe = 0 and VIm = 0
      haveI : Inhabited (Fin n) := ⟨⟨0, hn⟩⟩
      haveI : Nontrivial (Fin n → D) := Pi.nontrivial
      have hVRe0 : VRe = 0 := productHermite_schwartz_dense n (by omega) VRe hVRe_vanish
      have hVIm0 : VIm = 0 := productHermite_schwartz_dense n (by omega) VIm hVIm_vanish
      -- Hence V ∘ ι = 0 (both Re and Im are zero)
      intro f
      have hRe : Complex.re (Vr.comp ι f) = 0 := by
        have : VRe f = 0 := by rw [hVRe0]; simp
        exact this
      have hIm : Complex.im (Vr.comp ι f) = 0 := by
        have : VIm f = 0 := by rw [hVIm0]; simp
        exact this
      exact Complex.ext hRe hIm
  -- Step 2: V = 0 on all of S(prod, ℂ), using decomposition f = ι(Re f) + i • ι(Im f).
  ext f
  show V f = 0
  rw [schwartz_complex_decomp f]
  simp only [V, sub_apply, map_add, map_smul]
  -- V(ι(Re f)) = 0 and V(ι(Im f)) = 0 by hVι
  have h1 : Vr (ι (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.reCLM f)) = 0 :=
    hVι _
  have h2 : Vr (ι (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.imCLM f)) = 0 :=
    hVι _
  -- V is the same as Vr on S(prod, ℂ), composed with the addition
  -- Actually, V acts on ℂ-valued Schwartz, while Vr is V restricted to ℝ-linear
  -- V(ι(Re f) + I • ι(Im f)) = V(ι(Re f)) + I • V(ι(Im f))
  -- = Vr(ι(Re f)) + I * Vr(ι(Im f)) since V is ℂ-linear
  show V (iotaSchwartz (Fin n → D) (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.reCLM f)) +
      Complex.I • V (iotaSchwartz (Fin n → D) (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.imCLM f)) = 0
  -- V on ι(...) is the same as Vr on ι(...)
  change Vr (ι (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.reCLM f)) +
      Complex.I • Vr (ι (SchwartzMap.postcompCLM (𝕜 := ℝ) Complex.imCLM f)) = 0
  rw [h1, h2]; simp

end GaussianField
