Full source
/-- Any commutative ring `R` satisfies the `OrzechProperty`, that is, for any finitely generated
`R`-module `M`, any surjective homomorphism `f : N →ₗ[R] M` from a submodule `N` of `M` to `M`
is injective.
This is a consequence of Noetherian case
(`IsNoetherian.injective_of_surjective_of_injective`), which requires that `M` is a
Noetherian module, but allows `R` to be non-commutative. The reduction of this result to
Noetherian case is adapted from <https://math.stackexchange.com/a/1066110>:
suppose `{ m_j }` is a finite set of generator of `M`, for any `n : N` one can write
`i n = ∑ j, b_j * m_j` for `{ b_j }` in `R`, here `i : N →ₗ[R] M` is the standard inclusion.
We can choose `{ n_j }` which are preimages of `{ m_j }` under `f`, and can choose
`{ c_jl }` in `R` such that `i n_j = ∑ l, c_jl * m_l` for each `j`.
Now let `A` be the subring of `R` generated by `{ b_j }` and `{ c_jl }`, then it is
Noetherian. Let `N'` be the `A`-submodule of `N` generated by `n` and `{ n_j }`,
`M'` be the `A`-submodule of `M` generated by `{ m_j }`,
then it's easy to see that `i` and `f` restrict to `N' →ₗ[A] M'`,
and the restricted version of `f` is surjective, hence by Noetherian case,
it is also injective, in particular, if `f n = 0`, then `n = 0`.
See also Orzech's original paper: *Onto endomorphisms are isomorphisms* [orzech1971]. -/
instance (priority := 100) CommRing.orzechProperty
(R : Type*) [CommRing R] : OrzechProperty R := by
refine ⟨fun {M} _ _ _ {N} f hf ↦ ?_⟩
letI := addCommMonoidToAddCommGroup R (M := M)
letI := addCommMonoidToAddCommGroup R (M := N)
let i := N.subtype
let hi : Function.Injective i := N.injective_subtype
refine LinearMap.ker_eq_bot.1 <| LinearMap.ker_eq_bot'.2 fun n hn ↦ ?_
obtain ⟨k, mj, hmj⟩ := exists_fin (R := R) (M := M)
rw [← surjective_piEquiv_apply_iff] at hmj
obtain ⟨b, hb⟩ := hmj (i n)
choose nj hnj using fun j ↦ hf (mj j)
choose c hc using fun j ↦ hmj (i (nj j))
let A := Subring.closure (Set.rangeSet.range b ∪ Set.range c.uncurry)
let N' := span A ({n}{n} ∪ Set.range nj)
let M' := span A (Set.range mj)
haveI : IsNoetherianRing A := is_noetherian_subring_closure _
(.union (Set.finite_range _) (Set.finite_range _))
haveI : Module.Finite A M' := span_of_finite A (Set.finite_range _)
refine congr($((LinearMap.ker_eq_bot'.1 <| LinearMap.ker_eq_bot.2 <|
IsNoetherian.injective_of_surjective_of_injective
((i.restrictScalars A).restrict fun x hx ↦ ?_ : N' →ₗ[A] M')
((f.restrictScalars A).restrict fun x hx ↦ ?_ : N' →ₗ[A] M')
(fun _ _ h ↦ injective_subtype _ (hi congr(($h).1)))
fun ⟨x, hx⟩ ↦ ?_) ⟨n, (subset_span (by simp))⟩ (Subtype.val_injective hn)).1)
· induction hx using span_induction with
| mem x hx =>
change i x ∈ M'
simp only [Set.singleton_union, Set.mem_insert_iff, Set.mem_range] at hx
rcases hx with hx | ⟨j, rfl⟩
· rw [hx, ← hb, piEquiv_apply_apply]
refine Submodule.sum_mem _ fun j _ ↦ ?_
let b' : A := ⟨b j, Subring.subset_closure (by simp)⟩
rw [show b j • mj j = b' • mj j from rfl]
exact smul_mem _ _ (subset_span (by simp))
· rw [← hc, piEquiv_apply_apply]
refine Submodule.sum_mem _ fun j' _ ↦ ?_
let c' : A := ⟨c j j', Subring.subset_closure
(by simp [show ∃ a b, c a b = c j j' from ⟨j, j', rfl⟩])⟩
rw [show c j j' • mj j' = c' • mj j' from rfl]
exact smul_mem _ _ (subset_span (by simp))
| zero => simp
| add x _ y _ hx hy => rw [map_add]; exact add_mem hx hy
| smul a x _ hx => rw [map_smul]; exact smul_mem _ _ hx
· induction hx using span_induction with
| mem x hx =>
change f x ∈ M'
simp only [Set.singleton_union, Set.mem_insert_iff, Set.mem_range] at hx
rcases hx with hx | ⟨j, rfl⟩
· rw [hx, hn]; exact zero_mem _
· exact subset_span (by simp [hnj])
| zero => simp
| add x _ y _ hx hy => rw [map_add]; exact add_mem hx hy
| smul a x _ hx => rw [map_smul]; exact smul_mem _ _ hx
suffices x ∈ LinearMap.range ((f.restrictScalars A).domRestrict N') by
obtain ⟨a, ha⟩ := this
exact ⟨a, Subtype.val_injective ha⟩
induction hx using span_induction with
| mem x hx =>
obtain ⟨j, rfl⟩ := hx
exact ⟨⟨nj j, subset_span (by simp)⟩, hnj j⟩
| zero => exact zero_mem _
| add x y _ _ hx hy => exact add_mem hx hy
| smul a x _ hx => exact smul_mem _ a hx