l3lab/ntp-mathlib huggingface dataset:
/-- Given a multilinear map `f` in `n` variables to the space of linear maps from `M (last n)` to
`M₂`, construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (init m) (m (last n))`-/
def MultilinearMap.uncurryRight
    (f : MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂)) :
    MultilinearMap R M M₂ where
  toFun m := f (init m) (m (last n))
  map_add' {dec} m i x y := by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    by_cases h : i.val < n
    · have : last n ≠ i := Ne.symm (ne_of_lt h)
      simp_rw [update_noteq this]
      revert x y
      rw [(castSucc_castLT i h).symm]
      intro x y
      rw [init_update_castSucc, MultilinearMap.map_add, init_update_castSucc,
        init_update_castSucc, LinearMap.add_apply]
    · revert x y
      rw [eq_last_of_not_lt h]
      intro x y
      simp_rw [init_update_last, update_same, LinearMap.map_add]
  map_smul' {dec} m i c x := by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    by_cases h : i.val < n
    · have : last n ≠ i := Ne.symm (ne_of_lt h)
      simp_rw [update_noteq this]
      revert x
      rw [(castSucc_castLT i h).symm]
      intro x
      rw [init_update_castSucc, init_update_castSucc, MultilinearMap.map_smul,
        LinearMap.smul_apply]
    · revert x
      

Proof state:
case neg
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
c : R
h : ¬↑i < n
⊢ ∀ (x : M i),
    (fun m => (f (init m)) (m (last n))) (update m i (c • x)) = c • (fun m => (f (init m)) (m (last n))) (update m i x)

Next tactic:
rw [eq_last_of_not_lt h]
/-- Given a multilinear map `f` in `n` variables to the space of linear maps from `M (last n)` to
`M₂`, construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (init m) (m (last n))`-/
def MultilinearMap.uncurryRight
    (f : MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂)) :
    MultilinearMap R M M₂ where
  toFun m := f (init m) (m (last n))
  map_add' {dec} m i x y := by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    by_cases h : i.val < n
    · have : last n ≠ i := Ne.symm (ne_of_lt h)
      simp_rw [update_noteq this]
      revert x y
      rw [(castSucc_castLT i h).symm]
      intro x y
      rw [init_update_castSucc, MultilinearMap.map_add, init_update_castSucc,
        init_update_castSucc, LinearMap.add_apply]
    · revert x y
      rw [eq_last_of_not_lt h]
      intro x y
      simp_rw [init_update_last, update_same, LinearMap.map_add]
  map_smul' {dec} m i c x := by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    by_cases h : i.val < n
    · have : last n ≠ i := Ne.symm (ne_of_lt h)
      simp_rw [update_noteq this]
      revert x
      rw [(castSucc_castLT i h).symm]
      intro x
      rw [init_update_castSucc, init_update_castSucc, MultilinearMap.map_smul,
        LinearMap.smul_apply]
    · revert x
      rw [eq_last_of_not_lt h]
      

Proof state:
case neg
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
c : R
h : ¬↑i < n
⊢ ∀ (x : M (last n)),
    (fun m => (f (init m)) (m (last n))) (update m (last n) (c • x)) =
      c • (fun m => (f (init m)) (m (last n))) (update m (last n) x)

Next tactic:
intro x
/-- Given a multilinear map `f` in `n` variables to the space of linear maps from `M (last n)` to
`M₂`, construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (init m) (m (last n))`-/
def MultilinearMap.uncurryRight
    (f : MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂)) :
    MultilinearMap R M M₂ where
  toFun m := f (init m) (m (last n))
  map_add' {dec} m i x y := by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    by_cases h : i.val < n
    · have : last n ≠ i := Ne.symm (ne_of_lt h)
      simp_rw [update_noteq this]
      revert x y
      rw [(castSucc_castLT i h).symm]
      intro x y
      rw [init_update_castSucc, MultilinearMap.map_add, init_update_castSucc,
        init_update_castSucc, LinearMap.add_apply]
    · revert x y
      rw [eq_last_of_not_lt h]
      intro x y
      simp_rw [init_update_last, update_same, LinearMap.map_add]
  map_smul' {dec} m i c x := by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    by_cases h : i.val < n
    · have : last n ≠ i := Ne.symm (ne_of_lt h)
      simp_rw [update_noteq this]
      revert x
      rw [(castSucc_castLT i h).symm]
      intro x
      rw [init_update_castSucc, init_update_castSucc, MultilinearMap.map_smul,
        LinearMap.smul_apply]
    · revert x
      rw [eq_last_of_not_lt h]
      intro x
      

Proof state:
case neg
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
c : R
h : ¬↑i < n
x : M (last n)
⊢ (fun m => (f (init m)) (m (last n))) (update m (last n) (c • x)) =
    c • (fun m => (f (init m)) (m (last n))) (update m (last n) x)

Next tactic:
simp_rw [update_same, init_update_last, map_smul]
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by 

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
m : (i : Fin n) → M (castSucc i)
x y : M (last n)
⊢ (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y

Next tactic:
simp_rw [f.snoc_add]
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by 

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
m : (i : Fin n) → M (castSucc i)
c : R
x : M (last n)
⊢ AddHom.toFun
      { toFun := fun x => f (snoc m x),
        map_add' :=
          (_ :
            ∀ (x y : M (last n)),
              (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) }
      (c • x) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := fun x => f (snoc m x),
          map_add' :=
            (_ :
              ∀ (x y : M (last n)),
                (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) }
        x

Next tactic:
simp only [f.snoc_smul, RingHom.id_apply]
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
dec : DecidableEq (Fin n)
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
⊢ (fun m =>
        {
          toAddHom :=
            { toFun := fun x => f (snoc m x),
              map_add' :=
                (_ :
                  ∀ (x y : M (last n)),
                    (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
          map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
      (update m i (x + y)) =
    (fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i x) +
      (fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i y)

Next tactic:
rw [Subsingleton.elim dec (by clear dec; infer_instance)]
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    rw [Subsingleton.elim dec (by 

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
dec : DecidableEq (Fin n)
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
⊢ DecidableEq (Fin n)

Next tactic:
clear dec
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    rw [Subsingleton.elim dec (by clear dec; 

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
⊢ DecidableEq (Fin n)

Next tactic:
infer_instance
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; 

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
dec : DecidableEq (Fin n)
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
⊢ (fun m =>
        {
          toAddHom :=
            { toFun := fun x => f (snoc m x),
              map_add' :=
                (_ :
                  ∀ (x y : M (last n)),
                    (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
          map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
      (update m i (x + y)) =
    (fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i x) +
      (fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i y)

Next tactic:
clear dec
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    

Proof state:
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
⊢ (fun m =>
        {
          toAddHom :=
            { toFun := fun x => f (snoc m x),
              map_add' :=
                (_ :
                  ∀ (x y : M (last n)),
                    (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
          map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
      (update m i (x + y)) =
    (fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i x) +
      (fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i y)

Next tactic:
ext z
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    ext z
    

Proof state:
case h
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
z : M (last n)
⊢ ((fun m =>
          {
            toAddHom :=
              { toFun := fun x => f (snoc m x),
                map_add' :=
                  (_ :
                    ∀ (x y : M (last n)),
                      (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
            map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
        (update m i (x + y)))
      z =
    ((fun m =>
            {
              toAddHom :=
                { toFun := fun x => f (snoc m x),
                  map_add' :=
                    (_ :
                      ∀ (x y : M (last n)),
                        (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
              map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
          (update m i x) +
        (fun m =>
            {
              toAddHom :=
                { toFun := fun x => f (snoc m x),
                  map_add' :=
                    (_ :
                      ∀ (x y : M (last n)),
                        (fun x => f (snoc m x)) (x + y) = (fun x => f (snoc m x)) x + (fun x => f (snoc m x)) y) },
              map_smul' := (_ : ∀ (c : R) (x : M (last n)), f (snoc m (c • x)) = c • f (snoc m x)) })
          (update m i y))
      z

Next tactic:
change f (snoc (update m i (x + y)) z) = f (snoc (update m i x) z) + f (snoc (update m i y) z)
/-- Given a multilinear map `f` in `n+1` variables, split the last variable to obtain
a multilinear map in `n` variables taking values in linear maps from `M (last n)` to `M₂`, given by
`m ↦ (x ↦ f (snoc m x))`. -/
def MultilinearMap.curryRight (f : MultilinearMap R M M₂) :
    MultilinearMap R (fun i : Fin n => M (Fin.castSucc i)) (M (last n) →ₗ[R] M₂) where
  toFun m :=
    { toFun := fun x => f (snoc m x)
      map_add' := fun x y => by simp_rw [f.snoc_add]
      map_smul' := fun c x => by simp only [f.snoc_smul, RingHom.id_apply] }
  map_add' := @fun dec m i x y => by
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    ext z
    change f (snoc (update m i (x + y)) z) = f (snoc (update m i x) z) + f (snoc (update m i y) z)
    

Proof state:
case h
R : Type uR
S : Type uS
ι : Type uι
n : ℕ
M : Fin (Nat.succ n) → Type v
M₁ : ι → Type v₁
M₂ : Type v₂
M₃ : Type v₃
M' : Type v'
inst✝⁶ : CommSemiring R
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M'
inst✝³ : AddCommMonoid M₂
inst✝² : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹ : Module R M'
inst✝ : Module R M₂
f : MultilinearMap R M M₂
m : (i : Fin n) → M (castSucc i)
i : Fin n
x y : M (castSucc i)
z : M (last n)
⊢ f (snoc (update m i (x + y)) z) = f (snoc (update m i x) z) + f (snoc (update m i y) z)

Next tactic:
rw [snoc_update, snoc_update, snoc_update, f.map_add]