Theorem: LinearMap.trace_prodMap
File: Mathlib/LinearAlgebra/Trace.lean

tactic: let e := (dualTensorHomEquiv R M M).prod (dualTensorHomEquiv R N N)
state_before: R : Type u_1
inst✝⁹ : CommRing R
M : Type u_2
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
N : Type u_3
inst✝⁶ : AddCommGroup N
inst✝⁵ : Module R N
ι : Type ?u.416634
inst✝⁴ : Module.Free R M
inst✝³ : Module.Finite R M
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
⊢ comp (trace R (M × N)) (prodMapLinear R M N M N R) = comp (coprod id id) (prodMap (trace R M) (trace R N))

tactic: have h : Function.Surjective e.toLinearMap := e.surjective
state_before: R : Type u_1
inst✝⁹ : CommRing R
M : Type u_2
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
N : Type u_3
inst✝⁶ : AddCommGroup N
inst✝⁵ : Module R N
ι : Type ?u.416634
inst✝⁴ : Module.Free R M
inst✝³ : Module.Finite R M
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Module.Dual R M ⊗[R] M × Module.Dual R N ⊗[R] N) ≃ₗ[R] (M →ₗ[R] M) × (N →ₗ[R] N) :=
  LinearEquiv.prod (dualTensorHomEquiv R M M) (dualTensorHomEquiv R N N)
⊢ comp (trace R (M × N)) (prodMapLinear R M N M N R) = comp (coprod id id) (prodMap (trace R M) (trace R N))

tactic: refine' (cancel_right h).1 _
state_before: R : Type u_1
inst✝⁹ : CommRing R
M : Type u_2
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
N : Type u_3
inst✝⁶ : AddCommGroup N
inst✝⁵ : Module R N
ι : Type ?u.416634
inst✝⁴ : Module.Free R M
inst✝³ : Module.Finite R M
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Module.Dual R M ⊗[R] M × Module.Dual R N ⊗[R] N) ≃ₗ[R] (M →ₗ[R] M) × (N →ₗ[R] N) :=
  LinearEquiv.prod (dualTensorHomEquiv R M M) (dualTensorHomEquiv R N N)
h : Function.Surjective ↑↑e
⊢ comp (trace R (M × N)) (prodMapLinear R M N M N R) = comp (coprod id id) (prodMap (trace R M) (trace R N))

tactic: ext
state_before: R : Type u_1
inst✝⁹ : CommRing R
M : Type u_2
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
N : Type u_3
inst✝⁶ : AddCommGroup N
inst✝⁵ : Module R N
ι : Type ?u.416634
inst✝⁴ : Module.Free R M
inst✝³ : Module.Finite R M
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Module.Dual R M ⊗[R] M × Module.Dual R N ⊗[R] N) ≃ₗ[R] (M →ₗ[R] M) × (N →ₗ[R] N) :=
  LinearEquiv.prod (dualTensorHomEquiv R M M) (dualTensorHomEquiv R N N)
h : Function.Surjective ↑↑e
⊢ comp (comp (trace R (M × N)) (prodMapLinear R M N M N R)) ↑e =
    comp (comp (coprod id id) (prodMap (trace R M) (trace R N))) ↑e

tactic: simp only [dualTensorHomEquiv, AlgebraTensorModule.curry_apply_apply, coe_comp,
  LinearEquiv.coe_toLinearMap, coe_inl, Function.comp_apply, LinearEquiv.prod_apply,
  dualTensorHomEquivOfBasis_apply, map_zero, prodMapLinear_apply, dualTensorHom_prodMap_zero,
  trace_eq_contract_apply, contractLeft_apply, fst_apply, prodMap_apply, coprod_apply, id_coe,
  id.def, add_zero]
state_before: case hl.a.h.h
R : Type u_1
inst✝⁹ : CommRing R
M : Type u_2
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
N : Type u_3
inst✝⁶ : AddCommGroup N
inst✝⁵ : Module R N
ι : Type ?u.416634
inst✝⁴ : Module.Free R M
inst✝³ : Module.Finite R M
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Module.Dual R M ⊗[R] M × Module.Dual R N ⊗[R] N) ≃ₗ[R] (M →ₗ[R] M) × (N →ₗ[R] N) :=
  LinearEquiv.prod (dualTensorHomEquiv R M M) (dualTensorHomEquiv R N N)
h : Function.Surjective ↑↑e
x✝¹ : Module.Dual R M
x✝ : M
⊢ ↑(↑(AlgebraTensorModule.curry
              (comp (comp (comp (trace R (M × N)) (prodMapLinear R M N M N R)) ↑e)
                (inl R (Module.Dual R M ⊗[R] M) (Module.Dual R N ⊗[R] N))))
          x✝¹)
      x✝ =
    ↑(↑(AlgebraTensorModule.curry
              (comp (comp (comp (coprod id id) (prodMap (trace R M) (trace R N))) ↑e)
                (inl R (Module.Dual R M ⊗[R] M) (Module.Dual R N ⊗[R] N))))
          x✝¹)
      x✝

tactic: simp only [dualTensorHomEquiv, AlgebraTensorModule.curry_apply_apply, coe_comp,
  LinearEquiv.coe_toLinearMap, coe_inr, Function.comp_apply, LinearEquiv.prod_apply, map_zero,
  dualTensorHomEquivOfBasis_apply, prodMapLinear_apply, zero_prodMap_dualTensorHom,
  trace_eq_contract_apply, contractLeft_apply, snd_apply, prodMap_apply, coprod_apply, id_coe,
  id.def, zero_add]
state_before: case hr.a.h.h
R : Type u_1
inst✝⁹ : CommRing R
M : Type u_2
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
N : Type u_3
inst✝⁶ : AddCommGroup N
inst✝⁵ : Module R N
ι : Type ?u.416634
inst✝⁴ : Module.Free R M
inst✝³ : Module.Finite R M
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
inst✝ : Nontrivial R
e : (Module.Dual R M ⊗[R] M × Module.Dual R N ⊗[R] N) ≃ₗ[R] (M →ₗ[R] M) × (N →ₗ[R] N) :=
  LinearEquiv.prod (dualTensorHomEquiv R M M) (dualTensorHomEquiv R N N)
h : Function.Surjective ↑↑e
x✝¹ : Module.Dual R N
x✝ : N
⊢ ↑(↑(AlgebraTensorModule.curry
              (comp (comp (comp (trace R (M × N)) (prodMapLinear R M N M N R)) ↑e)
                (inr R (Module.Dual R M ⊗[R] M) (Module.Dual R N ⊗[R] N))))
          x✝¹)
      x✝ =
    ↑(↑(AlgebraTensorModule.curry
              (comp (comp (comp (coprod id id) (prodMap (trace R M) (trace R N))) ↑e)
                (inr R (Module.Dual R M ⊗[R] M) (Module.Dual R N ⊗[R] N))))
          x✝¹)
      x✝