l3lab/ntp-mathlib huggingface dataset:
theorem map_update_sum {α : Type*} [DecidableEq ι] (t : Finset α) (i : ι) (g : α → M₁ i)
    (m : ∀ i, M₁ i) : f (update m i (∑ a in t, g a)) = ∑ a in t, f (update m i (g a)) := by
  classical
    induction' t using Finset.induction with a t has ih h
    · simp
    · 

Proof state:
case insert
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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
α✝ : ι → Type u_1
g✝ : (i : ι) → α✝ i → M₁ i
A : (i : ι) → Finset (α✝ i)
α : Type u_2
inst✝ : DecidableEq ι
i : ι
g : α → M₁ i
m : (i : ι) → M₁ i
a : α
t : Finset α
has : a ∉ t
ih : f (update m i (∑ a in t, g a)) = ∑ a in t, f (update m i (g a))
⊢ f (update m i (∑ a in insert a t, g a)) = ∑ a in insert a t, f (update m i (g a))

Next tactic:
simp [Finset.sum_insert has, ih]
/-- Transfer the arguments to a map along an equivalence between argument indices.

The naming is derived from `Finsupp.domCongr`, noting that here the permutation applies to the
domain of the domain. -/
@[simps apply]
def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M₂) M₃) :
    MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun v := m fun i => v (σ i)
  map_add' v i a b := 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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
inst✝ : DecidableEq ι₂
v : ι₂ → M₂
i : ι₂
a b : M₂
⊢ (fun v => m fun i => v (σ i)) (update v i (a + b)) =
    (fun v => m fun i => v (σ i)) (update v i a) + (fun v => m fun i => v (σ i)) (update v i b)

Next tactic:
letI := σ.injective.decidableEq
/-- Transfer the arguments to a map along an equivalence between argument indices.

The naming is derived from `Finsupp.domCongr`, noting that here the permutation applies to the
domain of the domain. -/
@[simps apply]
def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M₂) M₃) :
    MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun v := m fun i => v (σ i)
  map_add' v i a b := by
    letI := σ.injective.decidableEq
    

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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
inst✝ : DecidableEq ι₂
v : ι₂ → M₂
i : ι₂
a b : M₂
this : DecidableEq ι₁ := Injective.decidableEq (_ : Injective ⇑σ)
⊢ (fun v => m fun i => v (σ i)) (update v i (a + b)) =
    (fun v => m fun i => v (σ i)) (update v i a) + (fun v => m fun i => v (σ i)) (update v i b)

Next tactic:
simp_rw [Function.update_apply_equiv_apply v]
/-- Transfer the arguments to a map along an equivalence between argument indices.

The naming is derived from `Finsupp.domCongr`, noting that here the permutation applies to the
domain of the domain. -/
@[simps apply]
def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M₂) M₃) :
    MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun v := m fun i => v (σ i)
  map_add' v i a b := by
    letI := σ.injective.decidableEq
    simp_rw [Function.update_apply_equiv_apply v]
    

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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
inst✝ : DecidableEq ι₂
v : ι₂ → M₂
i : ι₂
a b : M₂
this : DecidableEq ι₁ := Injective.decidableEq (_ : Injective ⇑σ)
⊢ (m fun i_1 => update (v ∘ ⇑σ) (σ.symm i) (a + b) i_1) =
    (m fun i_1 => update (v ∘ ⇑σ) (σ.symm i) a i_1) + m fun i_1 => update (v ∘ ⇑σ) (σ.symm i) b i_1

Next tactic:
rw [m.map_add]
/-- Transfer the arguments to a map along an equivalence between argument indices.

The naming is derived from `Finsupp.domCongr`, noting that here the permutation applies to the
domain of the domain. -/
@[simps apply]
def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M₂) M₃) :
    MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun v := m fun i => v (σ i)
  map_add' v i a b := by
    letI := σ.injective.decidableEq
    simp_rw [Function.update_apply_equiv_apply v]
    rw [m.map_add]
  map_smul' v i a b := 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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
inst✝ : DecidableEq ι₂
v : ι₂ → M₂
i : ι₂
a : R
b : M₂
⊢ (fun v => m fun i => v (σ i)) (update v i (a • b)) = a • (fun v => m fun i => v (σ i)) (update v i b)

Next tactic:
letI := σ.injective.decidableEq
/-- Transfer the arguments to a map along an equivalence between argument indices.

The naming is derived from `Finsupp.domCongr`, noting that here the permutation applies to the
domain of the domain. -/
@[simps apply]
def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M₂) M₃) :
    MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun v := m fun i => v (σ i)
  map_add' v i a b := by
    letI := σ.injective.decidableEq
    simp_rw [Function.update_apply_equiv_apply v]
    rw [m.map_add]
  map_smul' v i a b := by
    letI := σ.injective.decidableEq
    

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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
inst✝ : DecidableEq ι₂
v : ι₂ → M₂
i : ι₂
a : R
b : M₂
this : DecidableEq ι₁ := Injective.decidableEq (_ : Injective ⇑σ)
⊢ (fun v => m fun i => v (σ i)) (update v i (a • b)) = a • (fun v => m fun i => v (σ i)) (update v i b)

Next tactic:
simp_rw [Function.update_apply_equiv_apply v]
/-- Transfer the arguments to a map along an equivalence between argument indices.

The naming is derived from `Finsupp.domCongr`, noting that here the permutation applies to the
domain of the domain. -/
@[simps apply]
def domDomCongr (σ : ι₁ ≃ ι₂) (m : MultilinearMap R (fun _ : ι₁ => M₂) M₃) :
    MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun v := m fun i => v (σ i)
  map_add' v i a b := by
    letI := σ.injective.decidableEq
    simp_rw [Function.update_apply_equiv_apply v]
    rw [m.map_add]
  map_smul' v i a b := by
    letI := σ.injective.decidableEq
    simp_rw [Function.update_apply_equiv_apply v]
    

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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁸ : AddCommMonoid M₂
inst✝⁷ : AddCommMonoid M₃
inst✝⁶ : AddCommMonoid M'
inst✝⁵ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
inst✝ : DecidableEq ι₂
v : ι₂ → M₂
i : ι₂
a : R
b : M₂
this : DecidableEq ι₁ := Injective.decidableEq (_ : Injective ⇑σ)
⊢ (m fun i_1 => update (v ∘ ⇑σ) (σ.symm i) (a • b) i_1) = a • m fun i_1 => update (v ∘ ⇑σ) (σ.symm i) b i_1

Next tactic:
rw [m.map_smul]
/-- `MultilinearMap.domDomCongr` as an equivalence.

This is declared separately because it does not work with dot notation. -/
@[simps apply symm_apply]
def domDomCongrEquiv (σ : ι₁ ≃ ι₂) :
    MultilinearMap R (fun _ : ι₁ => M₂) M₃ ≃+ MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun := domDomCongr σ
  invFun := domDomCongr σ.symm
  left_inv m := 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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
⊢ domDomCongr σ.symm (domDomCongr σ m) = m

Next tactic:
ext
/-- `MultilinearMap.domDomCongr` as an equivalence.

This is declared separately because it does not work with dot notation. -/
@[simps apply symm_apply]
def domDomCongrEquiv (σ : ι₁ ≃ ι₂) :
    MultilinearMap R (fun _ : ι₁ => M₂) M₃ ≃+ MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun := domDomCongr σ
  invFun := domDomCongr σ.symm
  left_inv m := 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✝¹⁰ : Semiring R
inst✝⁹ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
x✝ : ι₁ → M₂
⊢ (domDomCongr σ.symm (domDomCongr σ m)) x✝ = m x✝

Next tactic:
simp [domDomCongr]
/-- `MultilinearMap.domDomCongr` as an equivalence.

This is declared separately because it does not work with dot notation. -/
@[simps apply symm_apply]
def domDomCongrEquiv (σ : ι₁ ≃ ι₂) :
    MultilinearMap R (fun _ : ι₁ => M₂) M₃ ≃+ MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun := domDomCongr σ
  invFun := domDomCongr σ.symm
  left_inv m := by
    ext
    simp [domDomCongr]
  right_inv m := 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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
⊢ domDomCongr σ (domDomCongr σ.symm m) = m

Next tactic:
ext
/-- `MultilinearMap.domDomCongr` as an equivalence.

This is declared separately because it does not work with dot notation. -/
@[simps apply symm_apply]
def domDomCongrEquiv (σ : ι₁ ≃ ι₂) :
    MultilinearMap R (fun _ : ι₁ => M₂) M₃ ≃+ MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun := domDomCongr σ
  invFun := domDomCongr σ.symm
  left_inv m := by
    ext
    simp [domDomCongr]
  right_inv m := 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✝¹⁰ : Semiring R
inst✝⁹ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
m : MultilinearMap R (fun x => M₂) M₃
x✝ : ι₂ → M₂
⊢ (domDomCongr σ (domDomCongr σ.symm m)) x✝ = m x✝

Next tactic:
simp [domDomCongr]
/-- `MultilinearMap.domDomCongr` as an equivalence.

This is declared separately because it does not work with dot notation. -/
@[simps apply symm_apply]
def domDomCongrEquiv (σ : ι₁ ≃ ι₂) :
    MultilinearMap R (fun _ : ι₁ => M₂) M₃ ≃+ MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun := domDomCongr σ
  invFun := domDomCongr σ.symm
  left_inv m := by
    ext
    simp [domDomCongr]
  right_inv m := by
    ext
    simp [domDomCongr]
  map_add' a b := 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 : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
a b : MultilinearMap R (fun x => M₂) M₃
⊢ Equiv.toFun
      { toFun := domDomCongr σ, invFun := domDomCongr σ.symm,
        left_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ.symm (domDomCongr σ m) = m),
        right_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ (domDomCongr σ.symm m) = m) }
      (a + b) =
    Equiv.toFun
        { toFun := domDomCongr σ, invFun := domDomCongr σ.symm,
          left_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ.symm (domDomCongr σ m) = m),
          right_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ (domDomCongr σ.symm m) = m) }
        a +
      Equiv.toFun
        { toFun := domDomCongr σ, invFun := domDomCongr σ.symm,
          left_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ.symm (domDomCongr σ m) = m),
          right_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ (domDomCongr σ.symm m) = m) }
        b

Next tactic:
ext
/-- `MultilinearMap.domDomCongr` as an equivalence.

This is declared separately because it does not work with dot notation. -/
@[simps apply symm_apply]
def domDomCongrEquiv (σ : ι₁ ≃ ι₂) :
    MultilinearMap R (fun _ : ι₁ => M₂) M₃ ≃+ MultilinearMap R (fun _ : ι₂ => M₂) M₃ where
  toFun := domDomCongr σ
  invFun := domDomCongr σ.symm
  left_inv m := by
    ext
    simp [domDomCongr]
  right_inv m := by
    ext
    simp [domDomCongr]
  map_add' a b := 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✝¹⁰ : Semiring R
inst✝⁹ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
f f' : MultilinearMap R M₁ M₂
ι₁ : Type u_1
ι₂ : Type u_2
ι₃ : Type u_3
σ : ι₁ ≃ ι₂
a b : MultilinearMap R (fun x => M₂) M₃
x✝ : ι₂ → M₂
⊢ (Equiv.toFun
        { toFun := domDomCongr σ, invFun := domDomCongr σ.symm,
          left_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ.symm (domDomCongr σ m) = m),
          right_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ (domDomCongr σ.symm m) = m) }
        (a + b))
      x✝ =
    (Equiv.toFun
          { toFun := domDomCongr σ, invFun := domDomCongr σ.symm,
            left_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ.symm (domDomCongr σ m) = m),
            right_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ (domDomCongr σ.symm m) = m) }
          a +
        Equiv.toFun
          { toFun := domDomCongr σ, invFun := domDomCongr σ.symm,
            left_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ.symm (domDomCongr σ m) = m),
            right_inv := (_ : ∀ (m : MultilinearMap R (fun x => M₂) M₃), domDomCongr σ (domDomCongr σ.symm m) = m) }
          b)
      x✝

Next tactic:
simp [domDomCongr]
/-- Composing a multilinear map with a linear map gives again a multilinear map. -/
def compMultilinearMap (g : M₂ →ₗ[R] M₃) (f : MultilinearMap R M₁ M₂) : MultilinearMap R M₁ M₃ where
  toFun := g ∘ f
  map_add' 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✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
g : M₂ →ₗ[R] M₃
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
x y : M₁ i
⊢ (⇑g ∘ ⇑f) (update m i (x + y)) = (⇑g ∘ ⇑f) (update m i x) + (⇑g ∘ ⇑f) (update m i y)

Next tactic:
simp
/-- Composing a multilinear map with a linear map gives again a multilinear map. -/
def compMultilinearMap (g : M₂ →ₗ[R] M₃) (f : MultilinearMap R M₁ M₂) : MultilinearMap R M₁ M₃ where
  toFun := g ∘ f
  map_add' m i x y := by simp
  map_smul' 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✝⁷ : AddCommMonoid M₂
inst✝⁶ : AddCommMonoid M₃
inst✝⁵ : AddCommMonoid M'
inst✝⁴ : (i : ι) → Module R (M₁ i)
inst✝³ : Module R M₂
inst✝² : Module R M₃
inst✝¹ : Module R M'
g : M₂ →ₗ[R] M₃
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι
m : (i : ι) → M₁ i
i : ι
c : R
x : M₁ i
⊢ (⇑g ∘ ⇑f) (update m i (c • x)) = c • (⇑g ∘ ⇑f) (update m i x)

Next tactic:
simp
@[simp]
theorem compMultilinearMap_domDomCongr (σ : ι₁ ≃ ι₂) (g : M₂ →ₗ[R] M₃)
    (f : MultilinearMap R (fun _ : ι₁ => M') M₂) :
    (g.compMultilinearMap f).domDomCongr σ = g.compMultilinearMap (f.domDomCongr σ) := 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✝⁶ : AddCommMonoid M₂
inst✝⁵ : AddCommMonoid M₃
inst✝⁴ : AddCommMonoid M'
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
ι₁ : Type u_1
ι₂ : Type u_2
σ : ι₁ ≃ ι₂
g : M₂ →ₗ[R] M₃
f : MultilinearMap R (fun x => M') M₂
⊢ MultilinearMap.domDomCongr σ (compMultilinearMap g f) = compMultilinearMap g (MultilinearMap.domDomCongr σ f)

Next tactic:
ext
@[simp]
theorem compMultilinearMap_domDomCongr (σ : ι₁ ≃ ι₂) (g : M₂ →ₗ[R] M₃)
    (f : MultilinearMap R (fun _ : ι₁ => M') M₂) :
    (g.compMultilinearMap f).domDomCongr σ = g.compMultilinearMap (f.domDomCongr σ) := 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✝⁸ : Semiring R
inst✝⁷ : (i : ι) → AddCommMonoid (M₁ i)
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : AddCommMonoid M₃
inst✝⁴ : AddCommMonoid M'
inst✝³ : (i : ι) → Module R (M₁ i)
inst✝² : Module R M₂
inst✝¹ : Module R M₃
inst✝ : Module R M'
ι₁ : Type u_1
ι₂ : Type u_2
σ : ι₁ ≃ ι₂
g : M₂ →ₗ[R] M₃
f : MultilinearMap R (fun x => M') M₂
x✝ : ι₂ → M'
⊢ (MultilinearMap.domDomCongr σ (compMultilinearMap g f)) x✝ =
    (compMultilinearMap g (MultilinearMap.domDomCongr σ f)) x✝

Next tactic:
simp [MultilinearMap.domDomCongr]
/-- The dependent version of `MultilinearMap.domDomCongrLinearEquiv`. -/
@[simps apply symm_apply]
def domDomCongrLinearEquiv' {ι' : Type*} (σ : ι ≃ ι') :
    MultilinearMap R M₁ M₂ ≃ₗ[S] MultilinearMap R (fun i => M₁ (σ.symm i)) M₂ where
  toFun f :=
    { toFun := f ∘ (σ.piCongrLeft' M₁).symm
      map_add' := fun m i => 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✝⁷ : (i : ι) → Module R (M₁ i)
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : Module R M₂
inst✝⁴ : Semiring S
inst✝³ : Module S M₂
inst✝² : Module R M₂
inst✝¹ : SMulCommClass R S M₂
ι' : Type u_1
σ : ι ≃ ι'
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι'
m : (i : ι') → M₁ (σ.symm i)
i : ι'
⊢ ∀ (x y : M₁ (σ.symm i)),
    (⇑f ∘ ⇑(Equiv.piCongrLeft' M₁ σ).symm) (update m i (x + y)) =
      (⇑f ∘ ⇑(Equiv.piCongrLeft' M₁ σ).symm) (update m i x) + (⇑f ∘ ⇑(Equiv.piCongrLeft' M₁ σ).symm) (update m i y)

Next tactic:
letI := σ.decidableEq
/-- The dependent version of `MultilinearMap.domDomCongrLinearEquiv`. -/
@[simps apply symm_apply]
def domDomCongrLinearEquiv' {ι' : Type*} (σ : ι ≃ ι') :
    MultilinearMap R M₁ M₂ ≃ₗ[S] MultilinearMap R (fun i => M₁ (σ.symm i)) M₂ where
  toFun f :=
    { toFun := f ∘ (σ.piCongrLeft' M₁).symm
      map_add' := fun m i => by
        letI := σ.decidableEq
        

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✝⁷ : (i : ι) → Module R (M₁ i)
inst✝⁶ : AddCommMonoid M₂
inst✝⁵ : Module R M₂
inst✝⁴ : Semiring S
inst✝³ : Module S M₂
inst✝² : Module R M₂
inst✝¹ : SMulCommClass R S M₂
ι' : Type u_1
σ : ι ≃ ι'
f : MultilinearMap R M₁ M₂
inst✝ : DecidableEq ι'
m : (i : ι') → M₁ (σ.symm i)
i : ι'
this : DecidableEq ι := Equiv.decidableEq σ
⊢ ∀ (x y : M₁ (σ.symm i)),
    (⇑f ∘ ⇑(Equiv.piCongrLeft' M₁ σ).symm) (update m i (x + y)) =
      (⇑f ∘ ⇑(Equiv.piCongrLeft' M₁ σ).symm) (update m i x) + (⇑f ∘ ⇑(Equiv.piCongrLeft' M₁ σ).symm) (update m i y)

Next tactic:
rw [← σ.apply_symm_apply i]