l3lab/ntp-mathlib huggingface dataset:
/-- A finite type torsion free module over a PID admits a basis. -/
noncomputable def Module.basisOfFiniteTypeTorsionFree [Fintype ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Σn : ℕ, Basis (Fin n) R M := by
  classical
    -- We define `N` as the submodule spanned by a maximal linear independent subfamily of `s`
    have := exists_maximal_independent R s
    let I : Set ι := this.choose
    obtain
      ⟨indepI : LinearIndependent R (s ∘ (fun x => x) : I → M), hI :
        ∀ i ∉ I, ∃ a : R, a ≠ 0 ∧ a • s i ∈ span R (s '' I)⟩ :=
      this.choose_spec
    let N := span R (range <| (s ∘ (fun x => x) : I → M))
    -- same as `span R (s '' I)` but more convenient
    let _sI : I → N := fun i ↦ ⟨s i.1, subset_span (mem_range_self i)⟩
    -- `s` restricted to `I` is a basis of `N`
    let sI_basis : Basis I R N := Basis.span indepI
    -- Our first goal is to build `A ≠ 0` such that `A • M ⊆ N`
    have exists_a : ∀ i : ι, ∃ a : R, a ≠ 0 ∧ a • s i ∈ N := by
      intro i
      by_cases hi : i ∈ I
      · use 1, zero_ne_one.symm
        rw [one_smul]
        exact subset_span (mem_range_self (⟨i, hi⟩ : I))
      · simpa [image_eq_range s I] using hI i hi
    choose a ha ha' using exists_a
    let A := ∏ i, a i
    have hA : A ≠ 0 := by
      rw [Finset.prod_ne_zero_iff]
      simpa using ha
    -- `M ≃ A • M` because `M` is torsion free and `A ≠ 0`
    let φ : M →ₗ[R] M := LinearMap.lsmul R M A
    have : LinearMap.ker φ = ⊥ := @LinearMap.ker_lsmul R M _ _ _ _ _ hA
    let ψ := LinearEquiv.ofInjective φ (LinearMap.ker_eq_bot.mp this)
    have : LinearMap.range φ ≤ N := by
      -- as announced, `A • M ⊆ N`
      suffices ∀ i, φ (s i) ∈ N by
        rw [LinearMap.range_eq_map, ← hs, map_span_le]
        rintro _ ⟨i, rfl⟩
        

Proof state:
case intro
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : Fintype ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
this✝¹ : ∃ I, (LinearIndependent R fun (x : ↑I) => s ↑x) ∧ ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
I : Set ι := Exists.choose this✝¹
indepI : LinearIndependent (ι := ↑I) R (s ∘ fun x => ↑x)
hI : ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
N : Submodule R M := span R (range (s ∘ fun x => ↑x))
_sI : ↑I → ↥N := fun i => { val := s ↑i, property := (_ : s ↑i ∈ ↑(span R (range (s ∘ fun x => ↑x)))) }
sI_basis : Basis (↑I) R ↥N := Basis.span indepI
a : ι → R
ha : ∀ (i : ι), a i ≠ 0
ha' : ∀ (i : ι), a i • s i ∈ N
A : R := ∏ i : ι, a i
hA : A ≠ 0
φ : M →ₗ[R] M := (LinearMap.lsmul R M) A
this✝ : LinearMap.ker φ = ⊥
ψ : M ≃ₗ[R] ↥(LinearMap.range φ) := LinearEquiv.ofInjective φ (_ : Function.Injective ⇑φ)
this : ∀ (i : ι), φ (s i) ∈ N
i : ι
⊢ φ (s i) ∈ N

Next tactic:
apply this
/-- A finite type torsion free module over a PID admits a basis. -/
noncomputable def Module.basisOfFiniteTypeTorsionFree [Fintype ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Σn : ℕ, Basis (Fin n) R M := by
  classical
    -- We define `N` as the submodule spanned by a maximal linear independent subfamily of `s`
    have := exists_maximal_independent R s
    let I : Set ι := this.choose
    obtain
      ⟨indepI : LinearIndependent R (s ∘ (fun x => x) : I → M), hI :
        ∀ i ∉ I, ∃ a : R, a ≠ 0 ∧ a • s i ∈ span R (s '' I)⟩ :=
      this.choose_spec
    let N := span R (range <| (s ∘ (fun x => x) : I → M))
    -- same as `span R (s '' I)` but more convenient
    let _sI : I → N := fun i ↦ ⟨s i.1, subset_span (mem_range_self i)⟩
    -- `s` restricted to `I` is a basis of `N`
    let sI_basis : Basis I R N := Basis.span indepI
    -- Our first goal is to build `A ≠ 0` such that `A • M ⊆ N`
    have exists_a : ∀ i : ι, ∃ a : R, a ≠ 0 ∧ a • s i ∈ N := by
      intro i
      by_cases hi : i ∈ I
      · use 1, zero_ne_one.symm
        rw [one_smul]
        exact subset_span (mem_range_self (⟨i, hi⟩ : I))
      · simpa [image_eq_range s I] using hI i hi
    choose a ha ha' using exists_a
    let A := ∏ i, a i
    have hA : A ≠ 0 := by
      rw [Finset.prod_ne_zero_iff]
      simpa using ha
    -- `M ≃ A • M` because `M` is torsion free and `A ≠ 0`
    let φ : M →ₗ[R] M := LinearMap.lsmul R M A
    have : LinearMap.ker φ = ⊥ := @LinearMap.ker_lsmul R M _ _ _ _ _ hA
    let ψ := LinearEquiv.ofInjective φ (LinearMap.ker_eq_bot.mp this)
    have : LinearMap.range φ ≤ N := by
      -- as announced, `A • M ⊆ N`
      suffices ∀ i, φ (s i) ∈ N by
        rw [LinearMap.range_eq_map, ← hs, map_span_le]
        rintro _ ⟨i, rfl⟩
        apply this
      

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : Fintype ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
this✝ : ∃ I, (LinearIndependent R fun (x : ↑I) => s ↑x) ∧ ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
I : Set ι := Exists.choose this✝
indepI : LinearIndependent (ι := ↑I) R (s ∘ fun x => ↑x)
hI : ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
N : Submodule R M := span R (range (s ∘ fun x => ↑x))
_sI : ↑I → ↥N := fun i => { val := s ↑i, property := (_ : s ↑i ∈ ↑(span R (range (s ∘ fun x => ↑x)))) }
sI_basis : Basis (↑I) R ↥N := Basis.span indepI
a : ι → R
ha : ∀ (i : ι), a i ≠ 0
ha' : ∀ (i : ι), a i • s i ∈ N
A : R := ∏ i : ι, a i
hA : A ≠ 0
φ : M →ₗ[R] M := (LinearMap.lsmul R M) A
this : LinearMap.ker φ = ⊥
ψ : M ≃ₗ[R] ↥(LinearMap.range φ) := LinearEquiv.ofInjective φ (_ : Function.Injective ⇑φ)
⊢ ∀ (i : ι), φ (s i) ∈ N

Next tactic:
intro i
/-- A finite type torsion free module over a PID admits a basis. -/
noncomputable def Module.basisOfFiniteTypeTorsionFree [Fintype ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Σn : ℕ, Basis (Fin n) R M := by
  classical
    -- We define `N` as the submodule spanned by a maximal linear independent subfamily of `s`
    have := exists_maximal_independent R s
    let I : Set ι := this.choose
    obtain
      ⟨indepI : LinearIndependent R (s ∘ (fun x => x) : I → M), hI :
        ∀ i ∉ I, ∃ a : R, a ≠ 0 ∧ a • s i ∈ span R (s '' I)⟩ :=
      this.choose_spec
    let N := span R (range <| (s ∘ (fun x => x) : I → M))
    -- same as `span R (s '' I)` but more convenient
    let _sI : I → N := fun i ↦ ⟨s i.1, subset_span (mem_range_self i)⟩
    -- `s` restricted to `I` is a basis of `N`
    let sI_basis : Basis I R N := Basis.span indepI
    -- Our first goal is to build `A ≠ 0` such that `A • M ⊆ N`
    have exists_a : ∀ i : ι, ∃ a : R, a ≠ 0 ∧ a • s i ∈ N := by
      intro i
      by_cases hi : i ∈ I
      · use 1, zero_ne_one.symm
        rw [one_smul]
        exact subset_span (mem_range_self (⟨i, hi⟩ : I))
      · simpa [image_eq_range s I] using hI i hi
    choose a ha ha' using exists_a
    let A := ∏ i, a i
    have hA : A ≠ 0 := by
      rw [Finset.prod_ne_zero_iff]
      simpa using ha
    -- `M ≃ A • M` because `M` is torsion free and `A ≠ 0`
    let φ : M →ₗ[R] M := LinearMap.lsmul R M A
    have : LinearMap.ker φ = ⊥ := @LinearMap.ker_lsmul R M _ _ _ _ _ hA
    let ψ := LinearEquiv.ofInjective φ (LinearMap.ker_eq_bot.mp this)
    have : LinearMap.range φ ≤ N := by
      -- as announced, `A • M ⊆ N`
      suffices ∀ i, φ (s i) ∈ N by
        rw [LinearMap.range_eq_map, ← hs, map_span_le]
        rintro _ ⟨i, rfl⟩
        apply this
      intro i
      

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : Fintype ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
this✝ : ∃ I, (LinearIndependent R fun (x : ↑I) => s ↑x) ∧ ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
I : Set ι := Exists.choose this✝
indepI : LinearIndependent (ι := ↑I) R (s ∘ fun x => ↑x)
hI : ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
N : Submodule R M := span R (range (s ∘ fun x => ↑x))
_sI : ↑I → ↥N := fun i => { val := s ↑i, property := (_ : s ↑i ∈ ↑(span R (range (s ∘ fun x => ↑x)))) }
sI_basis : Basis (↑I) R ↥N := Basis.span indepI
a : ι → R
ha : ∀ (i : ι), a i ≠ 0
ha' : ∀ (i : ι), a i • s i ∈ N
A : R := ∏ i : ι, a i
hA : A ≠ 0
φ : M →ₗ[R] M := (LinearMap.lsmul R M) A
this : LinearMap.ker φ = ⊥
ψ : M ≃ₗ[R] ↥(LinearMap.range φ) := LinearEquiv.ofInjective φ (_ : Function.Injective ⇑φ)
i : ι
⊢ φ (s i) ∈ N

Next tactic:
calc
        (∏ j, a j) • s i = (∏ j in {i}ᶜ, a j) • a i • s i := by
          rw [Fintype.prod_eq_prod_compl_mul i, mul_smul]
        _ ∈ N := N.smul_mem _ (ha' i)
/-- A finite type torsion free module over a PID admits a basis. -/
noncomputable def Module.basisOfFiniteTypeTorsionFree [Fintype ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Σn : ℕ, Basis (Fin n) R M := by
  classical
    -- We define `N` as the submodule spanned by a maximal linear independent subfamily of `s`
    have := exists_maximal_independent R s
    let I : Set ι := this.choose
    obtain
      ⟨indepI : LinearIndependent R (s ∘ (fun x => x) : I → M), hI :
        ∀ i ∉ I, ∃ a : R, a ≠ 0 ∧ a • s i ∈ span R (s '' I)⟩ :=
      this.choose_spec
    let N := span R (range <| (s ∘ (fun x => x) : I → M))
    -- same as `span R (s '' I)` but more convenient
    let _sI : I → N := fun i ↦ ⟨s i.1, subset_span (mem_range_self i)⟩
    -- `s` restricted to `I` is a basis of `N`
    let sI_basis : Basis I R N := Basis.span indepI
    -- Our first goal is to build `A ≠ 0` such that `A • M ⊆ N`
    have exists_a : ∀ i : ι, ∃ a : R, a ≠ 0 ∧ a • s i ∈ N := by
      intro i
      by_cases hi : i ∈ I
      · use 1, zero_ne_one.symm
        rw [one_smul]
        exact subset_span (mem_range_self (⟨i, hi⟩ : I))
      · simpa [image_eq_range s I] using hI i hi
    choose a ha ha' using exists_a
    let A := ∏ i, a i
    have hA : A ≠ 0 := by
      rw [Finset.prod_ne_zero_iff]
      simpa using ha
    -- `M ≃ A • M` because `M` is torsion free and `A ≠ 0`
    let φ : M →ₗ[R] M := LinearMap.lsmul R M A
    have : LinearMap.ker φ = ⊥ := @LinearMap.ker_lsmul R M _ _ _ _ _ hA
    let ψ := LinearEquiv.ofInjective φ (LinearMap.ker_eq_bot.mp this)
    have : LinearMap.range φ ≤ N := by
      -- as announced, `A • M ⊆ N`
      suffices ∀ i, φ (s i) ∈ N by
        rw [LinearMap.range_eq_map, ← hs, map_span_le]
        rintro _ ⟨i, rfl⟩
        apply this
      intro i
      calc
        (∏ j, a j) • s i = (∏ j in {i}ᶜ, a j) • a i • s i := by
          

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : Fintype ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
this✝ : ∃ I, (LinearIndependent R fun (x : ↑I) => s ↑x) ∧ ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
I : Set ι := Exists.choose this✝
indepI : LinearIndependent (ι := ↑I) R (s ∘ fun x => ↑x)
hI : ∀ i ∉ I, ∃ a, a ≠ 0 ∧ a • s i ∈ span R (s '' I)
N : Submodule R M := span R (range (s ∘ fun x => ↑x))
_sI : ↑I → ↥N := fun i => { val := s ↑i, property := (_ : s ↑i ∈ ↑(span R (range (s ∘ fun x => ↑x)))) }
sI_basis : Basis (↑I) R ↥N := Basis.span indepI
a : ι → R
ha : ∀ (i : ι), a i ≠ 0
ha' : ∀ (i : ι), a i • s i ∈ N
A : R := ∏ i : ι, a i
hA : A ≠ 0
φ : M →ₗ[R] M := (LinearMap.lsmul R M) A
this : LinearMap.ker φ = ⊥
ψ : M ≃ₗ[R] ↥(LinearMap.range φ) := LinearEquiv.ofInjective φ (_ : Function.Injective ⇑φ)
i : ι
⊢ (∏ j : ι, a j) • s i = (∏ j in {i}ᶜ, a j) • a i • s i

Next tactic:
rw [Fintype.prod_eq_prod_compl_mul i, mul_smul]
theorem Module.free_of_finite_type_torsion_free [_root_.Finite ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Module.Free R M := by
  

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : _root_.Finite ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
⊢ Free R M

Next tactic:
cases nonempty_fintype ι
theorem Module.free_of_finite_type_torsion_free [_root_.Finite ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Module.Free R M := by
  cases nonempty_fintype ι
  

Proof state:
case intro
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : _root_.Finite ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
val✝ : Fintype ι
⊢ Free R M

Next tactic:
obtain ⟨n, b⟩ : Σn, Basis (Fin n) R M := Module.basisOfFiniteTypeTorsionFree hs
theorem Module.free_of_finite_type_torsion_free [_root_.Finite ι] {s : ι → M}
    (hs : span R (range s) = ⊤) [NoZeroSMulDivisors R M] : Module.Free R M := by
  cases nonempty_fintype ι
  obtain ⟨n, b⟩ : Σn, Basis (Fin n) R M := Module.basisOfFiniteTypeTorsionFree hs
  

Proof state:
case intro.mk
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b✝ : ι → M
inst✝¹ : _root_.Finite ι
s : ι → M
hs : span R (range s) = ⊤
inst✝ : NoZeroSMulDivisors R M
val✝ : Fintype ι
n : ℕ
b : Basis (Fin n) R M
⊢ Free R M

Next tactic:
exact Module.Free.of_basis b
theorem Module.free_of_finite_type_torsion_free' [Module.Finite R M] [NoZeroSMulDivisors R M] :
    Module.Free R M := by
  

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b : ι → M
inst✝¹ : Finite R M
inst✝ : NoZeroSMulDivisors R M
⊢ Free R M

Next tactic:
obtain ⟨n, b⟩ : Σn, Basis (Fin n) R M := Module.basisOfFiniteTypeTorsionFree'
theorem Module.free_of_finite_type_torsion_free' [Module.Finite R M] [NoZeroSMulDivisors R M] :
    Module.Free R M := by
  obtain ⟨n, b⟩ : Σn, Basis (Fin n) R M := Module.basisOfFiniteTypeTorsionFree'
  

Proof state:
case mk
ι : Type u_1
R : Type u_2
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type u_3
inst✝³ : AddCommGroup M
inst✝² : Module R M
b✝ : ι → M
inst✝¹ : Finite R M
inst✝ : NoZeroSMulDivisors R M
n : ℕ
b : Basis (Fin n) R M
⊢ Free R M

Next tactic:
exact Module.Free.of_basis b
lemma repr_eq_zero_of_nmem_range {i : ι} (hi : i ∉ Set.range snf.f) :
    snf.bM.repr m i = 0 := by
  

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
m : ↥N
i : ι
hi : i ∉ range ⇑snf.f
⊢ (snf.bM.repr ↑m) i = 0

Next tactic:
obtain ⟨m, hm⟩ := m
lemma repr_eq_zero_of_nmem_range {i : ι} (hi : i ∉ Set.range snf.f) :
    snf.bM.repr m i = 0 := by
  obtain ⟨m, hm⟩ := m
  

Proof state:
case mk
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : ι
hi : i ∉ range ⇑snf.f
m : M
hm : m ∈ N
⊢ (snf.bM.repr ↑{ val := m, property := hm }) i = 0

Next tactic:
obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
lemma repr_eq_zero_of_nmem_range {i : ι} (hi : i ∉ Set.range snf.f) :
    snf.bM.repr m i = 0 := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  

Proof state:
case mk.intro
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : ι
hi : i ∉ range ⇑snf.f
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
⊢ (snf.bM.repr ↑{ val := Finsupp.sum c fun i x => x • ↑(snf.bN i), property := hm }) i = 0

Next tactic:
replace hi : ∀ j, snf.f j ≠ i := by simpa using hi
lemma repr_eq_zero_of_nmem_range {i : ι} (hi : i ∉ Set.range snf.f) :
    snf.bM.repr m i = 0 := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  replace hi : ∀ j, snf.f j ≠ i := by 

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : ι
hi : i ∉ range ⇑snf.f
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
⊢ ∀ (j : Fin n), snf.f j ≠ i

Next tactic:
simpa using hi
lemma repr_eq_zero_of_nmem_range {i : ι} (hi : i ∉ Set.range snf.f) :
    snf.bM.repr m i = 0 := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  replace hi : ∀ j, snf.f j ≠ i := by simpa using hi
  

Proof state:
case mk.intro
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : ι
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
hi : ∀ (j : Fin n), snf.f j ≠ i
⊢ (snf.bM.repr ↑{ val := Finsupp.sum c fun i x => x • ↑(snf.bN i), property := hm }) i = 0

Next tactic:
simp [Finsupp.single_apply, hi, snf.snf, map_finsupp_sum]
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
m : ↥N
i : Fin n
⊢ (snf.bM.repr ↑m) (snf.f i) = (snf.bN.repr (a snf i • m)) i

Next tactic:
obtain ⟨m, hm⟩ := m
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  obtain ⟨m, hm⟩ := m
  

Proof state:
case mk
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : Fin n
m : M
hm : m ∈ N
⊢ (snf.bM.repr ↑{ val := m, property := hm }) (snf.f i) = (snf.bN.repr (a snf i • { val := m, property := hm })) i

Next tactic:
obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  

Proof state:
case mk.intro
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : Fin n
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
⊢ (snf.bM.repr ↑{ val := Finsupp.sum c fun i x => x • ↑(snf.bN i), property := hm }) (snf.f i) =
    (snf.bN.repr (a snf i • { val := Finsupp.sum c fun i x => x • ↑(snf.bN i), property := hm })) i

Next tactic:
replace hm : (⟨Finsupp.sum c fun i t ↦ t • (↑(snf.bN i) : M), hm⟩ : N) =
      Finsupp.sum c fun i t ↦ t • ⟨snf.bN i, (snf.bN i).2⟩ := by
    ext; change _ = N.subtype _; simp [map_finsupp_sum]
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  replace hm : (⟨Finsupp.sum c fun i t ↦ t • (↑(snf.bN i) : M), hm⟩ : N) =
      Finsupp.sum c fun i t ↦ t • ⟨snf.bN i, (snf.bN i).2⟩ := by
    

Proof state:
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : Fin n
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
⊢ { val := Finsupp.sum c fun i t => t • ↑(snf.bN i), property := hm } =
    Finsupp.sum c fun i t => t • { val := ↑(snf.bN i), property := (_ : ↑(snf.bN i) ∈ N) }

Next tactic:
ext
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  replace hm : (⟨Finsupp.sum c fun i t ↦ t • (↑(snf.bN i) : M), hm⟩ : N) =
      Finsupp.sum c fun i t ↦ t • ⟨snf.bN i, (snf.bN i).2⟩ := by
    ext; 

Proof state:
case a
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : Fin n
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
⊢ ↑{ val := Finsupp.sum c fun i t => t • ↑(snf.bN i), property := hm } =
    ↑(Finsupp.sum c fun i t => t • { val := ↑(snf.bN i), property := (_ : ↑(snf.bN i) ∈ N) })

Next tactic:
change _ = N.subtype _
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  replace hm : (⟨Finsupp.sum c fun i t ↦ t • (↑(snf.bN i) : M), hm⟩ : N) =
      Finsupp.sum c fun i t ↦ t • ⟨snf.bN i, (snf.bN i).2⟩ := by
    ext; change _ = N.subtype _; 

Proof state:
case a
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : Fin n
c : Fin n →₀ R
hm : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
⊢ ↑{ val := Finsupp.sum c fun i t => t • ↑(snf.bN i), property := hm } =
    (Submodule.subtype N) (Finsupp.sum c fun i t => t • { val := ↑(snf.bN i), property := (_ : ↑(snf.bN i) ∈ N) })

Next tactic:
simp [map_finsupp_sum]
@[simp] lemma repr_apply_embedding_eq_repr_smul {i : Fin n} :
    snf.bM.repr m (snf.f i) = snf.bN.repr (snf.a i • m) i := by
  obtain ⟨m, hm⟩ := m
  obtain ⟨c, rfl⟩ := snf.bN.mem_submodule_iff.mp hm
  replace hm : (⟨Finsupp.sum c fun i t ↦ t • (↑(snf.bN i) : M), hm⟩ : N) =
      Finsupp.sum c fun i t ↦ t • ⟨snf.bN i, (snf.bN i).2⟩ := by
    ext; change _ = N.subtype _; simp [map_finsupp_sum]
  

Proof state:
case mk.intro
ι : Type u_1
R : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : IsPrincipalIdealRing R
M : Type u_3
inst✝¹ : AddCommGroup M
inst✝ : Module R M
b : ι → M
n : ℕ
N : Submodule R M
snf : SmithNormalForm N ι n
i : Fin n
c : Fin n →₀ R
hm✝ : (Finsupp.sum c fun i x => x • ↑(snf.bN i)) ∈ N
hm :
  { val := Finsupp.sum c fun i t => t • ↑(snf.bN i), property := hm✝ } =
    Finsupp.sum c fun i t => t • { val := ↑(snf.bN i), property := (_ : ↑(snf.bN i) ∈ N) }
⊢ (snf.bM.repr ↑{ val := Finsupp.sum c fun i x => x • ↑(snf.bN i), property := hm✝ }) (snf.f i) =
    (snf.bN.repr (a snf i • { val := Finsupp.sum c fun i x => x • ↑(snf.bN i), property := hm✝ })) i

Next tactic:
classical
  simp_rw [hm, map_smul, map_finsupp_sum, map_smul, Subtype.coe_eta, repr_self,
    Finsupp.smul_single, smul_eq_mul, mul_one, Finsupp.sum_single, Finsupp.smul_apply, snf.snf,
    map_smul, repr_self, Finsupp.smul_single, smul_eq_mul, mul_one, Finsupp.sum_apply,
    Finsupp.single_apply, EmbeddingLike.apply_eq_iff_eq, Finsupp.sum_ite_eq',
    Finsupp.mem_support_iff, ite_not, mul_comm, ite_eq_right_iff]
  exact fun a ↦ (mul_eq_zero_of_right _ a).symm