l3lab/ntp-mathlib huggingface dataset:
/-- 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)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i 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₂
dec : DecidableEq (Fin n)
m : (i : Fin n) → M (castSucc i)
i : Fin n
c : R
x : 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 (c • x)) =
    c •
      (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)

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 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)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i c x => 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
c : R
x : 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; 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)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i c x => 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
c : R
x : 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)]; 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)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i c x => 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
c : R
x : 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 (c • x)) =
    c •
      (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)

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
    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)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i c x => 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
c : R
x : 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 (c • x)) =
    c •
      (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)

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
    change f (snoc (update m i (x + y)) z) = f (snoc (update m i x) z) + f (snoc (update m i y) z)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i c x => 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
c : R
x : 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 (c • x)))
      z =
    (c •
        (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))
      z

Next tactic:
change f (snoc (update m i (c • x)) z) = c • f (snoc (update m i x) 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)
    rw [snoc_update, snoc_update, snoc_update, f.map_add]
  map_smul' := @fun dec m i c x => by
    rw [Subsingleton.elim dec (by clear dec; infer_instance)]; clear dec
    ext z
    change f (snoc (update m i (c • x)) z) = c • f (snoc (update m i x) 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
c : R
x : M (castSucc i)
z : M (last n)
⊢ f (snoc (update m i (c • x)) z) = c • f (snoc (update m i x) z)

Next tactic:
rw [snoc_update, snoc_update, f.map_smul]
@[simp]
theorem MultilinearMap.curry_uncurryRight
    (f : MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂)) :
    f.uncurryRight.curryRight = f := 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 (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
⊢ curryRight (uncurryRight f) = f

Next tactic:
ext m x
@[simp]
theorem MultilinearMap.curry_uncurryRight
    (f : MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂)) :
    f.uncurryRight.curryRight = f := by
  ext m x
  

Proof state:
case H.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 (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin n) → M (castSucc i)
x : M (last n)
⊢ ((curryRight (uncurryRight f)) m) x = (f m) x

Next tactic:
simp only [snoc_last, MultilinearMap.curryRight_apply, MultilinearMap.uncurryRight_apply]
@[simp]
theorem MultilinearMap.curry_uncurryRight
    (f : MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂)) :
    f.uncurryRight.curryRight = f := by
  ext m x
  simp only [snoc_last, MultilinearMap.curryRight_apply, MultilinearMap.uncurryRight_apply]
  

Proof state:
case H.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 (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin n) → M (castSucc i)
x : M (last n)
⊢ (f (init (snoc m x))) x = (f m) x

Next tactic:
rw [init_snoc]
@[simp]
theorem MultilinearMap.uncurry_curryRight (f : MultilinearMap R M M₂) :
    f.curryRight.uncurryRight = f := 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₂
⊢ uncurryRight (curryRight f) = f

Next tactic:
ext m
@[simp]
theorem MultilinearMap.uncurry_curryRight (f : MultilinearMap R M M₂) :
    f.curryRight.uncurryRight = f := by
  ext m
  

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 (Nat.succ n)) → M i
⊢ (uncurryRight (curryRight f)) m = f m

Next tactic:
simp
/-- The space of multilinear maps on `∀ (i : Fin (n+1)), M i` is canonically isomorphic to
the space of linear maps from the space of multilinear maps on `∀ (i : Fin n), M (castSucc i)` to
the space of linear maps on `M (last n)`, by separating the last variable. We register this
isomorphism as a linear isomorphism in `multilinearCurryRightEquiv R M M₂`.

The direct and inverse maps are given by `f.uncurryRight` and `f.curryRight`. Use these
unless you need the full framework of linear equivs. -/
def multilinearCurryRightEquiv :
    MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂) ≃ₗ[R]
      MultilinearMap R M M₂ where
  toFun := MultilinearMap.uncurryRight
  map_add' f₁ f₂ := 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₁ f₂ : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
⊢ uncurryRight (f₁ + f₂) = uncurryRight f₁ + uncurryRight f₂

Next tactic:
ext m
/-- The space of multilinear maps on `∀ (i : Fin (n+1)), M i` is canonically isomorphic to
the space of linear maps from the space of multilinear maps on `∀ (i : Fin n), M (castSucc i)` to
the space of linear maps on `M (last n)`, by separating the last variable. We register this
isomorphism as a linear isomorphism in `multilinearCurryRightEquiv R M M₂`.

The direct and inverse maps are given by `f.uncurryRight` and `f.curryRight`. Use these
unless you need the full framework of linear equivs. -/
def multilinearCurryRightEquiv :
    MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂) ≃ₗ[R]
      MultilinearMap R M M₂ where
  toFun := MultilinearMap.uncurryRight
  map_add' f₁ f₂ := by
    ext m
    

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₁ f₂ : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin (Nat.succ n)) → M i
⊢ (uncurryRight (f₁ + f₂)) m = (uncurryRight f₁ + uncurryRight f₂) m

Next tactic:
rfl
/-- The space of multilinear maps on `∀ (i : Fin (n+1)), M i` is canonically isomorphic to
the space of linear maps from the space of multilinear maps on `∀ (i : Fin n), M (castSucc i)` to
the space of linear maps on `M (last n)`, by separating the last variable. We register this
isomorphism as a linear isomorphism in `multilinearCurryRightEquiv R M M₂`.

The direct and inverse maps are given by `f.uncurryRight` and `f.curryRight`. Use these
unless you need the full framework of linear equivs. -/
def multilinearCurryRightEquiv :
    MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂) ≃ₗ[R]
      MultilinearMap R M M₂ where
  toFun := MultilinearMap.uncurryRight
  map_add' f₁ f₂ := by
    ext m
    rfl
  map_smul' c f := 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₂
c : R
f : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
⊢ AddHom.toFun
      { toFun := uncurryRight,
        map_add' :=
          (_ :
            ∀ (f₁ f₂ : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)),
              uncurryRight (f₁ + f₂) = uncurryRight f₁ + uncurryRight f₂) }
      (c • f) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := uncurryRight,
          map_add' :=
            (_ :
              ∀ (f₁ f₂ : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)),
                uncurryRight (f₁ + f₂) = uncurryRight f₁ + uncurryRight f₂) }
        f

Next tactic:
ext m
/-- The space of multilinear maps on `∀ (i : Fin (n+1)), M i` is canonically isomorphic to
the space of linear maps from the space of multilinear maps on `∀ (i : Fin n), M (castSucc i)` to
the space of linear maps on `M (last n)`, by separating the last variable. We register this
isomorphism as a linear isomorphism in `multilinearCurryRightEquiv R M M₂`.

The direct and inverse maps are given by `f.uncurryRight` and `f.curryRight`. Use these
unless you need the full framework of linear equivs. -/
def multilinearCurryRightEquiv :
    MultilinearMap R (fun i : Fin n => M (castSucc i)) (M (last n) →ₗ[R] M₂) ≃ₗ[R]
      MultilinearMap R M M₂ where
  toFun := MultilinearMap.uncurryRight
  map_add' f₁ f₂ := by
    ext m
    rfl
  map_smul' c f := by
    ext m
    

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₂
c : R
f : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)
m : (i : Fin (Nat.succ n)) → M i
⊢ (AddHom.toFun
        { toFun := uncurryRight,
          map_add' :=
            (_ :
              ∀ (f₁ f₂ : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)),
                uncurryRight (f₁ + f₂) = uncurryRight f₁ + uncurryRight f₂) }
        (c • f))
      m =
    ((RingHom.id R) c •
        AddHom.toFun
          { toFun := uncurryRight,
            map_add' :=
              (_ :
                ∀ (f₁ f₂ : MultilinearMap R (fun i => M (castSucc i)) (M (last n) →ₗ[R] M₂)),
                  uncurryRight (f₁ + f₂) = uncurryRight f₁ + uncurryRight f₂) }
          f)
      m

Next tactic:
rw [smul_apply]