-- Mathlib/LinearAlgebra/FreeModule/PID.lean
/-- Given a Smith-normal-form pair of bases for `N ⊆ M`, and a linear endomorphism `f` of `M`
that preserves `N`, the diagonal of the matrix of the restriction `f` to `N` does not depend on
which of the two bases for `N` is used. -/
@[simp]
lemma toMatrix_restrict_eq_toMatrix [Fintype ι] [DecidableEq ι]
    (f : M →ₗ[R] M) (hf : ∀ x, f x ∈ N) (hf' : ∀ x ∈ N, f x ∈ N := fun x _ ↦ hf x) {i : Fin n} :
    LinearMap.toMatrix snf.bN snf.bN (LinearMap.restrict f hf') i i =
    LinearMap.toMatrix snf.bM snf.bM f (snf.f i) (snf.f i)

Proof state:
case e_a.h.e_6.h.a
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ ↑((f.restrict hf') (snf.bN i)) = ↑(snf.a i • ⟨f (snf.bM (snf.f i)), ⋯⟩)

Tactic:
simp [snf.snf]

Result:
no goals

Proof state:
case e_a.h.e_6.h
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ (f.restrict hf') (snf.bN i) = snf.a i • ⟨f (snf.bM (snf.f i)), ⋯⟩

Tactic:
ext

Result:
case e_a.h.e_6.h.a
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ ↑((f.restrict hf') (snf.bN i)) = ↑(snf.a i • ⟨f (snf.bM (snf.f i)), ⋯⟩)

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ (snf.bN.repr ((f.restrict hf') (snf.bN i))) i = (snf.bN.repr (snf.a i • ⟨f (snf.bM (snf.f i)), ⋯⟩)) i

Tactic:
congr

Result:
case e_a.h.e_6.h
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ (f.restrict hf') (snf.bN i) = snf.a i • ⟨f (snf.bM (snf.f i)), ⋯⟩

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ (LinearMap.toMatrix snf.bN snf.bN) (f.restrict hf') i i = (LinearMap.toMatrix snf.bM snf.bM) f (snf.f i) (snf.f i)

Tactic:
rw [LinearMap.toMatrix_apply, LinearMap.toMatrix_apply,
  snf.repr_apply_embedding_eq_repr_smul ⟨_, (hf _)⟩]

Result:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
f : M →ₗ[R] M
hf : ∀ (x : M), f x ∈ N
hf' : optParam (∀ x ∈ N, f x ∈ N) ⋯
i : Fin n
⊢ (snf.bN.repr ((f.restrict hf') (snf.bN i))) i = (snf.bN.repr (snf.a i • ⟨f (snf.bM (snf.f i)), ⋯⟩)) i