l3lab/ntp-mathlib huggingface dataset:
/-- As a matrix, `dualTensorHom` evaluated on a basis element of `M* ⊗ N` is a matrix with a
single one and zeros elsewhere -/
theorem toMatrix_dualTensorHom {m : Type*} {n : Type*} [Fintype m] [Fintype n] [DecidableEq m]
    [DecidableEq n] (bM : Basis m R M) (bN : Basis n R N) (j : m) (i : n) :
    toMatrix bM bN (dualTensorHom R M N (bM.coord j ⊗ₜ bN i)) = stdBasisMatrix i j 1 := by
  ext i' j'
  by_cases hij : i = i' ∧ j = j' <;>
    simp [LinearMap.toMatrix_apply, Finsupp.single_eq_pi_single, hij]
  rw [and_iff_not_or_not, Classical.not_not] at hij
  cases' hij with hij hij <;> 

Proof state:
case neg.inr
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁴ : CommSemiring R
inst✝¹³ : AddCommMonoid M
inst✝¹² : AddCommMonoid N
inst✝¹¹ : AddCommMonoid P
inst✝¹⁰ : AddCommMonoid Q
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : DecidableEq ι
inst✝⁴ : Fintype ι
b : Basis ι R M
m : Type u_1
n : Type u_2
inst✝³ : Fintype m
inst✝² : Fintype n
inst✝¹ : DecidableEq m
inst✝ : DecidableEq n
bM : Basis m R M
bN : Basis n R N
j : m
i i' : n
j' : m
hij : ¬j = j'
⊢ Pi.single i (Pi.single j' 1 j) i' = 0

Next tactic:
simp [hij]
/-- If `M` is free, the natural linear map $M^* ⊗ N → Hom(M, N)$ is an equivalence. This function
provides this equivalence in return for a basis of `M`. -/
-- @[simps! apply] -- Porting note: removed and created manually; malformed
noncomputable def dualTensorHomEquivOfBasis : Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N :=
  LinearEquiv.ofLinear (dualTensorHom R M N)
    (∑ i, TensorProduct.mk R _ N (b.dualBasis i) ∘ₗ (LinearMap.applyₗ (R := R) (b i)))
    (by
      

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
⊢ comp (dualTensorHom R M N) (∑ i : ι, (TensorProduct.mk R (Dual R M) N) ((Basis.dualBasis b) i) ∘ₗ applyₗ (b i)) =
    LinearMap.id

Next tactic:
ext f m
/-- If `M` is free, the natural linear map $M^* ⊗ N → Hom(M, N)$ is an equivalence. This function
provides this equivalence in return for a basis of `M`. -/
-- @[simps! apply] -- Porting note: removed and created manually; malformed
noncomputable def dualTensorHomEquivOfBasis : Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N :=
  LinearEquiv.ofLinear (dualTensorHom R M N)
    (∑ i, TensorProduct.mk R _ N (b.dualBasis i) ∘ₗ (LinearMap.applyₗ (R := R) (b i)))
    (by
      ext f m
      

Proof state:
case h.h
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
f : M →ₗ[R] N
m : M
⊢ ((comp (dualTensorHom R M N) (∑ i : ι, (TensorProduct.mk R (Dual R M) N) ((Basis.dualBasis b) i) ∘ₗ applyₗ (b i))) f)
      m =
    (LinearMap.id f) m

Next tactic:
simp only [applyₗ_apply_apply, coeFn_sum, dualTensorHom_apply, mk_apply, id_coe, id.def,
        Fintype.sum_apply, Function.comp_apply, Basis.coe_dualBasis, coe_comp, Basis.coord_apply, ←
        f.map_smul, _root_.map_sum (dualTensorHom R M N), ← _root_.map_sum f, b.sum_repr]
/-- If `M` is free, the natural linear map $M^* ⊗ N → Hom(M, N)$ is an equivalence. This function
provides this equivalence in return for a basis of `M`. -/
-- @[simps! apply] -- Porting note: removed and created manually; malformed
noncomputable def dualTensorHomEquivOfBasis : Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N :=
  LinearEquiv.ofLinear (dualTensorHom R M N)
    (∑ i, TensorProduct.mk R _ N (b.dualBasis i) ∘ₗ (LinearMap.applyₗ (R := R) (b i)))
    (by
      ext f m
      simp only [applyₗ_apply_apply, coeFn_sum, dualTensorHom_apply, mk_apply, id_coe, id.def,
        Fintype.sum_apply, Function.comp_apply, Basis.coe_dualBasis, coe_comp, Basis.coord_apply, ←
        f.map_smul, _root_.map_sum (dualTensorHom R M N), ← _root_.map_sum f, b.sum_repr])
    (by
      

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
⊢ comp (∑ i : ι, (TensorProduct.mk R (Dual R M) N) ((Basis.dualBasis b) i) ∘ₗ applyₗ (b i)) (dualTensorHom R M N) =
    LinearMap.id

Next tactic:
ext f m
/-- If `M` is free, the natural linear map $M^* ⊗ N → Hom(M, N)$ is an equivalence. This function
provides this equivalence in return for a basis of `M`. -/
-- @[simps! apply] -- Porting note: removed and created manually; malformed
noncomputable def dualTensorHomEquivOfBasis : Module.Dual R M ⊗[R] N ≃ₗ[R] M →ₗ[R] N :=
  LinearEquiv.ofLinear (dualTensorHom R M N)
    (∑ i, TensorProduct.mk R _ N (b.dualBasis i) ∘ₗ (LinearMap.applyₗ (R := R) (b i)))
    (by
      ext f m
      simp only [applyₗ_apply_apply, coeFn_sum, dualTensorHom_apply, mk_apply, id_coe, id.def,
        Fintype.sum_apply, Function.comp_apply, Basis.coe_dualBasis, coe_comp, Basis.coord_apply, ←
        f.map_smul, _root_.map_sum (dualTensorHom R M N), ← _root_.map_sum f, b.sum_repr])
    (by
      ext f m
      

Proof state:
case H.h.h
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
f : Dual R M
m : N
⊢ ((compr₂ (TensorProduct.mk R (Dual R M) N)
          (comp (∑ i : ι, (TensorProduct.mk R (Dual R M) N) ((Basis.dualBasis b) i) ∘ₗ applyₗ (b i))
            (dualTensorHom R M N)))
        f)
      m =
    ((compr₂ (TensorProduct.mk R (Dual R M) N) LinearMap.id) f) m

Next tactic:
simp only [applyₗ_apply_apply, coeFn_sum, dualTensorHom_apply, mk_apply, id_coe, id.def,
        Fintype.sum_apply, Function.comp_apply, Basis.coe_dualBasis, coe_comp, compr₂_apply,
        tmul_smul, smul_tmul', ← sum_tmul, Basis.sum_dual_apply_smul_coord]
@[simp]
theorem dualTensorHomEquivOfBasis_apply (x : Module.Dual R M ⊗[R] N) :
    (dualTensorHomEquivOfBasis (N := N) b :
    Module.Dual R M ⊗[R] N → (M →ₗ[R] N)) x = (dualTensorHom R M N) x := by
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
x : Dual R M ⊗[R] N
⊢ (dualTensorHomEquivOfBasis b) x = (dualTensorHom R M N) x

Next tactic:
ext
@[simp]
theorem dualTensorHomEquivOfBasis_apply (x : Module.Dual R M ⊗[R] N) :
    (dualTensorHomEquivOfBasis (N := N) b :
    Module.Dual R M ⊗[R] N → (M →ₗ[R] N)) x = (dualTensorHom R M N) x := by
  ext; 

Proof state:
case h
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
x : Dual R M ⊗[R] N
x✝ : M
⊢ ((dualTensorHomEquivOfBasis b) x) x✝ = ((dualTensorHom R M N) x) x✝

Next tactic:
rfl
@[simp]
theorem dualTensorHomEquivOfBasis_symm_cancel_left (x : Module.Dual R M ⊗[R] N) :
    (dualTensorHomEquivOfBasis (N := N) b).symm (dualTensorHom R M N x) = x := by
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
x : Dual R M ⊗[R] N
⊢ (LinearEquiv.symm (dualTensorHomEquivOfBasis b)) ((dualTensorHom R M N) x) = x

Next tactic:
rw [← dualTensorHomEquivOfBasis_apply b,
    LinearEquiv.symm_apply_apply <| dualTensorHomEquivOfBasis (N := N) b]
@[simp]
theorem dualTensorHomEquivOfBasis_symm_cancel_right (x : M →ₗ[R] N) :
    dualTensorHom R M N ((dualTensorHomEquivOfBasis (N := N) b).symm x) = x := by
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹⁰ : CommRing R
inst✝⁹ : AddCommGroup M
inst✝⁸ : AddCommGroup N
inst✝⁷ : AddCommGroup P
inst✝⁶ : AddCommGroup Q
inst✝⁵ : Module R M
inst✝⁴ : Module R N
inst✝³ : Module R P
inst✝² : Module R Q
inst✝¹ : DecidableEq ι
inst✝ : Fintype ι
b : Basis ι R M
x : M →ₗ[R] N
⊢ (dualTensorHom R M N) ((LinearEquiv.symm (dualTensorHomEquivOfBasis b)) x) = x

Next tactic:
rw [← dualTensorHomEquivOfBasis_apply b, LinearEquiv.apply_symm_apply]
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
⊢ ↑(lTensorHomEquivHomLTensor R M P Q) = lTensorHomToHomLTensor R M P Q

Next tactic:
classical -- Porting note: missing decidable for choosing basis
  let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  ext f q m
  dsimp [lTensorHomEquivHomLTensor]
  simp only [lTensorHomEquivHomLTensor, dualTensorHomEquiv, compr₂_apply, mk_apply, coe_comp,
    LinearEquiv.coe_toLinearMap, Function.comp_apply, map_tmul, LinearEquiv.coe_coe,
    dualTensorHomEquivOfBasis_apply, LinearEquiv.trans_apply, congr_tmul, LinearEquiv.refl_apply,
    dualTensorHomEquivOfBasis_symm_cancel_left, leftComm_tmul, dualTensorHom_apply, tmul_smul]
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
⊢ ↑(lTensorHomEquivHomLTensor R M P Q) = lTensorHomToHomLTensor R M P Q

Next tactic:
let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : P ⊗[R] Dual R M ⊗[R] Q ≃ₗ[R] P ⊗[R] (M →ₗ[R] Q) :=
  TensorProduct.congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
⊢ ↑(lTensorHomEquivHomLTensor R M P Q) = lTensorHomToHomLTensor R M P Q

Next tactic:
have h : Function.Surjective e.toLinearMap := e.surjective
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : P ⊗[R] Dual R M ⊗[R] Q ≃ₗ[R] P ⊗[R] (M →ₗ[R] Q) :=
  TensorProduct.congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
h : Function.Surjective ⇑↑e
⊢ ↑(lTensorHomEquivHomLTensor R M P Q) = lTensorHomToHomLTensor R M P Q

Next tactic:
refine' (cancel_right h).1 _
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : P ⊗[R] Dual R M ⊗[R] Q ≃ₗ[R] P ⊗[R] (M →ₗ[R] Q) :=
  TensorProduct.congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
h : Function.Surjective ⇑↑e
⊢ ↑(lTensorHomEquivHomLTensor R M P Q) ∘ₗ ↑e = lTensorHomToHomLTensor R M P Q ∘ₗ ↑e

Next tactic:
ext f q m
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  ext f q m
  

Proof state:
case H.h.H.h.h.h
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : P ⊗[R] Dual R M ⊗[R] Q ≃ₗ[R] P ⊗[R] (M →ₗ[R] Q) :=
  TensorProduct.congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
h : Function.Surjective ⇑↑e
f : P
q : Dual R M
m : Q
x✝ : M
⊢ (((compr₂ (TensorProduct.mk R (Dual R M) Q)
            ((compr₂ (TensorProduct.mk R P (Dual R M ⊗[R] Q)) (↑(lTensorHomEquivHomLTensor R M P Q) ∘ₗ ↑e)) f))
          q)
        m)
      x✝ =
    (((compr₂ (TensorProduct.mk R (Dual R M) Q)
            ((compr₂ (TensorProduct.mk R P (Dual R M ⊗[R] Q)) (lTensorHomToHomLTensor R M P Q ∘ₗ ↑e)) f))
          q)
        m)
      x✝

Next tactic:
dsimp [lTensorHomEquivHomLTensor]
@[simp]
theorem lTensorHomEquivHomLTensor_toLinearMap :
    (lTensorHomEquivHomLTensor R M P Q).toLinearMap = lTensorHomToHomLTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  ext f q m
  dsimp [lTensorHomEquivHomLTensor]
  

Proof state:
case H.h.H.h.h.h
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : P ⊗[R] Dual R M ⊗[R] Q ≃ₗ[R] P ⊗[R] (M →ₗ[R] Q) :=
  TensorProduct.congr (LinearEquiv.refl R P) (dualTensorHomEquiv R M Q)
h : Function.Surjective ⇑↑e
f : P
q : Dual R M
m : Q
x✝ : M
⊢ ((dualTensorHomEquivOfBasis (Free.chooseBasis R M))
        ((leftComm R P (Dual R M) Q)
          (f ⊗ₜ[R]
            (LinearEquiv.symm (dualTensorHomEquivOfBasis (Free.chooseBasis R M)))
              ((dualTensorHomEquivOfBasis (Free.chooseBasis R M)) (q ⊗ₜ[R] m)))))
      x✝ =
    f ⊗ₜ[R] ((dualTensorHomEquivOfBasis (Free.chooseBasis R M)) (q ⊗ₜ[R] m)) x✝

Next tactic:
simp only [lTensorHomEquivHomLTensor, dualTensorHomEquiv, compr₂_apply, mk_apply, coe_comp,
    LinearEquiv.coe_toLinearMap, Function.comp_apply, map_tmul, LinearEquiv.coe_coe,
    dualTensorHomEquivOfBasis_apply, LinearEquiv.trans_apply, congr_tmul, LinearEquiv.refl_apply,
    dualTensorHomEquivOfBasis_symm_cancel_left, leftComm_tmul, dualTensorHom_apply, tmul_smul]
@[simp]
theorem rTensorHomEquivHomRTensor_toLinearMap :
    (rTensorHomEquivHomRTensor R M P Q).toLinearMap = rTensorHomToHomRTensor R M P Q := by
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
⊢ ↑(rTensorHomEquivHomRTensor R M P Q) = rTensorHomToHomRTensor R M P Q

Next tactic:
classical -- Porting note: missing decidable for choosing basis
  let e := congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  ext f p q m
  simp only [rTensorHomEquivHomRTensor, dualTensorHomEquiv, compr₂_apply, mk_apply, coe_comp,
    LinearEquiv.coe_toLinearMap, Function.comp_apply, map_tmul, LinearEquiv.coe_coe,
    dualTensorHomEquivOfBasis_apply, LinearEquiv.trans_apply, congr_tmul,
    dualTensorHomEquivOfBasis_symm_cancel_left, LinearEquiv.refl_apply, assoc_tmul,
    dualTensorHom_apply, rTensorHomToHomRTensor_apply, smul_tmul']
@[simp]
theorem rTensorHomEquivHomRTensor_toLinearMap :
    (rTensorHomEquivHomRTensor R M P Q).toLinearMap = rTensorHomToHomRTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
⊢ ↑(rTensorHomEquivHomRTensor R M P Q) = rTensorHomToHomRTensor R M P Q

Next tactic:
let e := congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
@[simp]
theorem rTensorHomEquivHomRTensor_toLinearMap :
    (rTensorHomEquivHomRTensor R M P Q).toLinearMap = rTensorHomToHomRTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Dual R M ⊗[R] P) ⊗[R] Q ≃ₗ[R] (M →ₗ[R] P) ⊗[R] Q :=
  TensorProduct.congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
⊢ ↑(rTensorHomEquivHomRTensor R M P Q) = rTensorHomToHomRTensor R M P Q

Next tactic:
have h : Function.Surjective e.toLinearMap := e.surjective
@[simp]
theorem rTensorHomEquivHomRTensor_toLinearMap :
    (rTensorHomEquivHomRTensor R M P Q).toLinearMap = rTensorHomToHomRTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Dual R M ⊗[R] P) ⊗[R] Q ≃ₗ[R] (M →ₗ[R] P) ⊗[R] Q :=
  TensorProduct.congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
h : Function.Surjective ⇑↑e
⊢ ↑(rTensorHomEquivHomRTensor R M P Q) = rTensorHomToHomRTensor R M P Q

Next tactic:
refine' (cancel_right h).1 _
@[simp]
theorem rTensorHomEquivHomRTensor_toLinearMap :
    (rTensorHomEquivHomRTensor R M P Q).toLinearMap = rTensorHomToHomRTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  

Proof state:
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Dual R M ⊗[R] P) ⊗[R] Q ≃ₗ[R] (M →ₗ[R] P) ⊗[R] Q :=
  TensorProduct.congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
h : Function.Surjective ⇑↑e
⊢ ↑(rTensorHomEquivHomRTensor R M P Q) ∘ₗ ↑e = rTensorHomToHomRTensor R M P Q ∘ₗ ↑e

Next tactic:
ext f p q m
@[simp]
theorem rTensorHomEquivHomRTensor_toLinearMap :
    (rTensorHomEquivHomRTensor R M P Q).toLinearMap = rTensorHomToHomRTensor R M P Q := by
  classical -- Porting note: missing decidable for choosing basis
  let e := congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
  have h : Function.Surjective e.toLinearMap := e.surjective
  refine' (cancel_right h).1 _
  ext f p q m
  

Proof state:
case H.H.h.h.h.h
ι : Type w
R : Type u
M : Type v₁
N : Type v₂
P : Type v₃
Q : Type v₄
inst✝¹³ : CommRing R
inst✝¹² : AddCommGroup M
inst✝¹¹ : AddCommGroup N
inst✝¹⁰ : AddCommGroup P
inst✝⁹ : AddCommGroup Q
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Free R M
inst✝³ : Module.Finite R M
inst✝² : Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Dual R M ⊗[R] P) ⊗[R] Q ≃ₗ[R] (M →ₗ[R] P) ⊗[R] Q :=
  TensorProduct.congr (dualTensorHomEquiv R M P) (LinearEquiv.refl R Q)
h : Function.Surjective ⇑↑e
f : Dual R M
p : P
q : Q
m : M
⊢ ((((compr₂ (TensorProduct.mk R (Dual R M) P)
              (compr₂ (TensorProduct.mk R (Dual R M ⊗[R] P) Q) (↑(rTensorHomEquivHomRTensor R M P Q) ∘ₗ ↑e)))
            f)
          p)
        q)
      m =
    ((((compr₂ (TensorProduct.mk R (Dual R M) P)
              (compr₂ (TensorProduct.mk R (Dual R M ⊗[R] P) Q) (rTensorHomToHomRTensor R M P Q ∘ₗ ↑e)))
            f)
          p)
        q)
      m

Next tactic:
simp only [rTensorHomEquivHomRTensor, dualTensorHomEquiv, compr₂_apply, mk_apply, coe_comp,
    LinearEquiv.coe_toLinearMap, Function.comp_apply, map_tmul, LinearEquiv.coe_coe,
    dualTensorHomEquivOfBasis_apply, LinearEquiv.trans_apply, congr_tmul,
    dualTensorHomEquivOfBasis_symm_cancel_left, LinearEquiv.refl_apply, assoc_tmul,
    dualTensorHom_apply, rTensorHomToHomRTensor_apply, smul_tmul']