-- Mathlib/Algebra/Module/FinitePresentation.lean
lemma Module.finitePresentation_of_free_of_surjective [Module.Free R M] [Module.Finite R M]
    (l : M →ₗ[R] N)
    (hl : Function.Surjective l) (hl' : (LinearMap.ker l).FG) :
    Module.FinitePresentation R N

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
hσ₁ : π ∘ σ = id
⊢ FinitePresentation R N

Tactic:
have hσ₂ : l ∘ b ∘ σ = Subtype.val := by ext i; exact congr_arg Subtype.val (hσ i)

Result:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
hσ₁ : π ∘ σ = id
hσ₂ : ⇑l ∘ ⇑b ∘ σ = Subtype.val
⊢ FinitePresentation R N

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
⊢ FinitePresentation R N

Tactic:
have hπ : Subtype.val ∘ π = l ∘ b := rfl

Result:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
⊢ FinitePresentation R N

Proof state:
case h.e'_6.h.mpr
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
hσ₁ : π ∘ σ = id
hσ₂ : ⇑l ∘ ⇑b ∘ σ = Subtype.val
f : M →ₗ[R] { x // x ∈ ⋯.toFinset } →₀ R := lmapDomain R R π ∘ₗ ↑b.repr
x : { x // x ∈ ⋯.toFinset } →₀ R
⊢ (∃ y, l y = 0 ∧ f y = x) → (linearCombination R Subtype.val) x = 0

Tactic:
rintro ⟨y, hy, rfl⟩

Result:
case h.e'_6.h.mpr.intro.intro
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
hσ₁ : π ∘ σ = id
hσ₂ : ⇑l ∘ ⇑b ∘ σ = Subtype.val
f : M →ₗ[R] { x // x ∈ ⋯.toFinset } →₀ R := lmapDomain R R π ∘ₗ ↑b.repr
y : M
hy : l y = 0
⊢ (linearCombination R Subtype.val) (f y) = 0

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
⊢ π ∘ σ = id

Tactic:
ext i

Result:
case h.a
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
i : { x // x ∈ ⋯.toFinset }
⊢ ↑((π ∘ σ) i) = ↑(id i)

Proof state:
case h.e'_6.h.mp.refine_2
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
π : Free.ChooseBasisIndex R M → { x // x ∈ ⋯.toFinset } := fun i => ⟨l (b i), ⋯⟩
σ : { x // x ∈ ⋯.toFinset } → Free.ChooseBasisIndex R M
hσ : ∀ (b_1 : { x // x ∈ ⋯.toFinset }), π (σ b_1) = b_1
hπ : Subtype.val ∘ π = ⇑l ∘ ⇑b
hσ₁ : π ∘ σ = id
hσ₂ : ⇑l ∘ ⇑b ∘ σ = Subtype.val
f : M →ₗ[R] { x // x ∈ ⋯.toFinset } →₀ R := lmapDomain R R π ∘ₗ ↑b.repr
x : { x // x ∈ ⋯.toFinset } →₀ R
hx : (linearCombination R Subtype.val) x = 0
⊢ mapDomain π (mapDomain σ x) = x

Tactic:
rw [← Finsupp.mapDomain_comp, hσ₁, Finsupp.mapDomain_id]

Result:
no goals

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
⊢ FinitePresentation R N

Tactic:
let b := Module.Free.chooseBasis R M

Result:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Free R M
inst✝ : Module.Finite R M
l : M →ₗ[R] N
hl : Function.Surjective ⇑l
hl' : (LinearMap.ker l).FG
b : Basis (Free.ChooseBasisIndex R M) R M := Free.chooseBasis R M
⊢ FinitePresentation R N