/-- Contract an element of the clifford algebra with an element `d : Module.Dual R M` from the left.

Note that $v ⌋ x$ is spelt `contractLeft (Q.associated v) x`.

This includes [grinberg_clifford_2016][] Theorem 10.75 -/
def contractLeft : Module.Dual R M →ₗ[R] CliffordAlgebra Q →ₗ[R] CliffordAlgebra Q where
  toFun d := foldr' Q (contractLeftAux Q d) (contractLeftAux_contractLeftAux Q d) 0
  map_add' d₁ d₂ :=
    LinearMap.ext fun x => by
      dsimp only
      rw [LinearMap.add_apply]
      induction' x using CliffordAlgebra.left_induction with r x y hx hy m x hx
      · simp_rw [foldr'_algebraMap, smul_zero, zero_add]
      · rw [map_add, map_add, map_add, add_add_add_comm, hx, hy]
      · rw [foldr'_ι_mul, foldr'_ι_mul, foldr'_ι_mul, hx]
        dsimp only [contractLeftAux_apply_apply]
        rw [sub_add_sub_comm, mul_add, LinearMap.add_apply, add_smul]
  map_smul' c d :=
    LinearMap.ext fun x => by
      

Proof state:
R : Type u1
inst✝² : CommRing R
M : Type u2
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
d✝ d' : Module.Dual R M
c : R
d : Module.Dual R M
x : CliffordAlgebra Q
⊢ (AddHom.toFun
        {
          toFun := fun d =>
            foldr' Q (contractLeftAux Q d)
              (_ :
                ∀ (v : M) (x fx : CliffordAlgebra Q),
                  ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
              0,
          map_add' :=
            (_ :
              ∀ (d₁ d₂ : Module.Dual R M),
                (fun d =>
                      foldr' Q (contractLeftAux Q d)
                        (_ :
                          ∀ (v : M) (x fx : CliffordAlgebra Q),
                            ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                        0)
                    (d₁ + d₂) =
                  (fun d =>
                        foldr' Q (contractLeftAux Q d)
                          (_ :
                            ∀ (v : M) (x fx : CliffordAlgebra Q),
                              ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                          0)
                      d₁ +
                    (fun d =>
                        foldr' Q (contractLeftAux Q d)
                          (_ :
                            ∀ (v : M) (x fx : CliffordAlgebra Q),
                              ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                          0)
                      d₂) }
        (c • d))
      x =
    ((RingHom.id R) c •
        AddHom.toFun
          {
            toFun := fun d =>
              foldr' Q (contractLeftAux Q d)
                (_ :
                  ∀ (v : M) (x fx : CliffordAlgebra Q),
                    ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                0,
            map_add' :=
              (_ :
                ∀ (d₁ d₂ : Module.Dual R M),
                  (fun d =>
                        foldr' Q (contractLeftAux Q d)
                          (_ :
                            ∀ (v : M) (x fx : CliffordAlgebra Q),
                              ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                          0)
                      (d₁ + d₂) =
                    (fun d =>
                          foldr' Q (contractLeftAux Q d)
                            (_ :
                              ∀ (v : M) (x fx : CliffordAlgebra Q),
                                ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                            0)
                        d₁ +
                      (fun d =>
                          foldr' Q (contractLeftAux Q d)
                            (_ :
                              ∀ (v : M) (x fx : CliffordAlgebra Q),
                                ((contractLeftAux Q d) v) ((ι Q) v * x, ((contractLeftAux Q d) v) (x, fx)) = Q v • fx)
                            0)
                        d₂) }
          d)
      x

Next tactic:
dsimp only