/-- The heterogeneous differential as a linear map. Instead of taking a function as an argument this
differential takes `h : f x = y`. It is particularly handy to deal with situations where the points
on where it has to be evaluated are equal but not definitionally equal. -/
def hfdifferential {f : C^∞⟮I, M; I', M'⟯} {x : M} {y : M'} (h : f x = y) :
    PointDerivation I x →ₗ[𝕜] PointDerivation I' y where
  toFun v :=
    Derivation.mk'
      { toFun := fun g => v (g.comp f)
        map_add' := fun g g' => by dsimp; rw [SmoothMap.add_comp, Derivation.map_add]
        map_smul' := fun k g => by
          dsimp; rw [SmoothMap.smul_comp, Derivation.map_smul, smul_eq_mul] }
      fun g g' => by
        

Proof state:
𝕜 : 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
n : ℕ∞
X Y : Derivation 𝕜 C^⊤⟮I, M; 𝓘(𝕜, 𝕜), 𝕜⟯ C^⊤⟮I, M; 𝓘(𝕜, 𝕜), 𝕜⟯
f✝ g✝ : C^⊤⟮I, M; 𝓘(𝕜, 𝕜), 𝕜⟯
r : 𝕜
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'
f : C^⊤⟮I, M; I', M'⟯
x : M
y : M'
h : f x = y
v : PointDerivation I x
g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩
⊢ {
        toAddHom :=
          { toFun := fun g => v (ContMDiffMap.comp g f),
            map_add' :=
              (_ :
                ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                  (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                    (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') },
        map_smul' :=
          (_ :
            ∀ (k : 𝕜) (g : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
              AddHom.toFun
                  { toFun := fun g => v (ContMDiffMap.comp g f),
                    map_add' :=
                      (_ :
                        ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                          (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                            (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') }
                  (k • g) =
                (RingHom.id 𝕜) k •
                  AddHom.toFun
                    { toFun := fun g => v (ContMDiffMap.comp g f),
                      map_add' :=
                        (_ :
                          ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                            (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                              (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') }
                    g) }
      (g * g') =
    g •
        {
            toAddHom :=
              { toFun := fun g => v (ContMDiffMap.comp g f),
                map_add' :=
                  (_ :
                    ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                      (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                        (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') },
            map_smul' :=
              (_ :
                ∀ (k : 𝕜) (g : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                  AddHom.toFun
                      { toFun := fun g => v (ContMDiffMap.comp g f),
                        map_add' :=
                          (_ :
                            ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                              (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                                (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') }
                      (k • g) =
                    (RingHom.id 𝕜) k •
                      AddHom.toFun
                        { toFun := fun g => v (ContMDiffMap.comp g f),
                          map_add' :=
                            (_ :
                              ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                                (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                                  (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') }
                        g) }
          g' +
      g' •
        {
            toAddHom :=
              { toFun := fun g => v (ContMDiffMap.comp g f),
                map_add' :=
                  (_ :
                    ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                      (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                        (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') },
            map_smul' :=
              (_ :
                ∀ (k : 𝕜) (g : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                  AddHom.toFun
                      { toFun := fun g => v (ContMDiffMap.comp g f),
                        map_add' :=
                          (_ :
                            ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                              (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                                (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') }
                      (k • g) =
                    (RingHom.id 𝕜) k •
                      AddHom.toFun
                        { toFun := fun g => v (ContMDiffMap.comp g f),
                          map_add' :=
                            (_ :
                              ∀ (g g' : C^⊤⟮I', M'; 𝕜⟯⟨y⟩),
                                (fun g => v (ContMDiffMap.comp g f)) (g + g') =
                                  (fun g => v (ContMDiffMap.comp g f)) g + (fun g => v (ContMDiffMap.comp g f)) g') }
                        g) }
          g

Next tactic:
dsimp