l3lab/ntp-mathlib huggingface dataset:
theorem mkPiRing_zero [Fintype ι] : MultilinearMap.mkPiRing R ι (0 : M₂) = 0 := 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 : ι) → AddCommMonoid (M₁ i)
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M₂
inst✝³ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f f' : MultilinearMap R M₁ M₂
inst✝ : Fintype ι
⊢ MultilinearMap.mkPiRing R ι 0 = 0

Next tactic:
ext
theorem mkPiRing_zero [Fintype ι] : MultilinearMap.mkPiRing R ι (0 : M₂) = 0 := by
  ext; 

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 : ι) → AddCommMonoid (M₁ i)
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M₂
inst✝³ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f f' : MultilinearMap R M₁ M₂
inst✝ : Fintype ι
x✝ : ι → R
⊢ (MultilinearMap.mkPiRing R ι 0) x✝ = 0 x✝

Next tactic:
rw [mkPiRing_apply, smul_zero, MultilinearMap.zero_apply]
theorem mkPiRing_eq_zero_iff [Fintype ι] (z : M₂) : MultilinearMap.mkPiRing R ι z = 0 ↔ z = 0 := 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 : ι) → AddCommMonoid (M₁ i)
inst✝⁵ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁴ : AddCommMonoid M₂
inst✝³ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f f' : MultilinearMap R M₁ M₂
inst✝ : Fintype ι
z : M₂
⊢ MultilinearMap.mkPiRing R ι z = 0 ↔ z = 0

Next tactic:
rw [← mkPiRing_zero, mkPiRing_eq_iff]
instance : Neg (MultilinearMap R M₁ M₂) :=
  ⟨fun f => ⟨fun m => -f m, fun 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x y : M₁ i
⊢ (fun m => -f m) (update m i (x + y)) = (fun m => -f m) (update m i x) + (fun m => -f m) (update m i y)

Next tactic:
simp [add_comm]
instance : Neg (MultilinearMap R M₁ M₂) :=
  ⟨fun f => ⟨fun m => -f m, fun m i x y => by simp [add_comm], fun 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
c : R
x : M₁ i
⊢ (fun m => -f m) (update m i (c • x)) = c • (fun m => -f m) (update m i x)

Next tactic:
simp
instance : Sub (MultilinearMap R M₁ M₂) :=
  ⟨fun f g =>
    ⟨fun m => f m - g m, fun 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g✝ f g : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x y : M₁ i
⊢ (fun m => f m - g m) (update m i (x + y)) = (fun m => f m - g m) (update m i x) + (fun m => f m - g m) (update m i y)

Next tactic:
simp only [MultilinearMap.map_add, sub_eq_add_neg, neg_add]
instance : Sub (MultilinearMap R M₁ M₂) :=
  ⟨fun f g =>
    ⟨fun m => f m - g m, fun m i x y => by
      simp only [MultilinearMap.map_add, sub_eq_add_neg, neg_add]
      -- Porting note: used to be `cc`
      

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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g✝ f g : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x y : M₁ i
⊢ f (update m i x) + f (update m i y) + (-g (update m i x) + -g (update m i y)) =
    f (update m i x) + -g (update m i x) + (f (update m i y) + -g (update m i y))

Next tactic:
abel
instance : Sub (MultilinearMap R M₁ M₂) :=
  ⟨fun f g =>
    ⟨fun m => f m - g m, fun m i x y => by
      simp only [MultilinearMap.map_add, sub_eq_add_neg, neg_add]
      -- Porting note: used to be `cc`
      abel,
      fun 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g✝ f g : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
c : R
x : M₁ i
⊢ (fun m => f m - g m) (update m i (c • x)) = c • (fun m => f m - g m) (update m i x)

Next tactic:
simp only [MultilinearMap.map_smul, smul_sub]
instance : AddCommGroup (MultilinearMap R M₁ M₂) :=
  { MultilinearMap.addCommMonoid with
    add_left_neg := fun a => MultilinearMap.ext fun v => add_left_neg _
    sub_eq_add_neg := fun a b => MultilinearMap.ext fun v => sub_eq_add_neg _ _
    zsmul := fun n f =>
      { toFun := fun m => n • f m
        map_add' := fun 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g : MultilinearMap R M₁ M₂
src✝ : AddCommMonoid (MultilinearMap R M₁ M₂) := addCommMonoid
n : ℤ
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x y : M₁ i
⊢ (fun m => n • f m) (update m i (x + y)) = (fun m => n • f m) (update m i x) + (fun m => n • f m) (update m i y)

Next tactic:
simp [smul_add]
instance : AddCommGroup (MultilinearMap R M₁ M₂) :=
  { MultilinearMap.addCommMonoid with
    add_left_neg := fun a => MultilinearMap.ext fun v => add_left_neg _
    sub_eq_add_neg := fun a b => MultilinearMap.ext fun v => sub_eq_add_neg _ _
    zsmul := fun n f =>
      { toFun := fun m => n • f m
        map_add' := fun m i x y => by simp [smul_add]
        map_smul' := fun l i x d => 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f✝ g : MultilinearMap R M₁ M₂
src✝ : AddCommMonoid (MultilinearMap R M₁ M₂) := addCommMonoid
n : ℤ
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
l : (i : ι) → M₁ i
i : ι
x : R
d : M₁ i
⊢ (fun m => n • f m) (update l i (x • d)) = x • (fun m => n • f m) (update l i d)

Next tactic:
simp [← smul_comm x n (_ : M₂)]
@[simp]
theorem map_neg [DecidableEq ι] (m : ∀ i, M₁ i) (i : ι) (x : M₁ i) :
    f (update m i (-x)) = -f (update m i x) :=
  eq_neg_of_add_eq_zero_left <| 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommGroup (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x : M₁ i
⊢ f (update m i (-x)) + f (update m i x) = 0

Next tactic:
rw [← MultilinearMap.map_add, add_left_neg, f.map_coord_zero i (update_same i 0 m)]
@[simp]
theorem map_sub [DecidableEq ι] (m : ∀ i, M₁ i) (i : ι) (x y : M₁ i) :
    f (update m i (x - y)) = f (update m i x) - f (update m i 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✝⁵ : Semiring R
inst✝⁴ : (i : ι) → AddCommGroup (M₁ i)
inst✝³ : AddCommGroup M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x y : M₁ i
⊢ f (update m i (x - y)) = f (update m i x) - f (update m i y)

Next tactic:
rw [sub_eq_add_neg, sub_eq_add_neg, MultilinearMap.map_add, map_neg]
/-- When `ι` is finite, multilinear maps on `R^ι` with values in `M₂` are in bijection with `M₂`,
as such a multilinear map is completely determined by its value on the constant vector made of ones.
We register this bijection as a linear equivalence in `MultilinearMap.piRingEquiv`. -/
protected def piRingEquiv [Fintype ι] : M₂ ≃ₗ[R] MultilinearMap R (fun _ : ι => R) M₂ where
  toFun z := MultilinearMap.mkPiRing R ι z
  invFun f := f fun _ => 1
  map_add' z z' := 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 : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommMonoid M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
inst✝ : Fintype ι
z z' : M₂
⊢ (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
    (fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z'

Next tactic:
ext m
/-- When `ι` is finite, multilinear maps on `R^ι` with values in `M₂` are in bijection with `M₂`,
as such a multilinear map is completely determined by its value on the constant vector made of ones.
We register this bijection as a linear equivalence in `MultilinearMap.piRingEquiv`. -/
protected def piRingEquiv [Fintype ι] : M₂ ≃ₗ[R] MultilinearMap R (fun _ : ι => R) M₂ where
  toFun z := MultilinearMap.mkPiRing R ι z
  invFun f := f fun _ => 1
  map_add' z z' := 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 : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommMonoid M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
inst✝ : Fintype ι
z z' : M₂
m : ι → R
⊢ ((fun z => MultilinearMap.mkPiRing R ι z) (z + z')) m =
    ((fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z') m

Next tactic:
simp [smul_add]
/-- When `ι` is finite, multilinear maps on `R^ι` with values in `M₂` are in bijection with `M₂`,
as such a multilinear map is completely determined by its value on the constant vector made of ones.
We register this bijection as a linear equivalence in `MultilinearMap.piRingEquiv`. -/
protected def piRingEquiv [Fintype ι] : M₂ ≃ₗ[R] MultilinearMap R (fun _ : ι => R) M₂ where
  toFun z := MultilinearMap.mkPiRing R ι z
  invFun f := f fun _ => 1
  map_add' z z' := by
    ext m
    simp [smul_add]
  map_smul' c z := 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 : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommMonoid M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
inst✝ : Fintype ι
c : R
z : M₂
⊢ AddHom.toFun
      { toFun := fun z => MultilinearMap.mkPiRing R ι z,
        map_add' :=
          (_ :
            ∀ (z z' : M₂),
              (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                (fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z') }
      (c • z) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := fun z => MultilinearMap.mkPiRing R ι z,
          map_add' :=
            (_ :
              ∀ (z z' : M₂),
                (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                  (fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z') }
        z

Next tactic:
ext m
/-- When `ι` is finite, multilinear maps on `R^ι` with values in `M₂` are in bijection with `M₂`,
as such a multilinear map is completely determined by its value on the constant vector made of ones.
We register this bijection as a linear equivalence in `MultilinearMap.piRingEquiv`. -/
protected def piRingEquiv [Fintype ι] : M₂ ≃ₗ[R] MultilinearMap R (fun _ : ι => R) M₂ where
  toFun z := MultilinearMap.mkPiRing R ι z
  invFun f := f fun _ => 1
  map_add' z z' := by
    ext m
    simp [smul_add]
  map_smul' c z := 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 : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommMonoid M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
inst✝ : Fintype ι
c : R
z : M₂
m : ι → R
⊢ (AddHom.toFun
        { toFun := fun z => MultilinearMap.mkPiRing R ι z,
          map_add' :=
            (_ :
              ∀ (z z' : M₂),
                (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                  (fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z') }
        (c • z))
      m =
    ((RingHom.id R) c •
        AddHom.toFun
          { toFun := fun z => MultilinearMap.mkPiRing R ι z,
            map_add' :=
              (_ :
                ∀ (z z' : M₂),
                  (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                    (fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z') }
          z)
      m

Next tactic:
simp [smul_smul, mul_comm]
/-- When `ι` is finite, multilinear maps on `R^ι` with values in `M₂` are in bijection with `M₂`,
as such a multilinear map is completely determined by its value on the constant vector made of ones.
We register this bijection as a linear equivalence in `MultilinearMap.piRingEquiv`. -/
protected def piRingEquiv [Fintype ι] : M₂ ≃ₗ[R] MultilinearMap R (fun _ : ι => R) M₂ where
  toFun z := MultilinearMap.mkPiRing R ι z
  invFun f := f fun _ => 1
  map_add' z z' := by
    ext m
    simp [smul_add]
  map_smul' c z := by
    ext m
    simp [smul_smul, mul_comm]
  left_inv z := 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 : ι) → AddCommMonoid (M₁ i)
inst✝³ : AddCommMonoid M₂
inst✝² : (i : ι) → Module R (M₁ i)
inst✝¹ : Module R M₂
inst✝ : Fintype ι
z : M₂
⊢ (fun f => f fun x => 1)
      (AddHom.toFun
        {
            toAddHom :=
              { toFun := fun z => MultilinearMap.mkPiRing R ι z,
                map_add' :=
                  (_ :
                    ∀ (z z' : M₂),
                      (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                        (fun z => MultilinearMap.mkPiRing R ι z) z + (fun z => MultilinearMap.mkPiRing R ι z) z') },
            map_smul' :=
              (_ :
                ∀ (c : R) (z : M₂),
                  AddHom.toFun
                      { toFun := fun z => MultilinearMap.mkPiRing R ι z,
                        map_add' :=
                          (_ :
                            ∀ (z z' : M₂),
                              (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                                (fun z => MultilinearMap.mkPiRing R ι z) z +
                                  (fun z => MultilinearMap.mkPiRing R ι z) z') }
                      (c • z) =
                    (RingHom.id R) c •
                      AddHom.toFun
                        { toFun := fun z => MultilinearMap.mkPiRing R ι z,
                          map_add' :=
                            (_ :
                              ∀ (z z' : M₂),
                                (fun z => MultilinearMap.mkPiRing R ι z) (z + z') =
                                  (fun z => MultilinearMap.mkPiRing R ι z) z +
                                    (fun z => MultilinearMap.mkPiRing R ι z) z') }
                        z) }.toAddHom
        z) =
    z

Next tactic:
simp
/-- Given a linear map `f` from `M 0` to multilinear maps on `n` variables,
construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (m 0) (tail m)`-/
def LinearMap.uncurryLeft (f : M 0 →ₗ[R] MultilinearMap R (fun i : Fin n => M i.succ) M₂) :
    MultilinearMap R M M₂ where
  toFun m := f (m 0) (tail m)
  map_add' := @fun dec m i x y => by
    -- porting note: `clear` not necessary in Lean 3 due to not being in the instance cache
    

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 : M 0 →ₗ[R] MultilinearMap R (fun i => M (succ i)) M₂
dec : DecidableEq (Fin (Nat.succ n))
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
x y : M i
⊢ (fun m => (f (m 0)) (tail m)) (update m i (x + y)) =
    (fun m => (f (m 0)) (tail m)) (update m i x) + (fun m => (f (m 0)) (tail m)) (update m i y)

Next tactic:
rw [Subsingleton.elim dec (by clear dec; infer_instance)]
/-- Given a linear map `f` from `M 0` to multilinear maps on `n` variables,
construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (m 0) (tail m)`-/
def LinearMap.uncurryLeft (f : M 0 →ₗ[R] MultilinearMap R (fun i : Fin n => M i.succ) M₂) :
    MultilinearMap R M M₂ where
  toFun m := f (m 0) (tail m)
  map_add' := @fun 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 

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 : M 0 →ₗ[R] MultilinearMap R (fun i => M (succ i)) M₂
dec : DecidableEq (Fin (Nat.succ n))
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
x y : M i
⊢ DecidableEq (Fin (Nat.succ n))

Next tactic:
clear dec
/-- Given a linear map `f` from `M 0` to multilinear maps on `n` variables,
construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (m 0) (tail m)`-/
def LinearMap.uncurryLeft (f : M 0 →ₗ[R] MultilinearMap R (fun i : Fin n => M i.succ) M₂) :
    MultilinearMap R M M₂ where
  toFun m := f (m 0) (tail m)
  map_add' := @fun 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; 

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 : M 0 →ₗ[R] MultilinearMap R (fun i => M (succ i)) M₂
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
x y : M i
⊢ DecidableEq (Fin (Nat.succ n))

Next tactic:
infer_instance
/-- Given a linear map `f` from `M 0` to multilinear maps on `n` variables,
construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (m 0) (tail m)`-/
def LinearMap.uncurryLeft (f : M 0 →ₗ[R] MultilinearMap R (fun i : Fin n => M i.succ) M₂) :
    MultilinearMap R M M₂ where
  toFun m := f (m 0) (tail m)
  map_add' := @fun 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)]; 

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 : M 0 →ₗ[R] MultilinearMap R (fun i => M (succ i)) M₂
dec : DecidableEq (Fin (Nat.succ n))
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
x y : M i
⊢ (fun m => (f (m 0)) (tail m)) (update m i (x + y)) =
    (fun m => (f (m 0)) (tail m)) (update m i x) + (fun m => (f (m 0)) (tail m)) (update m i y)

Next tactic:
clear dec
/-- Given a linear map `f` from `M 0` to multilinear maps on `n` variables,
construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (m 0) (tail m)`-/
def LinearMap.uncurryLeft (f : M 0 →ₗ[R] MultilinearMap R (fun i : Fin n => M i.succ) M₂) :
    MultilinearMap R M M₂ where
  toFun m := f (m 0) (tail m)
  map_add' := @fun 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
    

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 : M 0 →ₗ[R] MultilinearMap R (fun i => M (succ i)) M₂
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
x y : M i
⊢ (fun m => (f (m 0)) (tail m)) (update m i (x + y)) =
    (fun m => (f (m 0)) (tail m)) (update m i x) + (fun m => (f (m 0)) (tail m)) (update m i y)

Next tactic:
by_cases h : i = 0
/-- Given a linear map `f` from `M 0` to multilinear maps on `n` variables,
construct the corresponding multilinear map on `n+1` variables obtained by concatenating
the variables, given by `m ↦ f (m 0) (tail m)`-/
def LinearMap.uncurryLeft (f : M 0 →ₗ[R] MultilinearMap R (fun i : Fin n => M i.succ) M₂) :
    MultilinearMap R M M₂ where
  toFun m := f (m 0) (tail m)
  map_add' := @fun 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 = 0
    · 

Proof state:
case pos
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 : M 0 →ₗ[R] MultilinearMap R (fun i => M (succ i)) M₂
m : (i : Fin (Nat.succ n)) → M i
i : Fin (Nat.succ n)
x y : M i
h : i = 0
⊢ (fun m => (f (m 0)) (tail m)) (update m i (x + y)) =
    (fun m => (f (m 0)) (tail m)) (update m i x) + (fun m => (f (m 0)) (tail m)) (update m i y)

Next tactic:
subst i