/-- If the target space is complete, the space of continuous multilinear maps with its norm is also
complete. The proof is essentially the same as for the space of continuous linear maps (modulo the
addition of `Finset.prod` where needed. The duplication could be avoided by deducing the linear
case from the multilinear case via a currying isomorphism. However, this would mess up imports,
and it is more satisfactory to have the simplest case as a standalone proof. -/
instance completeSpace [CompleteSpace G] : CompleteSpace (ContinuousMultilinearMap 𝕜 E G) := by
  have nonneg : ∀ v : ∀ i, E i, 0 ≤ ∏ i, ‖v i‖ := fun v =>
    Finset.prod_nonneg fun i _ => norm_nonneg _
  -- We show that every Cauchy sequence converges.
  refine' Metric.complete_of_cauchySeq_tendsto fun f hf => _
  -- We now expand out the definition of a Cauchy sequence,
  rcases cauchySeq_iff_le_tendsto_0.1 hf with ⟨b, b0, b_bound, b_lim⟩
  -- and establish that the evaluation at any point `v : Π i, E i` is Cauchy.
  have cau : ∀ v, CauchySeq fun n => f n v := by
    intro v
    apply cauchySeq_iff_le_tendsto_0.2 ⟨fun n => b n * ∏ i, ‖v i‖, _, _, _⟩
    · intro
      exact mul_nonneg (b0 _) (nonneg v)
    · intro n m N hn hm
      rw [dist_eq_norm]
      apply le_trans ((f n - f m).le_op_norm v) _
      exact mul_le_mul_of_nonneg_right (b_bound n m N hn hm) (nonneg v)
    · simpa using b_lim.mul tendsto_const_nhds
  -- We assemble the limits points of those Cauchy sequences
  -- (which exist as `G` is complete)
  -- into a function which we call `F`.
  choose F hF using fun v => cauchySeq_tendsto_of_complete (cau v)
  -- Next, we show that this `F` is multilinear,
  let Fmult : MultilinearMap 𝕜 E G :=
    { toFun := F
      map_add' := fun v i x y => by
        skip
        have A := hF (Function.update v i (x + y))
        have B := (hF (Function.update v i x)).add (hF (Function.update v i y))
        simp? at A B says simp only [map_add] at A B
        exact tendsto_nhds_unique A B
      map_smul' := fun v i c x => by
        skip
        have A := hF (Function.update v i (c • x))
        have B := Filter.Tendsto.smul (@tendsto_const_nhds _ ℕ _ c _) (hF (Function.update v i x))
        simp? at A B says simp only [map_smul] at A B
        exact tendsto_nhds_unique A B }
  -- and that `F` has norm at most `(b 0 + ‖f 0‖)`.
  have Fnorm : ∀ v, ‖F v‖ ≤ (b 0 + ‖f 0‖) * ∏ i, ‖v i‖ := by
    intro v
    have A : ∀ n, ‖f n v‖ ≤ (b 0 + ‖f 0‖) * ∏ i, ‖v i‖ := by
      intro n
      apply le_trans ((f n).le_op_norm _) _
      apply mul_le_mul_of_nonneg_right _ (nonneg v)
      calc
        ‖f n‖ = ‖f n - f 0 + f 0‖ := by
          congr 1
          abel
        _ ≤ ‖f n - f 0‖ + ‖f 0‖ := (norm_add_le _ _)
        _ ≤ b 0 + ‖f 0‖ := by
          apply add_le_add_right
          simpa [dist_eq_norm] using b_bound n 0 0 (zero_le _) (zero_le _)
    exact le_of_tendsto (hF v).norm (eventually_of_forall A)
  -- Thus `F` is continuous, and we propose that as the limit point of our original Cauchy sequence.
  let Fcont := Fmult.mkContinuous _ Fnorm
  use Fcont
  -- Our last task is to establish convergence to `F` in norm.
  

Proof state:
case h
𝕜 : Type u
ι : Type v
ι' : Type v'
n : ℕ
E : ι → Type wE
E₁ : ι → Type wE₁
E' : ι' → Type wE'
Ei : Fin (Nat.succ n) → Type wEi
G : Type wG
G' : Type wG'
inst✝¹⁵ : Fintype ι
inst✝¹⁴ : Fintype ι'
inst✝¹³ : NontriviallyNormedField 𝕜
inst✝¹² : (i : ι) → NormedAddCommGroup (E i)
inst✝¹¹ : (i : ι) → NormedSpace 𝕜 (E i)
inst✝¹⁰ : (i : ι) → NormedAddCommGroup (E₁ i)
inst✝⁹ : (i : ι) → NormedSpace 𝕜 (E₁ i)
inst✝⁸ : (i : ι') → NormedAddCommGroup (E' i)
inst✝⁷ : (i : ι') → NormedSpace 𝕜 (E' i)
inst✝⁶ : (i : Fin (Nat.succ n)) → NormedAddCommGroup (Ei i)
inst✝⁵ : (i : Fin (Nat.succ n)) → NormedSpace 𝕜 (Ei i)
inst✝⁴ : NormedAddCommGroup G
inst✝³ : NormedSpace 𝕜 G
inst✝² : NormedAddCommGroup G'
inst✝¹ : NormedSpace 𝕜 G'
c : 𝕜
f✝ g : ContinuousMultilinearMap 𝕜 E G
m : (i : ι) → E i
inst✝ : CompleteSpace G
nonneg : ∀ (v : (i : ι) → E i), 0 ≤ ∏ i : ι, ‖v i‖
f : ℕ → ContinuousMultilinearMap 𝕜 E G
hf : CauchySeq f
b : ℕ → ℝ
b0 : ∀ (n : ℕ), 0 ≤ b n
b_bound : ∀ (n m N : ℕ), N ≤ n → N ≤ m → dist (f n) (f m) ≤ b N
b_lim : Tendsto b atTop (𝓝 0)
cau : ∀ (v : (i : ι) → E i), CauchySeq fun n => (f n) v
F : ((i : ι) → E i) → G
hF : ∀ (v : (i : ι) → E i), Tendsto (fun n => (f n) v) atTop (𝓝 (F v))
Fmult : MultilinearMap 𝕜 E G :=
  { toFun := F,
    map_add' :=
      (_ :
        ∀ [inst : DecidableEq ι] (v : (i : ι) → E i) (i : ι) (x y : E i),
          F (Function.update v i (x + y)) = F (Function.update v i x) + F (Function.update v i y)),
    map_smul' :=
      (_ :
        ∀ [inst : DecidableEq ι] (v : (i : ι) → E i) (i : ι) (c : 𝕜) (x : E i),
          F (Function.update v i (c • x)) = c • F (Function.update v i x)) }
Fnorm : ∀ (v : (i : ι) → E i), ‖F v‖ ≤ (b 0 + ‖f 0‖) * ∏ i : ι, ‖v i‖
Fcont : ContinuousMultilinearMap 𝕜 E G := MultilinearMap.mkContinuous Fmult (b 0 + ‖f 0‖) Fnorm
⊢ Tendsto f atTop (𝓝 Fcont)

Next tactic:
have : ∀ n, ‖f n - Fcont‖ ≤ b n := by
    intro n
    apply op_norm_le_bound _ (b0 n) fun v => ?_
    have A : ∀ᶠ m in atTop, ‖(f n - f m) v‖ ≤ b n * ∏ i, ‖v i‖ := by
      refine' eventually_atTop.2 ⟨n, fun m hm => _⟩
      apply le_trans ((f n - f m).le_op_norm _) _
      exact mul_le_mul_of_nonneg_right (b_bound n m n le_rfl hm) (nonneg v)
    have B : Tendsto (fun m => ‖(f n - f m) v‖) atTop (𝓝 ‖(f n - Fcont) v‖) :=
      Tendsto.norm (tendsto_const_nhds.sub (hF v))
    exact le_of_tendsto B A