/-- The convolution `f * g` is `C^n` when `f` is locally integrable and `g` is `C^n` and compactly
supported. Version where `g` depends on an additional parameter in an open subset `s` of a
parameter space `P` (and the compact support `k` is independent of the parameter in `s`).
In this version, all the types belong to the same universe (to get an induction working in the
proof). Use instead `contDiffOn_convolution_right_with_param`, which removes this restriction. -/
theorem contDiffOn_convolution_right_with_param_aux {G : Type uP} {E' : Type uP} {F : Type uP}
    {P : Type uP} [NormedAddCommGroup E'] [NormedAddCommGroup F] [NormedSpace 𝕜 E']
    [NormedSpace ℝ F] [NormedSpace 𝕜 F] [CompleteSpace F] [MeasurableSpace G]
    {μ : MeasureTheory.Measure G}
    [NormedAddCommGroup G] [BorelSpace G] [NormedSpace 𝕜 G] [NormedAddCommGroup P] [NormedSpace 𝕜 P]
    {f : G → E} {n : ℕ∞} (L : E →L[𝕜] E' →L[𝕜] F) {g : P → G → E'} {s : Set P} {k : Set G}
    (hs : IsOpen s) (hk : IsCompact k) (hgs : ∀ p, ∀ x, p ∈ s → x ∉ k → g p x = 0)
    (hf : LocallyIntegrable f μ) (hg : ContDiffOn 𝕜 n (↿g) (s ×ˢ univ)) :
    ContDiffOn 𝕜 n (fun q : P × G => (f ⋆[L, μ] g q.1) q.2) (s ×ˢ univ) := by
  /- We have a formula for the derivation of `f * g`, which is of the same form, thanks to
    `hasFDerivAt_convolution_right_with_param`. Therefore, we can prove the result by induction on
    `n` (but for this we need the spaces at the different steps of the induction to live in the same
    universe, which is why we make the assumption in the lemma that all the relevant spaces
    come from the same universe). -/
  induction' n using ENat.nat_induction with n ih ih generalizing g E' F
  · rw [contDiffOn_zero] at hg ⊢
    exact continuousOn_convolution_right_with_param L hk hgs hf hg
  · let f' : P → G → P × G →L[𝕜] F := fun p a =>
      (f ⋆[L.precompR (P × G), μ] fun x : G => fderiv 𝕜 (uncurry g) (p, x)) a
    

Proof state:
case hsuc
𝕜 : Type u𝕜
G✝ : Type uG
E : Type uE
E'✝ : Type uE'
E'' : Type uE''
F✝ : Type uF
F' : Type uF'
F'' : Type uF''
P✝ : Type uP
inst✝²⁸ : NormedAddCommGroup E
inst✝²⁷ : NormedAddCommGroup E'✝
inst✝²⁶ : NormedAddCommGroup E''
inst✝²⁵ : NormedAddCommGroup F✝
f✝ f'✝ : G✝ → E
g✝ g' : G✝ → E'✝
x x' : G✝
y y' : E
inst✝²⁴ : IsROrC 𝕜
inst✝²³ : NormedSpace 𝕜 E
inst✝²² : NormedSpace 𝕜 E'✝
inst✝²¹ : NormedSpace 𝕜 E''
inst✝²⁰ : NormedSpace ℝ F✝
inst✝¹⁹ : NormedSpace 𝕜 F✝
inst✝¹⁸ : CompleteSpace F✝
inst✝¹⁷ : MeasurableSpace G✝
inst✝¹⁶ : NormedAddCommGroup G✝
inst✝¹⁵ : BorelSpace G✝
inst✝¹⁴ : NormedSpace 𝕜 G✝
inst✝¹³ : NormedAddCommGroup P✝
inst✝¹² : NormedSpace 𝕜 P✝
μ✝ : Measure G✝
L✝ : E →L[𝕜] E'✝ →L[𝕜] F✝
G P : Type uP
inst✝¹¹ : MeasurableSpace G
μ : Measure G
inst✝¹⁰ : NormedAddCommGroup G
inst✝⁹ : BorelSpace G
inst✝⁸ : NormedSpace 𝕜 G
inst✝⁷ : NormedAddCommGroup P
inst✝⁶ : NormedSpace 𝕜 P
f : G → E
s : Set P
k : Set G
hs : IsOpen s
hk : IsCompact k
hf : LocallyIntegrable f
n : ℕ
ih :
  ∀ {E' F : Type uP} [inst : NormedAddCommGroup E'] [inst_1 : NormedAddCommGroup F] [inst_2 : NormedSpace 𝕜 E']
    [inst_3 : NormedSpace ℝ F] [inst_4 : NormedSpace 𝕜 F] [inst_5 : CompleteSpace F] (L : E →L[𝕜] E' →L[𝕜] F)
    {g : P → G → E'},
    (∀ (p : P) (x : G), p ∈ s → x ∉ k → g p x = 0) →
      ContDiffOn 𝕜 (↑n) (↿g) (s ×ˢ univ) → ContDiffOn 𝕜 (↑n) (fun q => f ⋆[L, q.2] g q.1) (s ×ˢ univ)
E' F : Type uP
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedAddCommGroup F
inst✝³ : NormedSpace 𝕜 E'
inst✝² : NormedSpace ℝ F
inst✝¹ : NormedSpace 𝕜 F
inst✝ : CompleteSpace F
L : E →L[𝕜] E' →L[𝕜] F
g : P → G → E'
hgs : ∀ (p : P) (x : G), p ∈ s → x ∉ k → g p x = 0
hg : ContDiffOn 𝕜 (↑(Nat.succ n)) (↿g) (s ×ˢ univ)
f' : P → G → P × G →L[𝕜] F := fun p a => f ⋆[precompR (P × G) L, a] fun x => fderiv 𝕜 (uncurry g) (p, x)
⊢ ContDiffOn 𝕜 (↑(Nat.succ n)) (fun q => f ⋆[L, q.2] g q.1) (s ×ˢ univ)

Next tactic:
have A : ∀ q₀ : P × G, q₀.1 ∈ s →
        HasFDerivAt (fun q : P × G => (f ⋆[L, μ] g q.1) q.2) (f' q₀.1 q₀.2) q₀ :=
      hasFDerivAt_convolution_right_with_param L hs hk hgs hf hg.one_of_succ