/-- The function that sends `x` to the `y`-derivative of `f(x,y)` at `g(x)` is `C^m` at `x₀`,
where the derivative is taken as a continuous linear map.
We have to assume that `f` is `C^n` at `(x₀, g(x₀))` for `n ≥ m + 1` and `g` is `C^m` at `x₀`.
We have to insert a coordinate change from `x₀` to `x` to make the derivative sensible.
This result is used to show that maps into the 1-jet bundle and cotangent bundle are smooth.
`ContMDiffAt.mfderiv_const` is a special case of this.

This result should be generalized to a `ContMDiffWithinAt` for `mfderivWithin`.
If we do that, we can deduce `ContMDiffOn.contMDiffOn_tangentMapWithin` from this.
-/
protected theorem ContMDiffAt.mfderiv {x₀ : N} (f : N → M → M') (g : N → M)
    (hf : ContMDiffAt (J.prod I) I' n (Function.uncurry f) (x₀, g x₀)) (hg : ContMDiffAt J I m g x₀)
    (hmn : m + 1 ≤ n) :
    ContMDiffAt J 𝓘(𝕜, E →L[𝕜] E') m
      (inTangentCoordinates I I' g (fun x => f x (g x)) (fun x => mfderiv I I' (f x) (g x)) x₀)
      x₀ := by
  have h4f : ContinuousAt (fun x => f x (g x)) x₀ :=
    ContinuousAt.comp_of_eq hf.continuousAt (continuousAt_id.prod hg.continuousAt) rfl
  have h4f := h4f.preimage_mem_nhds (extChartAt_source_mem_nhds I' (f x₀ (g x₀)))
  have h3f := contMDiffAt_iff_contMDiffAt_nhds.mp (hf.of_le <| (self_le_add_left 1 m).trans hmn)
  have h2f : ∀ᶠ x₂ in 𝓝 x₀, ContMDiffAt I I' 1 (f x₂) (g x₂) := by
    refine' ((continuousAt_id.prod hg.continuousAt).tendsto.eventually h3f).mono fun x hx => _
    exact hx.comp (g x) (contMDiffAt_const.prod_mk contMDiffAt_id)
  have h2g := hg.continuousAt.preimage_mem_nhds (extChartAt_source_mem_nhds I (g x₀))
  have :
    ContDiffWithinAt 𝕜 m
      (fun x =>
        fderivWithin 𝕜
          (extChartAt I' (f x₀ (g x₀)) ∘ f ((extChartAt J x₀).symm x) ∘ (extChartAt I (g x₀)).symm)
          (range I) (extChartAt I (g x₀) (g ((extChartAt J x₀).symm x))))
      (range J) (extChartAt J x₀ x₀) := by
    rw [contMDiffAt_iff] at hf hg
    simp_rw [Function.comp, uncurry, extChartAt_prod, PartialEquiv.prod_coe_symm,
      ModelWithCorners.range_prod] at hf ⊢
    refine' ContDiffWithinAt.fderivWithin _ hg.2 I.unique_diff hmn (mem_range_self _) _
    · simp_rw [extChartAt_to_inv]; exact hf.2
    · rw [← image_subset_iff]
      rintro _ ⟨x, -, rfl⟩
      exact mem_range_self _
  have :
    ContMDiffAt J 𝓘(𝕜, E →L[𝕜] E') m
      (fun x =>
        fderivWithin 𝕜 (extChartAt I' (f x₀ (g x₀)) ∘ f x ∘ (extChartAt I (g x₀)).symm) (range I)
          (extChartAt I (g x₀) (g x)))
      x₀ := by
    simp_rw [contMDiffAt_iff_source_of_mem_source (mem_chart_source G x₀),
      contMDiffWithinAt_iff_contDiffWithinAt, Function.comp]
    exact this
  have :
    ContMDiffAt J 𝓘(𝕜, E →L[𝕜] E') m
      (fun x =>
        fderivWithin 𝕜
          (extChartAt I' (f x₀ (g x₀)) ∘
            (extChartAt I' (f x (g x))).symm ∘
              writtenInExtChartAt I I' (g x) (f x) ∘
                extChartAt I (g x) ∘ (extChartAt I (g x₀)).symm)
          (range I) (extChartAt I (g x₀) (g x))) x₀ := by
    refine' this.congr_of_eventuallyEq _
    filter_upwards [h2g, h2f]
    intro x₂ hx₂ h2x₂
    have :
        ∀ x ∈ (extChartAt I (g x₀)).symm ⁻¹' (extChartAt I (g x₂)).source ∩
          (extChartAt I (g x₀)).symm ⁻¹' (f x₂ ⁻¹' (extChartAt I' (f x₂ (g x₂))).source),
          (extChartAt I' (f x₀ (g x₀)) ∘ (extChartAt I' (f x₂ (g x₂))).symm ∘
            writtenInExtChartAt I I' (g x₂) (f x₂) ∘ extChartAt I (g x₂) ∘
            (extChartAt I (g x₀)).symm) x =
          extChartAt I' (f x₀ (g x₀)) (f x₂ ((extChartAt I (g x₀)).symm x)) := by
      rintro x ⟨hx, h2x⟩
      simp_rw [writtenInExtChartAt, Function.comp_apply]
      rw [(extChartAt I (g x₂)).left_inv hx, (extChartAt I' (f x₂ (g x₂))).left_inv h2x]
    refine' Filter.EventuallyEq.fderivWithin_eq_nhds _
    refine' eventually_of_mem (inter_mem _ _) this
    · exact extChartAt_preimage_mem_nhds' _ _ hx₂ (extChartAt_source_mem_nhds I (g x₂))
    refine' extChartAt_preimage_mem_nhds' _ _ hx₂ _
    exact h2x₂.continuousAt.preimage_mem_nhds (extChartAt_source_mem_nhds _ _)
  /- The conclusion is equal to the following, when unfolding coord_change of
      `tangentBundleCore` -/
  -- Porting note: added
  letI _inst : ∀ x, NormedAddCommGroup (TangentSpace I (g x)) :=
    fun _ => inferInstanceAs (NormedAddCommGroup E)
  letI _inst : ∀ x, NormedSpace 𝕜 (TangentSpace I (g x)) :=
    fun _ => inferInstanceAs (NormedSpace 𝕜 E)
  have :
    ContMDiffAt J 𝓘(𝕜, E →L[𝕜] E') m
      (fun x =>
        (fderivWithin 𝕜 (extChartAt I' (f x₀ (g x₀)) ∘ (extChartAt I' (f x (g x))).symm) (range I')
              (extChartAt I' (f x (g x)) (f x (g x)))).comp
          ((mfderiv I I' (f x) (g x)).comp
            (fderivWithin 𝕜 (extChartAt I (g x) ∘ (extChartAt I (g x₀)).symm) (range I)
              (extChartAt I (g x₀) (g x))))) x₀ := by
    refine' this.congr_of_eventuallyEq _
    filter_upwards [h2g, h2f, h4f]
    intro x₂ hx₂ h2x₂ h3x₂
    symm
    rw [(h2x₂.mdifferentiableAt le_rfl).mfderiv]
    have hI := (contDiffWithinAt_ext_coord_change I (g x₂) (g x₀) <|
      PartialEquiv.mem_symm_trans_source _ hx₂ <|
        mem_extChartAt_source I (g x₂)).differentiableWithinAt le_top
    

Proof state:
case h
𝕜 : Type u_1
inst✝²⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝²³ : NormedAddCommGroup E
inst✝²² : NormedSpace 𝕜 E
H : Type u_3
inst✝²¹ : TopologicalSpace H
I : ModelWithCorners 𝕜 E H
M : Type u_4
inst✝²⁰ : TopologicalSpace M
inst✝¹⁹ : ChartedSpace H M
Is : SmoothManifoldWithCorners I M
E' : Type u_5
inst✝¹⁸ : NormedAddCommGroup E'
inst✝¹⁷ : NormedSpace 𝕜 E'
H' : Type u_6
inst✝¹⁶ : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M' : Type u_7
inst✝¹⁵ : TopologicalSpace M'
inst✝¹⁴ : ChartedSpace H' M'
I's : SmoothManifoldWithCorners I' M'
F : Type u_8
inst✝¹³ : NormedAddCommGroup F
inst✝¹² : NormedSpace 𝕜 F
G : Type u_9
inst✝¹¹ : TopologicalSpace G
J : ModelWithCorners 𝕜 F G
N : Type u_10
inst✝¹⁰ : TopologicalSpace N
inst✝⁹ : ChartedSpace G N
Js : SmoothManifoldWithCorners J N
F' : Type u_11
inst✝⁸ : NormedAddCommGroup F'
inst✝⁷ : NormedSpace 𝕜 F'
G' : Type u_12
inst✝⁶ : TopologicalSpace G'
J' : ModelWithCorners 𝕜 F' G'
N' : Type u_13
inst✝⁵ : TopologicalSpace N'
inst✝⁴ : ChartedSpace G' N'
J's : SmoothManifoldWithCorners J' N'
F₁ : Type u_14
inst✝³ : NormedAddCommGroup F₁
inst✝² : NormedSpace 𝕜 F₁
F₂ : Type u_15
inst✝¹ : NormedAddCommGroup F₂
inst✝ : NormedSpace 𝕜 F₂
f✝ f₁ : M → M'
s s₁ t : Set M
x : M
m n : ℕ∞
x₀ : N
f : N → M → M'
g : N → M
hf : ContMDiffAt (ModelWithCorners.prod J I) I' n (uncurry f) (x₀, g x₀)
hg : ContMDiffAt J I m g x₀
hmn : m + 1 ≤ n
h4f✝ : ContinuousAt (fun x => f x (g x)) x₀
h4f : (fun x => f x (g x)) ⁻¹' (extChartAt I' (f x₀ (g x₀))).source ∈ 𝓝 x₀
h3f : ∀ᶠ (x' : N × M) in 𝓝 (x₀, g x₀), ContMDiffAt (ModelWithCorners.prod J I) I' (↑One.one) (uncurry f) x'
h2f : ∀ᶠ (x₂ : N) in 𝓝 x₀, ContMDiffAt I I' 1 (f x₂) (g x₂)
h2g : g ⁻¹' (extChartAt I (g x₀)).source ∈ 𝓝 x₀
this✝¹ :
  ContDiffWithinAt 𝕜 m
    (fun x =>
      fderivWithin 𝕜
        (↑(extChartAt I' (f x₀ (g x₀))) ∘
          f (↑(PartialEquiv.symm (extChartAt J x₀)) x) ∘ ↑(PartialEquiv.symm (extChartAt I (g x₀))))
        (range ↑I) (↑(extChartAt I (g x₀)) (g (↑(PartialEquiv.symm (extChartAt J x₀)) x))))
    (range ↑J) (↑(extChartAt J x₀) x₀)
this✝ :
  ContMDiffAt J 𝓘(𝕜, E →L[𝕜] E') m
    (fun x =>
      fderivWithin 𝕜 (↑(extChartAt I' (f x₀ (g x₀))) ∘ f x ∘ ↑(PartialEquiv.symm (extChartAt I (g x₀)))) (range ↑I)
        (↑(extChartAt I (g x₀)) (g x)))
    x₀
this :
  ContMDiffAt J 𝓘(𝕜, E →L[𝕜] E') m
    (fun x =>
      fderivWithin 𝕜
        (↑(extChartAt I' (f x₀ (g x₀))) ∘
          ↑(PartialEquiv.symm (extChartAt I' (f x (g x)))) ∘
            writtenInExtChartAt I I' (g x) (f x) ∘ ↑(extChartAt I (g x)) ∘ ↑(PartialEquiv.symm (extChartAt I (g x₀))))
        (range ↑I) (↑(extChartAt I (g x₀)) (g x)))
    x₀
_inst✝ : (x : N) → NormedAddCommGroup (TangentSpace I (g x)) := fun x => inferInstanceAs (NormedAddCommGroup E)
_inst : (x : N) → NormedSpace 𝕜 (TangentSpace I (g x)) := fun x => inferInstanceAs (NormedSpace 𝕜 E)
x₂ : N
hx₂ : x₂ ∈ g ⁻¹' (extChartAt I (g x₀)).source
h2x₂ : ContMDiffAt I I' 1 (f x₂) (g x₂)
h3x₂ : x₂ ∈ (fun x => f x (g x)) ⁻¹' (extChartAt I' (f x₀ (g x₀))).source
hI :
  DifferentiableWithinAt 𝕜 (↑(extChartAt I (g x₂)) ∘ ↑(PartialEquiv.symm (extChartAt I (g x₀)))) (range ↑I)
    (↑(extChartAt I (g x₀)) (g x₂))
⊢ fderivWithin 𝕜
      (↑(extChartAt I' (f x₀ (g x₀))) ∘
        ↑(PartialEquiv.symm (extChartAt I' (f x₂ (g x₂)))) ∘
          writtenInExtChartAt I I' (g x₂) (f x₂) ∘ ↑(extChartAt I (g x₂)) ∘ ↑(PartialEquiv.symm (extChartAt I (g x₀))))
      (range ↑I) (↑(extChartAt I (g x₀)) (g x₂)) =
    ContinuousLinearMap.comp
      (fderivWithin 𝕜 (↑(extChartAt I' (f x₀ (g x₀))) ∘ ↑(PartialEquiv.symm (extChartAt I' (f x₂ (g x₂))))) (range ↑I')
        (↑(extChartAt I' (f x₂ (g x₂))) (f x₂ (g x₂))))
      (ContinuousLinearMap.comp
        (fderivWithin 𝕜 (writtenInExtChartAt I I' (g x₂) (f x₂)) (range ↑I) (↑(extChartAt I (g x₂)) (g x₂)))
        (fderivWithin 𝕜 (↑(extChartAt I (g x₂)) ∘ ↑(PartialEquiv.symm (extChartAt I (g x₀)))) (range ↑I)
          (↑(extChartAt I (g x₀)) (g x₂))))

Next tactic:
have hI' :=
      (contDiffWithinAt_ext_coord_change I' (f x₀ (g x₀)) (f x₂ (g x₂)) <|
            PartialEquiv.mem_symm_trans_source _ (mem_extChartAt_source I' (f x₂ (g x₂)))
              h3x₂).differentiableWithinAt le_top