/-
Copyright (c) 2020 Johan Commelin. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johan Commelin

! This file was ported from Lean 3 source module ring_theory.finiteness
! leanprover-community/mathlib commit 1dac236edca9b4b6f5f00b1ad831e35f89472837
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Algebra.Algebra.RestrictScalars
import Mathbin.Algebra.Algebra.Subalgebra.Basic
import Mathbin.GroupTheory.Finiteness
import Mathbin.RingTheory.Ideal.Operations

/-!
# Finiteness conditions in commutative algebra

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

In this file we define a notion of finiteness that is common in commutative algebra.

## Main declarations

- `submodule.fg`, `ideal.fg`
  These express that some object is finitely generated as *submodule* over some base ring.

- `module.finite`, `ring_hom.finite`, `alg_hom.finite`
  all of these express that some object is finitely generated *as module* over some base ring.

## Main results

* `exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul` is Nakayama's lemma, in the following form:
  if N is a finitely generated submodule of an ambient R-module M and I is an ideal of R
  such that N ⊆ IN, then there exists r ∈ 1 + I such that rN = 0.

-/

open Function (Surjective)

open BigOperators

namespace Submodule

variable {R : Type _} {M : Type _} [Semiring R] [AddCommMonoid M] [Module R M]

open Set

#print Submodule.Fg /-
/-- A submodule of `M` is finitely generated if it is the span of a finite subset of `M`. -/
def Fg (N : Submodule R M) : Prop :=
  ∃ S : Finset M, Submodule.span R ↑S = N
#align submodule.fg Submodule.Fg
-/

/- warning: submodule.fg_def -> Submodule.fg_def is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {N : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3}, Iff (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) (Exists.{succ u2} (Set.{u2} M) (fun (S : Set.{u2} M) => And (Set.Finite.{u2} M S) (Eq.{succ u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.span.{u1, u2} R M _inst_1 _inst_2 _inst_3 S) N)))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {N : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3}, Iff (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 N) (Exists.{succ u1} (Set.{u1} M) (fun (S : Set.{u1} M) => And (Set.Finite.{u1} M S) (Eq.{succ u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.span.{u2, u1} R M _inst_1 _inst_2 _inst_3 S) N)))
Case conversion may be inaccurate. Consider using '#align submodule.fg_def Submodule.fg_defₓ'. -/
theorem fg_def {N : Submodule R M} : N.Fg ↔ ∃ S : Set M, S.Finite ∧ span R S = N :=
  ⟨fun ⟨t, h⟩ => ⟨_, Finset.finite_toSet t, h⟩,
    by
    rintro ⟨t', h, rfl⟩
    rcases finite.exists_finset_coe h with ⟨t, rfl⟩
    exact ⟨t, rfl⟩⟩
#align submodule.fg_def Submodule.fg_def

#print Submodule.fg_iff_addSubmonoid_fg /-
theorem fg_iff_addSubmonoid_fg (P : Submodule ℕ M) : P.Fg ↔ P.toAddSubmonoid.Fg :=
  ⟨fun ⟨S, hS⟩ => ⟨S, by simpa [← span_nat_eq_add_submonoid_closure] using hS⟩, fun ⟨S, hS⟩ =>
    ⟨S, by simpa [← span_nat_eq_add_submonoid_closure] using hS⟩⟩
#align submodule.fg_iff_add_submonoid_fg Submodule.fg_iff_addSubmonoid_fg
-/

/- warning: submodule.fg_iff_add_subgroup_fg -> Submodule.fg_iff_add_subgroup_fg is a dubious translation:
lean 3 declaration is
  forall {G : Type.{u1}} [_inst_4 : AddCommGroup.{u1} G] (P : Submodule.{0, u1} Int G Int.semiring (AddCommGroup.toAddCommMonoid.{u1} G _inst_4) (AddCommGroup.intModule.{u1} G _inst_4)), Iff (Submodule.Fg.{0, u1} Int G Int.semiring (AddCommGroup.toAddCommMonoid.{u1} G _inst_4) (AddCommGroup.intModule.{u1} G _inst_4) P) (AddSubgroup.Fg.{u1} G (AddCommGroup.toAddGroup.{u1} G _inst_4) (Submodule.toAddSubgroup.{0, u1} Int G Int.ring _inst_4 (AddCommGroup.intModule.{u1} G _inst_4) P))
but is expected to have type
  forall {G : Type.{u1}} [_inst_4 : AddCommGroup.{u1} G] (P : Submodule.{0, u1} Int G Int.instSemiringInt (AddCommGroup.toAddCommMonoid.{u1} G _inst_4) (AddCommGroup.intModule.{u1} G _inst_4)), Iff (Submodule.Fg.{0, u1} Int G Int.instSemiringInt (AddCommGroup.toAddCommMonoid.{u1} G _inst_4) (AddCommGroup.intModule.{u1} G _inst_4) P) (AddSubgroup.Fg.{u1} G (AddCommGroup.toAddGroup.{u1} G _inst_4) (Submodule.toAddSubgroup.{0, u1} Int G Int.instRingInt _inst_4 (AddCommGroup.intModule.{u1} G _inst_4) P))
Case conversion may be inaccurate. Consider using '#align submodule.fg_iff_add_subgroup_fg Submodule.fg_iff_add_subgroup_fgₓ'. -/
theorem fg_iff_add_subgroup_fg {G : Type _} [AddCommGroup G] (P : Submodule ℤ G) :
    P.Fg ↔ P.toAddSubgroup.Fg :=
  ⟨fun ⟨S, hS⟩ => ⟨S, by simpa [← span_int_eq_add_subgroup_closure] using hS⟩, fun ⟨S, hS⟩ =>
    ⟨S, by simpa [← span_int_eq_add_subgroup_closure] using hS⟩⟩
#align submodule.fg_iff_add_subgroup_fg Submodule.fg_iff_add_subgroup_fg

/- warning: submodule.fg_iff_exists_fin_generating_family -> Submodule.fg_iff_exists_fin_generating_family is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {N : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3}, Iff (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) (Exists.{1} Nat (fun (n : Nat) => Exists.{succ u2} ((Fin n) -> M) (fun (s : (Fin n) -> M) => Eq.{succ u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.span.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Set.range.{u2, 1} M (Fin n) s)) N)))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {N : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3}, Iff (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 N) (Exists.{1} Nat (fun (n : Nat) => Exists.{succ u1} ((Fin n) -> M) (fun (s : (Fin n) -> M) => Eq.{succ u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.span.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Set.range.{u1, 1} M (Fin n) s)) N)))
Case conversion may be inaccurate. Consider using '#align submodule.fg_iff_exists_fin_generating_family Submodule.fg_iff_exists_fin_generating_familyₓ'. -/
theorem fg_iff_exists_fin_generating_family {N : Submodule R M} :
    N.Fg ↔ ∃ (n : ℕ)(s : Fin n → M), span R (range s) = N :=
  by
  rw [fg_def]
  constructor
  · rintro ⟨S, Sfin, hS⟩
    obtain ⟨n, f, rfl⟩ := Sfin.fin_embedding
    exact ⟨n, f, hS⟩
  · rintro ⟨n, s, hs⟩
    refine' ⟨range s, finite_range s, hs⟩
#align submodule.fg_iff_exists_fin_generating_family Submodule.fg_iff_exists_fin_generating_family

/- warning: submodule.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul -> Submodule.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_4 : CommRing.{u1} R] {M : Type.{u2}} [_inst_5 : AddCommGroup.{u2} M] [_inst_6 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)] (I : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6), (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6 N) -> (LE.le.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (Preorder.toLE.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (Submodule.completeLattice.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6))))) N (SMul.smul.{u1, u2} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (Submodule.hasSmul'.{u1, u2} R M (CommRing.toCommSemiring.{u1} R _inst_4) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) I N)) -> (Exists.{succ u1} R (fun (r : R) => And (Membership.Mem.{u1, u1} R (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (SetLike.hasMem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (Submodule.setLike.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))))) (HSub.hSub.{u1, u1, u1} R R R (instHSub.{u1} R (SubNegMonoid.toHasSub.{u1} R (AddGroup.toSubNegMonoid.{u1} R (AddGroupWithOne.toAddGroup.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R (CommRing.toRing.{u1} R _inst_4))))))) r (OfNat.ofNat.{u1} R 1 (OfNat.mk.{u1} R 1 (One.one.{u1} R (AddMonoidWithOne.toOne.{u1} R (AddGroupWithOne.toAddMonoidWithOne.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R (CommRing.toRing.{u1} R _inst_4))))))))) I) (forall (n : M), (Membership.Mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (SetLike.hasMem.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6)) n N) -> (Eq.{succ u2} M (SMul.smul.{u1, u2} R M (SMulZeroClass.toHasSmul.{u1, u2} R M (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (AddCommMonoid.toAddMonoid.{u2} M (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)))) (SMulWithZero.toSmulZeroClass.{u1, u2} R M (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)))))) (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (AddCommMonoid.toAddMonoid.{u2} M (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)))) (MulActionWithZero.toSMulWithZero.{u1, u2} R M (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (AddCommMonoid.toAddMonoid.{u2} M (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)))) (Module.toMulActionWithZero.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6)))) r n) (OfNat.ofNat.{u2} M 0 (OfNat.mk.{u2} M 0 (Zero.zero.{u2} M (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (SubNegMonoid.toAddMonoid.{u2} M (AddGroup.toSubNegMonoid.{u2} M (AddCommGroup.toAddGroup.{u2} M _inst_5))))))))))))
but is expected to have type
  forall {R : Type.{u2}} [_inst_4 : CommRing.{u2} R] {M : Type.{u1}} [_inst_5 : AddCommGroup.{u1} M] [_inst_6 : Module.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5)] (I : Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (N : Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6), (Submodule.Fg.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6 N) -> (LE.le.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Preorder.toLE.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (PartialOrder.toPreorder.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Submodule.completeLattice.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6))))) N (HSMul.hSMul.{u2, u1, u1} (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (instHSMul.{u2, u1} (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Submodule.hasSmul'.{u2, u1} R M (CommRing.toCommSemiring.{u2} R _inst_4) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6)) I N)) -> (Exists.{succ u2} R (fun (r : R) => And (Membership.mem.{u2, u2} R (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (SetLike.instMembership.{u2, u2} (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) R (Submodule.setLike.{u2, u2} R R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))))) (Semiring.toModule.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))))) (HSub.hSub.{u2, u2, u2} R R R (instHSub.{u2} R (Ring.toSub.{u2} R (CommRing.toRing.{u2} R _inst_4))) r (OfNat.ofNat.{u2} R 1 (One.toOfNat1.{u2} R (NonAssocRing.toOne.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_4)))))) I) (forall (n : M), (Membership.mem.{u1, u1} M (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (SetLike.instMembership.{u1, u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) M (Submodule.setLike.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6)) n N) -> (Eq.{succ u1} M (HSMul.hSMul.{u2, u1, u1} R M M (instHSMul.{u2, u1} R M (SMulZeroClass.toSMul.{u2, u1} R M (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5))))) (SMulWithZero.toSMulZeroClass.{u2, u1} R M (CommMonoidWithZero.toZero.{u2} R (CommSemiring.toCommMonoidWithZero.{u2} R (CommRing.toCommSemiring.{u2} R _inst_4))) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5))))) (MulActionWithZero.toSMulWithZero.{u2, u1} R M (Semiring.toMonoidWithZero.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5))))) (Module.toMulActionWithZero.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6))))) r n) (OfNat.ofNat.{u1} M 0 (Zero.toOfNat0.{u1} M (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5)))))))))))
Case conversion may be inaccurate. Consider using '#align submodule.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul Submodule.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smulₓ'. -/
/-- **Nakayama's Lemma**. Atiyah-Macdonald 2.5, Eisenbud 4.7, Matsumura 2.2,
[Stacks 00DV](https://stacks.math.columbia.edu/tag/00DV) -/
theorem exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul {R : Type _} [CommRing R] {M : Type _}
    [AddCommGroup M] [Module R M] (I : Ideal R) (N : Submodule R M) (hn : N.Fg) (hin : N ≤ I • N) :
    ∃ r : R, r - 1 ∈ I ∧ ∀ n ∈ N, r • n = (0 : M) :=
  by
  rw [fg_def] at hn
  rcases hn with ⟨s, hfs, hs⟩
  have : ∃ r : R, r - 1 ∈ I ∧ N ≤ (I • span R s).comap (LinearMap.lsmul R M r) ∧ s ⊆ N :=
    by
    refine' ⟨1, _, _, _⟩
    · rw [sub_self]
      exact I.zero_mem
    · rw [hs]
      intro n hn
      rw [mem_comap]
      change (1 : R) • n ∈ I • N
      rw [one_smul]
      exact hin hn
    · rw [← span_le, hs]
      exact le_refl N
  clear hin hs
  revert this
  refine' Set.Finite.dinduction_on hfs (fun H => _) fun i s his hfs ih H => _
  · rcases H with ⟨r, hr1, hrn, hs⟩
    refine' ⟨r, hr1, fun n hn => _⟩
    specialize hrn hn
    rwa [mem_comap, span_empty, smul_bot, mem_bot] at hrn
  apply ih
  rcases H with ⟨r, hr1, hrn, hs⟩
  rw [← Set.singleton_union, span_union, smul_sup] at hrn
  rw [Set.insert_subset] at hs
  have : ∃ c : R, c - 1 ∈ I ∧ c • i ∈ I • span R s :=
    by
    specialize hrn hs.1
    rw [mem_comap, mem_sup] at hrn
    rcases hrn with ⟨y, hy, z, hz, hyz⟩
    change y + z = r • i at hyz
    rw [mem_smul_span_singleton] at hy
    rcases hy with ⟨c, hci, rfl⟩
    use r - c
    constructor
    · rw [sub_right_comm]
      exact I.sub_mem hr1 hci
    · rw [sub_smul, ← hyz, add_sub_cancel']
      exact hz
  rcases this with ⟨c, hc1, hci⟩
  refine' ⟨c * r, _, _, hs.2⟩
  · simpa only [mul_sub, mul_one, sub_add_sub_cancel] using I.add_mem (I.mul_mem_left c hr1) hc1
  · intro n hn
    specialize hrn hn
    rw [mem_comap, mem_sup] at hrn
    rcases hrn with ⟨y, hy, z, hz, hyz⟩
    change y + z = r • n at hyz
    rw [mem_smul_span_singleton] at hy
    rcases hy with ⟨d, hdi, rfl⟩
    change _ • _ ∈ I • span R s
    rw [mul_smul, ← hyz, smul_add, smul_smul, mul_comm, mul_smul]
    exact add_mem (smul_mem _ _ hci) (smul_mem _ _ hz)
#align submodule.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul Submodule.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul

/- warning: submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul -> Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_4 : CommRing.{u1} R] {M : Type.{u2}} [_inst_5 : AddCommGroup.{u2} M] [_inst_6 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)] (I : Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6), (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6 N) -> (LE.le.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (Preorder.toLE.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (Submodule.completeLattice.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6))))) N (SMul.smul.{u1, u2} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (Submodule.hasSmul'.{u1, u2} R M (CommRing.toCommSemiring.{u1} R _inst_4) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) I N)) -> (Exists.{succ u1} R (fun (r : R) => Exists.{0} (Membership.Mem.{u1, u1} R (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (SetLike.hasMem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (Submodule.setLike.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))))) r I) (fun (H : Membership.Mem.{u1, u1} R (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (SetLike.hasMem.{u1, u1} (Ideal.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) R (Submodule.setLike.{u1, u1} R R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))))) (Semiring.toModule.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))))) r I) => forall (n : M), (Membership.Mem.{u2, u2} M (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) (SetLike.hasMem.{u2, u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6) M (Submodule.setLike.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6)) n N) -> (Eq.{succ u2} M (SMul.smul.{u1, u2} R M (SMulZeroClass.toHasSmul.{u1, u2} R M (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (AddCommMonoid.toAddMonoid.{u2} M (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)))) (SMulWithZero.toSmulZeroClass.{u1, u2} R M (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)))))) (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (AddCommMonoid.toAddMonoid.{u2} M (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)))) (MulActionWithZero.toSMulWithZero.{u1, u2} R M (Semiring.toMonoidWithZero.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4))) (AddZeroClass.toHasZero.{u2} M (AddMonoid.toAddZeroClass.{u2} M (AddCommMonoid.toAddMonoid.{u2} M (AddCommGroup.toAddCommMonoid.{u2} M _inst_5)))) (Module.toMulActionWithZero.{u1, u2} R M (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u2} M _inst_5) _inst_6)))) r n) n))))
but is expected to have type
  forall {R : Type.{u2}} [_inst_4 : CommRing.{u2} R] {M : Type.{u1}} [_inst_5 : AddCommGroup.{u1} M] [_inst_6 : Module.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5)] (I : Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (N : Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6), (Submodule.Fg.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6 N) -> (LE.le.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Preorder.toLE.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (PartialOrder.toPreorder.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Submodule.completeLattice.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6))))) N (HSMul.hSMul.{u2, u1, u1} (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (instHSMul.{u2, u1} (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (Submodule.hasSmul'.{u2, u1} R M (CommRing.toCommSemiring.{u2} R _inst_4) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6)) I N)) -> (Exists.{succ u2} R (fun (r : R) => And (Membership.mem.{u2, u2} R (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (SetLike.instMembership.{u2, u2} (Ideal.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) R (Submodule.setLike.{u2, u2} R R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))))) (Semiring.toModule.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))))) r I) (forall (n : M), (Membership.mem.{u1, u1} M (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) (SetLike.instMembership.{u1, u1} (Submodule.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6) M (Submodule.setLike.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6)) n N) -> (Eq.{succ u1} M (HSMul.hSMul.{u2, u1, u1} R M M (instHSMul.{u2, u1} R M (SMulZeroClass.toSMul.{u2, u1} R M (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5))))) (SMulWithZero.toSMulZeroClass.{u2, u1} R M (CommMonoidWithZero.toZero.{u2} R (CommSemiring.toCommMonoidWithZero.{u2} R (CommRing.toCommSemiring.{u2} R _inst_4))) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5))))) (MulActionWithZero.toSMulWithZero.{u2, u1} R M (Semiring.toMonoidWithZero.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4))) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_5))))) (Module.toMulActionWithZero.{u2, u1} R M (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_4)) (AddCommGroup.toAddCommMonoid.{u1} M _inst_5) _inst_6))))) r n) n))))
Case conversion may be inaccurate. Consider using '#align submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smulₓ'. -/
theorem exists_mem_and_smul_eq_self_of_fg_of_le_smul {R : Type _} [CommRing R] {M : Type _}
    [AddCommGroup M] [Module R M] (I : Ideal R) (N : Submodule R M) (hn : N.Fg) (hin : N ≤ I • N) :
    ∃ r ∈ I, ∀ n ∈ N, r • n = n :=
  by
  obtain ⟨r, hr, hr'⟩ := N.exists_sub_one_mem_and_smul_eq_zero_of_fg_of_le_smul I hn hin
  exact ⟨-(r - 1), I.neg_mem hr, fun n hn => by simpa [sub_smul] using hr' n hn⟩
#align submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul Submodule.exists_mem_and_smul_eq_self_of_fg_of_le_smul

/- warning: submodule.fg_bot -> Submodule.fg_bot is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2], Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Bot.bot.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.hasBot.{u1, u2} R M _inst_1 _inst_2 _inst_3))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2], Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Bot.bot.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.instBotSubmodule.{u2, u1} R M _inst_1 _inst_2 _inst_3))
Case conversion may be inaccurate. Consider using '#align submodule.fg_bot Submodule.fg_botₓ'. -/
theorem fg_bot : (⊥ : Submodule R M).Fg :=
  ⟨∅, by rw [Finset.coe_empty, span_empty]⟩
#align submodule.fg_bot Submodule.fg_bot

/- warning: subalgebra.fg_bot_to_submodule -> Subalgebra.fg_bot_toSubmodule is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} [_inst_4 : CommSemiring.{u1} R] [_inst_5 : Semiring.{u2} A] [_inst_6 : Algebra.{u1, u2} R A _inst_4 _inst_5], Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6) (coeFn.{succ u2, succ u2} (OrderEmbedding.{u2, u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Preorder.toLE.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (PartialOrder.toPreorder.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (SetLike.partialOrder.{u2, u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) A (Subalgebra.setLike.{u1, u2} R A _inst_4 _inst_5 _inst_6)))) (Preorder.toLE.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.completeLattice.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6))))))) (fun (_x : RelEmbedding.{u2, u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (LE.le.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Preorder.toLE.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (PartialOrder.toPreorder.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (SetLike.partialOrder.{u2, u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) A (Subalgebra.setLike.{u1, u2} R A _inst_4 _inst_5 _inst_6))))) (LE.le.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Preorder.toLE.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.completeLattice.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)))))))) => (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) -> (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6))) (RelEmbedding.hasCoeToFun.{u2, u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (LE.le.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Preorder.toLE.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (PartialOrder.toPreorder.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (SetLike.partialOrder.{u2, u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) A (Subalgebra.setLike.{u1, u2} R A _inst_4 _inst_5 _inst_6))))) (LE.le.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Preorder.toLE.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.completeLattice.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)))))))) (Subalgebra.toSubmodule.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Bot.bot.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (CompleteLattice.toHasBot.{u2} (Subalgebra.{u1, u2} R A _inst_4 _inst_5 _inst_6) (Algebra.Subalgebra.completeLattice.{u1, u2} R A _inst_4 _inst_5 _inst_6))))
but is expected to have type
  forall {R : Type.{u2}} {A : Type.{u1}} [_inst_4 : CommSemiring.{u2} R] [_inst_5 : Semiring.{u1} A] [_inst_6 : Algebra.{u2, u1} R A _inst_4 _inst_5], Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6) (FunLike.coe.{succ u1, succ u1, succ u1} (Function.Embedding.{succ u1, succ u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6))) (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (fun (_x : Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) => (fun (x._@.Mathlib.Data.FunLike.Embedding._hyg.19 : Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) => Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) _x) (EmbeddingLike.toFunLike.{succ u1, succ u1, succ u1} (Function.Embedding.{succ u1, succ u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6))) (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Function.instEmbeddingLikeEmbedding.{succ u1, succ u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)))) (RelEmbedding.toEmbedding.{u1, u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (fun (x._@.Mathlib.Order.Hom.Basic._hyg.680 : Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (x._@.Mathlib.Order.Hom.Basic._hyg.682 : Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) => LE.le.{u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Preorder.toLE.{u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (PartialOrder.toPreorder.{u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (SetLike.instPartialOrder.{u1, u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) A (Subalgebra.instSetLikeSubalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6)))) x._@.Mathlib.Order.Hom.Basic._hyg.680 x._@.Mathlib.Order.Hom.Basic._hyg.682) (fun (x._@.Mathlib.Order.Hom.Basic._hyg.695 : Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (x._@.Mathlib.Order.Hom.Basic._hyg.697 : Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) => LE.le.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Preorder.toLE.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (PartialOrder.toPreorder.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Submodule.completeLattice.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)))))) x._@.Mathlib.Order.Hom.Basic._hyg.695 x._@.Mathlib.Order.Hom.Basic._hyg.697) (Subalgebra.toSubmodule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Bot.bot.{u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (CompleteLattice.toBot.{u1} (Subalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Algebra.instCompleteLatticeSubalgebra.{u2, u1} R A _inst_4 _inst_5 _inst_6))))
Case conversion may be inaccurate. Consider using '#align subalgebra.fg_bot_to_submodule Subalgebra.fg_bot_toSubmoduleₓ'. -/
theorem Subalgebra.fg_bot_toSubmodule {R A : Type _} [CommSemiring R] [Semiring A] [Algebra R A] :
    (⊥ : Subalgebra R A).toSubmodule.Fg :=
  ⟨{1}, by simp [Algebra.toSubmodule_bot]⟩
#align subalgebra.fg_bot_to_submodule Subalgebra.fg_bot_toSubmodule

/- warning: submodule.fg_unit -> Submodule.fg_unit is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} [_inst_4 : CommSemiring.{u1} R] [_inst_5 : Semiring.{u2} A] [_inst_6 : Algebra.{u1, u2} R A _inst_4 _inst_5] (I : Units.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6))))), Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6) ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6))))) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6))))) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6))))) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (coeBase.{succ u2, succ u2} (Units.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6))))) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Units.hasCoe.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6)))))))) I)
but is expected to have type
  forall {R : Type.{u2}} {A : Type.{u1}} [_inst_4 : CommSemiring.{u2} R] [_inst_5 : Semiring.{u1} A] [_inst_6 : Algebra.{u2, u1} R A _inst_4 _inst_5] (I : Units.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u2, u1} R _inst_4 A _inst_5 _inst_6))))), Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6) (Units.val.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u2, u1} R _inst_4 A _inst_5 _inst_6)))) I)
Case conversion may be inaccurate. Consider using '#align submodule.fg_unit Submodule.fg_unitₓ'. -/
theorem fg_unit {R A : Type _} [CommSemiring R] [Semiring A] [Algebra R A] (I : (Submodule R A)ˣ) :
    (I : Submodule R A).Fg :=
  by
  have : (1 : A) ∈ (I * ↑I⁻¹ : Submodule R A) :=
    by
    rw [I.mul_inv]
    exact one_le.mp le_rfl
  obtain ⟨T, T', hT, hT', one_mem⟩ := mem_span_mul_finite_of_mem_mul this
  refine' ⟨T, span_eq_of_le _ hT _⟩
  rw [← one_mul ↑I, ← mul_one (span R ↑T)]
  conv_rhs => rw [← I.inv_mul, ← mul_assoc]
  refine' mul_le_mul_left (le_trans _ <| mul_le_mul_right <| span_le.mpr hT')
  rwa [one_le, span_mul_span]
#align submodule.fg_unit Submodule.fg_unit

/- warning: submodule.fg_of_is_unit -> Submodule.fg_of_isUnit is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} [_inst_4 : CommSemiring.{u1} R] [_inst_5 : Semiring.{u2} A] [_inst_6 : Algebra.{u1, u2} R A _inst_4 _inst_5] {I : Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)}, (IsUnit.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u1, u2} R _inst_4 A _inst_5 _inst_6)))) I) -> (Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_5))) (Algebra.toModule.{u1, u2} R A _inst_4 _inst_5 _inst_6) I)
but is expected to have type
  forall {R : Type.{u2}} {A : Type.{u1}} [_inst_4 : CommSemiring.{u2} R] [_inst_5 : Semiring.{u1} A] [_inst_6 : Algebra.{u2, u1} R A _inst_4 _inst_5] {I : Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)}, (IsUnit.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (MonoidWithZero.toMonoid.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Semiring.toMonoidWithZero.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (IdemSemiring.toSemiring.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6)) (Submodule.idemSemiring.{u2, u1} R _inst_4 A _inst_5 _inst_6)))) I) -> (Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_4) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_5))) (Algebra.toModule.{u2, u1} R A _inst_4 _inst_5 _inst_6) I)
Case conversion may be inaccurate. Consider using '#align submodule.fg_of_is_unit Submodule.fg_of_isUnitₓ'. -/
theorem fg_of_isUnit {R A : Type _} [CommSemiring R] [Semiring A] [Algebra R A] {I : Submodule R A}
    (hI : IsUnit I) : I.Fg :=
  fg_unit hI.Unit
#align submodule.fg_of_is_unit Submodule.fg_of_isUnit

#print Submodule.fg_span /-
theorem fg_span {s : Set M} (hs : s.Finite) : Fg (span R s) :=
  ⟨hs.toFinset, by rw [hs.coe_to_finset]⟩
#align submodule.fg_span Submodule.fg_span
-/

/- warning: submodule.fg_span_singleton -> Submodule.fg_span_singleton is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] (x : M), Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Submodule.span.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Singleton.singleton.{u2, u2} M (Set.{u2} M) (Set.hasSingleton.{u2} M) x))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] (x : M), Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Submodule.span.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Singleton.singleton.{u1, u1} M (Set.{u1} M) (Set.instSingletonSet.{u1} M) x))
Case conversion may be inaccurate. Consider using '#align submodule.fg_span_singleton Submodule.fg_span_singletonₓ'. -/
theorem fg_span_singleton (x : M) : Fg (R ∙ x) :=
  fg_span (finite_singleton x)
#align submodule.fg_span_singleton Submodule.fg_span_singleton

/- warning: submodule.fg.sup -> Submodule.Fg.sup is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {N₁ : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3} {N₂ : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N₁) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N₂) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Sup.sup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (SemilatticeSup.toHasSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Lattice.toSemilatticeSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) N₁ N₂))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {N₁ : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3} {N₂ : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 N₁) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 N₂) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Sup.sup.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (SemilatticeSup.toSup.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Lattice.toSemilatticeSup.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3))))) N₁ N₂))
Case conversion may be inaccurate. Consider using '#align submodule.fg.sup Submodule.Fg.supₓ'. -/
theorem Fg.sup {N₁ N₂ : Submodule R M} (hN₁ : N₁.Fg) (hN₂ : N₂.Fg) : (N₁ ⊔ N₂).Fg :=
  let ⟨t₁, ht₁⟩ := fg_def.1 hN₁
  let ⟨t₂, ht₂⟩ := fg_def.1 hN₂
  fg_def.2 ⟨t₁ ∪ t₂, ht₁.1.union ht₂.1, by rw [span_union, ht₁.2, ht₂.2]⟩
#align submodule.fg.sup Submodule.Fg.sup

/- warning: submodule.fg_finset_sup -> Submodule.fg_finset_sup is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {ι : Type.{u3}} (s : Finset.{u3} ι) (N : ι -> (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3)), (forall (i : ι), (Membership.Mem.{u3, u3} ι (Finset.{u3} ι) (Finset.hasMem.{u3} ι) i s) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (N i))) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Finset.sup.{u2, u3} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) ι (Lattice.toSemilatticeSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3)))) (Submodule.orderBot.{u1, u2} R M _inst_1 _inst_2 _inst_3) s N))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {ι : Type.{u3}} (s : Finset.{u3} ι) (N : ι -> (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3)), (forall (i : ι), (Membership.mem.{u3, u3} ι (Finset.{u3} ι) (Finset.instMembershipFinset.{u3} ι) i s) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (N i))) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Finset.sup.{u1, u3} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) ι (Lattice.toSemilatticeSup.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3)))) (Submodule.instOrderBotSubmoduleToLEToPreorderInstPartialOrderSetLike.{u2, u1} R M _inst_1 _inst_2 _inst_3) s N))
Case conversion may be inaccurate. Consider using '#align submodule.fg_finset_sup Submodule.fg_finset_supₓ'. -/
theorem fg_finset_sup {ι : Type _} (s : Finset ι) (N : ι → Submodule R M) (h : ∀ i ∈ s, (N i).Fg) :
    (s.sup N).Fg :=
  Finset.sup_induction fg_bot (fun a ha b hb => ha.sup hb) h
#align submodule.fg_finset_sup Submodule.fg_finset_sup

/- warning: submodule.fg_bsupr -> Submodule.fg_bsupr is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {ι : Type.{u3}} (s : Finset.{u3} ι) (N : ι -> (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3)), (forall (i : ι), (Membership.Mem.{u3, u3} ι (Finset.{u3} ι) (Finset.hasMem.{u3} ι) i s) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (N i))) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (supᵢ.{u2, succ u3} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toHasSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))) ι (fun (i : ι) => supᵢ.{u2, 0} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toHasSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))) (Membership.Mem.{u3, u3} ι (Finset.{u3} ι) (Finset.hasMem.{u3} ι) i s) (fun (H : Membership.Mem.{u3, u3} ι (Finset.{u3} ι) (Finset.hasMem.{u3} ι) i s) => N i))))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {ι : Type.{u3}} (s : Finset.{u3} ι) (N : ι -> (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3)), (forall (i : ι), (Membership.mem.{u3, u3} ι (Finset.{u3} ι) (Finset.instMembershipFinset.{u3} ι) i s) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (N i))) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (supᵢ.{u1, succ u3} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toSupSet.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3))) ι (fun (i : ι) => supᵢ.{u1, 0} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toSupSet.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3))) (Membership.mem.{u3, u3} ι (Finset.{u3} ι) (Finset.instMembershipFinset.{u3} ι) i s) (fun (H : Membership.mem.{u3, u3} ι (Finset.{u3} ι) (Finset.instMembershipFinset.{u3} ι) i s) => N i))))
Case conversion may be inaccurate. Consider using '#align submodule.fg_bsupr Submodule.fg_bsuprₓ'. -/
theorem fg_bsupr {ι : Type _} (s : Finset ι) (N : ι → Submodule R M) (h : ∀ i ∈ s, (N i).Fg) :
    (⨆ i ∈ s, N i).Fg := by simpa only [Finset.sup_eq_supᵢ] using fg_finset_sup s N h
#align submodule.fg_bsupr Submodule.fg_bsupr

/- warning: submodule.fg_supr -> Submodule.fg_supᵢ is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {ι : Type.{u3}} [_inst_4 : Finite.{succ u3} ι] (N : ι -> (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3)), (forall (i : ι), Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (N i)) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (supᵢ.{u2, succ u3} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toHasSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))) ι N))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {ι : Type.{u3}} [_inst_4 : Finite.{succ u3} ι] (N : ι -> (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3)), (forall (i : ι), Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (N i)) -> (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 (supᵢ.{u1, succ u3} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toSupSet.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3))) ι N))
Case conversion may be inaccurate. Consider using '#align submodule.fg_supr Submodule.fg_supᵢₓ'. -/
theorem fg_supᵢ {ι : Type _} [Finite ι] (N : ι → Submodule R M) (h : ∀ i, (N i).Fg) : (supᵢ N).Fg :=
  by
  cases nonempty_fintype ι
  simpa using fg_bsupr Finset.univ N fun i hi => h i
#align submodule.fg_supr Submodule.fg_supᵢ

variable {P : Type _} [AddCommMonoid P] [Module R P]

variable (f : M →ₗ[R] P)

/- warning: submodule.fg.map -> Submodule.Fg.map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {P : Type.{u3}} [_inst_4 : AddCommMonoid.{u3} P] [_inst_5 : Module.{u1, u3} R P _inst_1 _inst_4] (f : LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) {N : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) -> (Submodule.Fg.{u1, u3} R P _inst_1 _inst_4 _inst_5 (Submodule.map.{u1, u1, u2, u3, max u2 u3} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (RingHomSurjective.ids.{u1} R _inst_1) (LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) f N))
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} [_inst_1 : Semiring.{u3} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u3, u2} R M _inst_1 _inst_2] {P : Type.{u1}} [_inst_4 : AddCommMonoid.{u1} P] [_inst_5 : Module.{u3, u1} R P _inst_1 _inst_4] (f : LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) {N : Submodule.{u3, u2} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u3, u2} R M _inst_1 _inst_2 _inst_3 N) -> (Submodule.Fg.{u3, u1} R P _inst_1 _inst_4 _inst_5 (Submodule.map.{u3, u3, u2, u1, max u2 u1} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) (RingHomSurjective.ids.{u3} R _inst_1) (LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) (LinearMap.instSemilinearMapClassLinearMap.{u3, u3, u2, u1} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1))) f N))
Case conversion may be inaccurate. Consider using '#align submodule.fg.map Submodule.Fg.mapₓ'. -/
theorem Fg.map {N : Submodule R M} (hs : N.Fg) : (N.map f).Fg :=
  let ⟨t, ht⟩ := fg_def.1 hs
  fg_def.2 ⟨f '' t, ht.1.image _, by rw [span_image, ht.2]⟩
#align submodule.fg.map Submodule.Fg.map

variable {f}

/- warning: submodule.fg_of_fg_map_injective -> Submodule.fg_of_fg_map_injective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {P : Type.{u3}} [_inst_4 : AddCommMonoid.{u3} P] [_inst_5 : Module.{u1, u3} R P _inst_1 _inst_4] (f : LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5), (Function.Injective.{succ u2, succ u3} M P (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) (fun (_x : LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) => M -> P) (LinearMap.hasCoeToFun.{u1, u1, u2, u3} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) f)) -> (forall {N : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u1, u3} R P _inst_1 _inst_4 _inst_5 (Submodule.map.{u1, u1, u2, u3, max u2 u3} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (RingHomSurjective.ids.{u1} R _inst_1) (LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) f N)) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N))
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} [_inst_1 : Semiring.{u3} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u3, u2} R M _inst_1 _inst_2] {P : Type.{u1}} [_inst_4 : AddCommMonoid.{u1} P] [_inst_5 : Module.{u3, u1} R P _inst_1 _inst_4] (f : LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5), (Function.Injective.{succ u2, succ u1} M P (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : M) => P) _x) (LinearMap.instFunLikeLinearMap.{u3, u3, u2, u1} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1))) f)) -> (forall {N : Submodule.{u3, u2} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u3, u1} R P _inst_1 _inst_4 _inst_5 (Submodule.map.{u3, u3, u2, u1, max u2 u1} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) (RingHomSurjective.ids.{u3} R _inst_1) (LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M P _inst_2 _inst_4 _inst_3 _inst_5) (LinearMap.instSemilinearMapClassLinearMap.{u3, u3, u2, u1} R R M P _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1))) f N)) -> (Submodule.Fg.{u3, u2} R M _inst_1 _inst_2 _inst_3 N))
Case conversion may be inaccurate. Consider using '#align submodule.fg_of_fg_map_injective Submodule.fg_of_fg_map_injectiveₓ'. -/
theorem fg_of_fg_map_injective (f : M →ₗ[R] P) (hf : Function.Injective f) {N : Submodule R M}
    (hfn : (N.map f).Fg) : N.Fg :=
  let ⟨t, ht⟩ := hfn
  ⟨t.Preimage f fun x _ y _ h => hf h,
    Submodule.map_injective_of_injective hf <|
      by
      rw [f.map_span, Finset.coe_preimage, Set.image_preimage_eq_inter_range,
        Set.inter_eq_self_of_subset_left, ht]
      rw [← LinearMap.range_coe, ← span_le, ht, ← map_top]
      exact map_mono le_top⟩
#align submodule.fg_of_fg_map_injective Submodule.fg_of_fg_map_injective

/- warning: submodule.fg_of_fg_map -> Submodule.fg_of_fg_map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {P : Type.{u3}} [_inst_6 : Ring.{u1} R] [_inst_7 : AddCommGroup.{u2} M] [_inst_8 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7)] [_inst_9 : AddCommGroup.{u3} P] [_inst_10 : Module.{u1, u3} R P (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9)] (f : LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10), (Eq.{succ u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) (LinearMap.ker.{u1, u1, u2, u3, max u2 u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) f) (Bot.bot.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) (Submodule.hasBot.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8))) -> (forall {N : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8}, (Submodule.Fg.{u1, u3} R P (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_10 (Submodule.map.{u1, u1, u2, u3, max u2 u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (RingHomSurjective.ids.{u1} R (Ring.toSemiring.{u1} R _inst_6)) (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) f N)) -> (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 N))
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} {P : Type.{u1}} [_inst_6 : Ring.{u3} R] [_inst_7 : AddCommGroup.{u2} M] [_inst_8 : Module.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7)] [_inst_9 : AddCommGroup.{u1} P] [_inst_10 : Module.{u3, u1} R P (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9)] (f : LinearMap.{u3, u3, u2, u1} R R (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (RingHom.id.{u3} R (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10), (Eq.{succ u2} (Submodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) (LinearMap.ker.{u3, u3, u2, u1, max u1 u2} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) (LinearMap.{u3, u3, u2, u1} R R (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10) (Submodule.instSLMC.{u3, u3, u2, u1} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6)))) f) (Bot.bot.{u2} (Submodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) (Submodule.instBotSubmodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8))) -> (forall {N : Submodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8}, (Submodule.Fg.{u3, u1} R P (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_10 (Submodule.map.{u3, u3, u2, u1, max u1 u2} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) (RingHomSurjective.ids.{u3} R (Ring.toSemiring.{u3} R _inst_6)) (LinearMap.{u3, u3, u2, u1} R R (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10) (Submodule.instSLMC.{u3, u3, u2, u1} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6)))) f N)) -> (Submodule.Fg.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 N))
Case conversion may be inaccurate. Consider using '#align submodule.fg_of_fg_map Submodule.fg_of_fg_mapₓ'. -/
theorem fg_of_fg_map {R M P : Type _} [Ring R] [AddCommGroup M] [Module R M] [AddCommGroup P]
    [Module R P] (f : M →ₗ[R] P) (hf : f.ker = ⊥) {N : Submodule R M} (hfn : (N.map f).Fg) : N.Fg :=
  fg_of_fg_map_injective f (LinearMap.ker_eq_bot.1 hf) hfn
#align submodule.fg_of_fg_map Submodule.fg_of_fg_map

/- warning: submodule.fg_top -> Submodule.fg_top is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] (N : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3), Iff (Submodule.Fg.{u1, u2} R (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) M (Submodule.setLike.{u1, u2} R M _inst_1 _inst_2 _inst_3)) N) _inst_1 (Submodule.addCommMonoid.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) (Submodule.module.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) (Top.top.{u2} (Submodule.{u1, u2} R (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) M (Submodule.setLike.{u1, u2} R M _inst_1 _inst_2 _inst_3)) N) _inst_1 (Submodule.addCommMonoid.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) (Submodule.module.{u1, u2} R M _inst_1 _inst_2 _inst_3 N)) (Submodule.hasTop.{u1, u2} R (coeSort.{succ u2, succ (succ u2)} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) Type.{u2} (SetLike.hasCoeToSort.{u2, u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) M (Submodule.setLike.{u1, u2} R M _inst_1 _inst_2 _inst_3)) N) _inst_1 (Submodule.addCommMonoid.{u1, u2} R M _inst_1 _inst_2 _inst_3 N) (Submodule.module.{u1, u2} R M _inst_1 _inst_2 _inst_3 N)))) (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 N)
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] (N : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3), Iff (Submodule.Fg.{u2, u1} R (Subtype.{succ u1} M (fun (x : M) => Membership.mem.{u1, u1} M (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (SetLike.instMembership.{u1, u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) M (Submodule.setLike.{u2, u1} R M _inst_1 _inst_2 _inst_3)) x N)) _inst_1 (Submodule.addCommMonoid.{u2, u1} R M _inst_1 _inst_2 _inst_3 N) (Submodule.module.{u2, u1} R M _inst_1 _inst_2 _inst_3 N) (Top.top.{u1} (Submodule.{u2, u1} R (Subtype.{succ u1} M (fun (x : M) => Membership.mem.{u1, u1} M (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (SetLike.instMembership.{u1, u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) M (Submodule.setLike.{u2, u1} R M _inst_1 _inst_2 _inst_3)) x N)) _inst_1 (Submodule.addCommMonoid.{u2, u1} R M _inst_1 _inst_2 _inst_3 N) (Submodule.module.{u2, u1} R M _inst_1 _inst_2 _inst_3 N)) (Submodule.instTopSubmodule.{u2, u1} R (Subtype.{succ u1} M (fun (x : M) => Membership.mem.{u1, u1} M (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (SetLike.instMembership.{u1, u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) M (Submodule.setLike.{u2, u1} R M _inst_1 _inst_2 _inst_3)) x N)) _inst_1 (Submodule.addCommMonoid.{u2, u1} R M _inst_1 _inst_2 _inst_3 N) (Submodule.module.{u2, u1} R M _inst_1 _inst_2 _inst_3 N)))) (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 N)
Case conversion may be inaccurate. Consider using '#align submodule.fg_top Submodule.fg_topₓ'. -/
theorem fg_top (N : Submodule R M) : (⊤ : Submodule R N).Fg ↔ N.Fg :=
  ⟨fun h => N.range_subtype ▸ map_top N.Subtype ▸ h.map _, fun h =>
    fg_of_fg_map_injective N.Subtype Subtype.val_injective <| by rwa [map_top, range_subtype]⟩
#align submodule.fg_top Submodule.fg_top

/- warning: submodule.fg_of_linear_equiv -> Submodule.fg_of_linearEquiv is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {P : Type.{u3}} [_inst_4 : AddCommMonoid.{u3} P] [_inst_5 : Module.{u1, u3} R P _inst_1 _inst_4], (LinearEquiv.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (RingHomInvPair.ids.{u1} R _inst_1) (RingHomInvPair.ids.{u1} R _inst_1) M P _inst_2 _inst_4 _inst_3 _inst_5) -> (Submodule.Fg.{u1, u3} R P _inst_1 _inst_4 _inst_5 (Top.top.{u3} (Submodule.{u1, u3} R P _inst_1 _inst_4 _inst_5) (Submodule.hasTop.{u1, u3} R P _inst_1 _inst_4 _inst_5))) -> (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Top.top.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.hasTop.{u1, u2} R M _inst_1 _inst_2 _inst_3)))
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} [_inst_1 : Semiring.{u3} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u3, u2} R M _inst_1 _inst_2] {P : Type.{u1}} [_inst_4 : AddCommMonoid.{u1} P] [_inst_5 : Module.{u3, u1} R P _inst_1 _inst_4], (LinearEquiv.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) (RingHomInvPair.ids.{u3} R _inst_1) (RingHomInvPair.ids.{u3} R _inst_1) M P _inst_2 _inst_4 _inst_3 _inst_5) -> (Submodule.Fg.{u3, u1} R P _inst_1 _inst_4 _inst_5 (Top.top.{u1} (Submodule.{u3, u1} R P _inst_1 _inst_4 _inst_5) (Submodule.instTopSubmodule.{u3, u1} R P _inst_1 _inst_4 _inst_5))) -> (Submodule.Fg.{u3, u2} R M _inst_1 _inst_2 _inst_3 (Top.top.{u2} (Submodule.{u3, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.instTopSubmodule.{u3, u2} R M _inst_1 _inst_2 _inst_3)))
Case conversion may be inaccurate. Consider using '#align submodule.fg_of_linear_equiv Submodule.fg_of_linearEquivₓ'. -/
theorem fg_of_linearEquiv (e : M ≃ₗ[R] P) (h : (⊤ : Submodule R P).Fg) : (⊤ : Submodule R M).Fg :=
  e.symm.range ▸ map_top (e.symm : P →ₗ[R] M) ▸ h.map _
#align submodule.fg_of_linear_equiv Submodule.fg_of_linearEquiv

/- warning: submodule.fg.prod -> Submodule.Fg.prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {P : Type.{u3}} [_inst_4 : AddCommMonoid.{u3} P] [_inst_5 : Module.{u1, u3} R P _inst_1 _inst_4] {sb : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3} {sc : Submodule.{u1, u3} R P _inst_1 _inst_4 _inst_5}, (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 sb) -> (Submodule.Fg.{u1, u3} R P _inst_1 _inst_4 _inst_5 sc) -> (Submodule.Fg.{u1, max u2 u3} R (Prod.{u2, u3} M P) _inst_1 (Prod.addCommMonoid.{u2, u3} M P _inst_2 _inst_4) (Prod.module.{u1, u2, u3} R M P _inst_1 _inst_2 _inst_4 _inst_3 _inst_5) (Submodule.prod.{u1, u2, u3} R M _inst_1 _inst_2 _inst_3 sb P _inst_4 _inst_5 sc))
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} [_inst_1 : Semiring.{u3} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u3, u2} R M _inst_1 _inst_2] {P : Type.{u1}} [_inst_4 : AddCommMonoid.{u1} P] [_inst_5 : Module.{u3, u1} R P _inst_1 _inst_4] {sb : Submodule.{u3, u2} R M _inst_1 _inst_2 _inst_3} {sc : Submodule.{u3, u1} R P _inst_1 _inst_4 _inst_5}, (Submodule.Fg.{u3, u2} R M _inst_1 _inst_2 _inst_3 sb) -> (Submodule.Fg.{u3, u1} R P _inst_1 _inst_4 _inst_5 sc) -> (Submodule.Fg.{u3, max u2 u1} R (Prod.{u2, u1} M P) _inst_1 (Prod.instAddCommMonoidSum.{u2, u1} M P _inst_2 _inst_4) (Prod.module.{u3, u2, u1} R M P _inst_1 _inst_2 _inst_4 _inst_3 _inst_5) (Submodule.prod.{u3, u2, u1} R M _inst_1 _inst_2 _inst_3 sb P _inst_4 _inst_5 sc))
Case conversion may be inaccurate. Consider using '#align submodule.fg.prod Submodule.Fg.prodₓ'. -/
theorem Fg.prod {sb : Submodule R M} {sc : Submodule R P} (hsb : sb.Fg) (hsc : sc.Fg) :
    (sb.Prod sc).Fg :=
  let ⟨tb, htb⟩ := fg_def.1 hsb
  let ⟨tc, htc⟩ := fg_def.1 hsc
  fg_def.2
    ⟨LinearMap.inl R M P '' tb ∪ LinearMap.inr R M P '' tc, (htb.1.image _).union (htc.1.image _),
      by rw [LinearMap.span_inl_union_inr, htb.2, htc.2]⟩
#align submodule.fg.prod Submodule.Fg.prod

/- warning: submodule.fg_pi -> Submodule.fg_pi is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {ι : Type.{u2}} {M : ι -> Type.{u3}} [_inst_6 : Finite.{succ u2} ι] [_inst_7 : forall (i : ι), AddCommMonoid.{u3} (M i)] [_inst_8 : forall (i : ι), Module.{u1, u3} R (M i) _inst_1 (_inst_7 i)] {p : forall (i : ι), Submodule.{u1, u3} R (M i) _inst_1 (_inst_7 i) (_inst_8 i)}, (forall (i : ι), Submodule.Fg.{u1, u3} R (M i) _inst_1 (_inst_7 i) (_inst_8 i) (p i)) -> (Submodule.Fg.{u1, max u2 u3} R (forall (i : ι), M i) _inst_1 (Pi.addCommMonoid.{u2, u3} ι (fun (i : ι) => M i) (fun (i : ι) => _inst_7 i)) (Pi.module.{u2, u3, u1} ι (fun (i : ι) => M i) R _inst_1 (fun (i : ι) => _inst_7 i) (fun (i : ι) => _inst_8 i)) (Submodule.pi.{u1, u2, u3} R ι _inst_1 (fun (i : ι) => M i) (fun (i : ι) => _inst_7 i) (fun (i : ι) => _inst_8 i) (Set.univ.{u2} ι) p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {ι : Type.{u3}} {M : ι -> Type.{u2}} [_inst_6 : Finite.{succ u3} ι] [_inst_7 : forall (i : ι), AddCommMonoid.{u2} (M i)] [_inst_8 : forall (i : ι), Module.{u1, u2} R (M i) _inst_1 (_inst_7 i)] {p : forall (i : ι), Submodule.{u1, u2} R (M i) _inst_1 (_inst_7 i) (_inst_8 i)}, (forall (i : ι), Submodule.Fg.{u1, u2} R (M i) _inst_1 (_inst_7 i) (_inst_8 i) (p i)) -> (Submodule.Fg.{u1, max u3 u2} R (forall (i : ι), M i) _inst_1 (Pi.addCommMonoid.{u3, u2} ι (fun (i : ι) => M i) (fun (i : ι) => _inst_7 i)) (Pi.module.{u3, u2, u1} ι (fun (i : ι) => M i) R _inst_1 (fun (i : ι) => _inst_7 i) (fun (i : ι) => _inst_8 i)) (Submodule.pi.{u1, u3, u2} R ι _inst_1 (fun (i : ι) => M i) (fun (i : ι) => _inst_7 i) (fun (i : ι) => _inst_8 i) (Set.univ.{u3} ι) p))
Case conversion may be inaccurate. Consider using '#align submodule.fg_pi Submodule.fg_piₓ'. -/
theorem fg_pi {ι : Type _} {M : ι → Type _} [Finite ι] [∀ i, AddCommMonoid (M i)]
    [∀ i, Module R (M i)] {p : ∀ i, Submodule R (M i)} (hsb : ∀ i, (p i).Fg) :
    (Submodule.pi Set.univ p).Fg := by
  classical
    simp_rw [fg_def] at hsb⊢
    choose t htf hts using hsb
    refine'
      ⟨⋃ i, (LinearMap.single i : _ →ₗ[R] _) '' t i, Set.finite_unionᵢ fun i => (htf i).image _, _⟩
    simp_rw [span_Union, span_image, hts, Submodule.supᵢ_map_single]
#align submodule.fg_pi Submodule.fg_pi

/- warning: submodule.fg_of_fg_map_of_fg_inf_ker -> Submodule.fg_of_fg_map_of_fg_inf_ker is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {P : Type.{u3}} [_inst_6 : Ring.{u1} R] [_inst_7 : AddCommGroup.{u2} M] [_inst_8 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7)] [_inst_9 : AddCommGroup.{u3} P] [_inst_10 : Module.{u1, u3} R P (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9)] (f : LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10) {s : Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8}, (Submodule.Fg.{u1, u3} R P (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_10 (Submodule.map.{u1, u1, u2, u3, max u2 u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (RingHomSurjective.ids.{u1} R (Ring.toSemiring.{u1} R _inst_6)) (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) f s)) -> (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 (Inf.inf.{u2} (Submodule.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) (Submodule.hasInf.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) s (LinearMap.ker.{u1, u1, u2, u3, max u2 u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) f))) -> (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 s)
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} {P : Type.{u1}} [_inst_6 : Ring.{u3} R] [_inst_7 : AddCommGroup.{u2} M] [_inst_8 : Module.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7)] [_inst_9 : AddCommGroup.{u1} P] [_inst_10 : Module.{u3, u1} R P (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9)] (f : LinearMap.{u3, u3, u2, u1} R R (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (RingHom.id.{u3} R (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10) {s : Submodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8}, (Submodule.Fg.{u3, u1} R P (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_10 (Submodule.map.{u3, u3, u2, u1, max u1 u2} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) (RingHomSurjective.ids.{u3} R (Ring.toSemiring.{u3} R _inst_6)) (LinearMap.{u3, u3, u2, u1} R R (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10) (Submodule.instSLMC.{u3, u3, u2, u1} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6)))) f s)) -> (Submodule.Fg.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 (Inf.inf.{u2} (Submodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) (Submodule.instInfSubmodule.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8) s (LinearMap.ker.{u3, u3, u2, u1, max u1 u2} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) (LinearMap.{u3, u3, u2, u1} R R (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10) (Submodule.instSLMC.{u3, u3, u2, u1} R R M P (Ring.toSemiring.{u3} R _inst_6) (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_9) _inst_8 _inst_10 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R (Ring.toSemiring.{u3} R _inst_6)))) f))) -> (Submodule.Fg.{u3, u2} R M (Ring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 s)
Case conversion may be inaccurate. Consider using '#align submodule.fg_of_fg_map_of_fg_inf_ker Submodule.fg_of_fg_map_of_fg_inf_kerₓ'. -/
/-- If 0 → M' → M → M'' → 0 is exact and M' and M'' are
finitely generated then so is M. -/
theorem fg_of_fg_map_of_fg_inf_ker {R M P : Type _} [Ring R] [AddCommGroup M] [Module R M]
    [AddCommGroup P] [Module R P] (f : M →ₗ[R] P) {s : Submodule R M} (hs1 : (s.map f).Fg)
    (hs2 : (s ⊓ f.ker).Fg) : s.Fg :=
  by
  haveI := Classical.decEq R
  haveI := Classical.decEq M
  haveI := Classical.decEq P
  cases' hs1 with t1 ht1
  cases' hs2 with t2 ht2
  have : ∀ y ∈ t1, ∃ x ∈ s, f x = y := by
    intro y hy
    have : y ∈ map f s := by
      rw [← ht1]
      exact subset_span hy
    rcases mem_map.1 this with ⟨x, hx1, hx2⟩
    exact ⟨x, hx1, hx2⟩
  have : ∃ g : P → M, ∀ y ∈ t1, g y ∈ s ∧ f (g y) = y :=
    by
    choose g hg1 hg2
    exists fun y => if H : y ∈ t1 then g y H else 0
    intro y H
    constructor
    · simp only [dif_pos H]
      apply hg1
    · simp only [dif_pos H]
      apply hg2
  cases' this with g hg
  clear this
  exists t1.image g ∪ t2
  rw [Finset.coe_union, span_union, Finset.coe_image]
  apply le_antisymm
  · refine' sup_le (span_le.2 <| image_subset_iff.2 _) (span_le.2 _)
    · intro y hy
      exact (hg y hy).1
    · intro x hx
      have := subset_span hx
      rw [ht2] at this
      exact this.1
  intro x hx
  have : f x ∈ map f s := by
    rw [mem_map]
    exact ⟨x, hx, rfl⟩
  rw [← ht1, ← Set.image_id ↑t1, Finsupp.mem_span_image_iff_total] at this
  rcases this with ⟨l, hl1, hl2⟩
  refine'
    mem_sup.2
      ⟨(Finsupp.total M M R id).toFun ((Finsupp.lmapDomain R R g : (P →₀ R) → M →₀ R) l), _,
        x - Finsupp.total M M R id ((Finsupp.lmapDomain R R g : (P →₀ R) → M →₀ R) l), _,
        add_sub_cancel'_right _ _⟩
  · rw [← Set.image_id (g '' ↑t1), Finsupp.mem_span_image_iff_total]
    refine' ⟨_, _, rfl⟩
    haveI : Inhabited P := ⟨0⟩
    rw [← Finsupp.lmapDomain_supported _ _ g, mem_map]
    refine' ⟨l, hl1, _⟩
    rfl
  rw [ht2, mem_inf]
  constructor
  · apply s.sub_mem hx
    rw [Finsupp.total_apply, Finsupp.lmapDomain_apply, Finsupp.sum_mapDomain_index]
    refine' s.sum_mem _
    · intro y hy
      exact s.smul_mem _ (hg y (hl1 hy)).1
    · exact zero_smul _
    · exact fun _ _ _ => add_smul _ _ _
  · rw [LinearMap.mem_ker, f.map_sub, ← hl2]
    rw [Finsupp.total_apply, Finsupp.total_apply, Finsupp.lmapDomain_apply]
    rw [Finsupp.sum_mapDomain_index, Finsupp.sum, Finsupp.sum, f.map_sum]
    rw [sub_eq_zero]
    refine' Finset.sum_congr rfl fun y hy => _
    unfold id
    rw [f.map_smul, (hg y (hl1 hy)).2]
    · exact zero_smul _
    · exact fun _ _ _ => add_smul _ _ _
#align submodule.fg_of_fg_map_of_fg_inf_ker Submodule.fg_of_fg_map_of_fg_inf_ker

/- warning: submodule.fg_induction -> Submodule.fg_induction is a dubious translation:
lean 3 declaration is
  forall (R : Type.{u1}) (M : Type.{u2}) [_inst_6 : Semiring.{u1} R] [_inst_7 : AddCommMonoid.{u2} M] [_inst_8 : Module.{u1, u2} R M _inst_6 _inst_7] (P : (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) -> Prop), (forall (x : M), P (Submodule.span.{u1, u2} R M _inst_6 _inst_7 _inst_8 (Singleton.singleton.{u2, u2} M (Set.{u2} M) (Set.hasSingleton.{u2} M) x))) -> (forall (M₁ : Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (M₂ : Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8), (P M₁) -> (P M₂) -> (P (Sup.sup.{u2} (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (SemilatticeSup.toHasSup.{u2} (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (Lattice.toSemilatticeSup.{u2} (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (ConditionallyCompleteLattice.toLattice.{u2} (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (Submodule.completeLattice.{u1, u2} R M _inst_6 _inst_7 _inst_8))))) M₁ M₂))) -> (forall (N : Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8), (Submodule.Fg.{u1, u2} R M _inst_6 _inst_7 _inst_8 N) -> (P N))
but is expected to have type
  forall (R : Type.{u2}) (M : Type.{u1}) [_inst_6 : Semiring.{u2} R] [_inst_7 : AddCommMonoid.{u1} M] [_inst_8 : Module.{u2, u1} R M _inst_6 _inst_7] (P : (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) -> Prop), (forall (x : M), P (Submodule.span.{u2, u1} R M _inst_6 _inst_7 _inst_8 (Singleton.singleton.{u1, u1} M (Set.{u1} M) (Set.instSingletonSet.{u1} M) x))) -> (forall (M₁ : Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (M₂ : Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8), (P M₁) -> (P M₂) -> (P (Sup.sup.{u1} (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (SemilatticeSup.toSup.{u1} (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (Lattice.toSemilatticeSup.{u1} (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (ConditionallyCompleteLattice.toLattice.{u1} (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (Submodule.completeLattice.{u2, u1} R M _inst_6 _inst_7 _inst_8))))) M₁ M₂))) -> (forall (N : Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8), (Submodule.Fg.{u2, u1} R M _inst_6 _inst_7 _inst_8 N) -> (P N))
Case conversion may be inaccurate. Consider using '#align submodule.fg_induction Submodule.fg_inductionₓ'. -/
theorem fg_induction (R M : Type _) [Semiring R] [AddCommMonoid M] [Module R M]
    (P : Submodule R M → Prop) (h₁ : ∀ x, P (Submodule.span R {x}))
    (h₂ : ∀ M₁ M₂, P M₁ → P M₂ → P (M₁ ⊔ M₂)) (N : Submodule R M) (hN : N.Fg) : P N := by
  classical
    obtain ⟨s, rfl⟩ := hN
    induction s using Finset.induction
    · rw [Finset.coe_empty, Submodule.span_empty, ← Submodule.span_zero_singleton]
      apply h₁
    · rw [Finset.coe_insert, Submodule.span_insert]
      apply h₂ <;> apply_assumption
#align submodule.fg_induction Submodule.fg_induction

/- warning: submodule.fg_ker_comp -> Submodule.fg_ker_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} {P : Type.{u4}} [_inst_6 : Ring.{u1} R] [_inst_7 : AddCommGroup.{u2} M] [_inst_8 : Module.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7)] [_inst_9 : AddCommGroup.{u3} N] [_inst_10 : Module.{u1, u3} R N (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9)] [_inst_11 : AddCommGroup.{u4} P] [_inst_12 : Module.{u1, u4} R P (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11)] (f : LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10) (g : LinearMap.{u1, u1, u3, u4} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) N P (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_10 _inst_12), (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 (LinearMap.ker.{u1, u1, u2, u3, max u2 u3} R R M N (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10) (LinearMap.semilinearMapClass.{u1, u1, u2, u3} R R M N (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) f)) -> (Submodule.Fg.{u1, u3} R N (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_10 (LinearMap.ker.{u1, u1, u3, u4, max u3 u4} R R N P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_10 _inst_12 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (LinearMap.{u1, u1, u3, u4} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) N P (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_10 _inst_12) (LinearMap.semilinearMapClass.{u1, u1, u3, u4} R R N P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_10 _inst_12 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) g)) -> (Function.Surjective.{succ u2, succ u3} M N (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10) (fun (_x : LinearMap.{u1, u1, u2, u3} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M N (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10) => M -> N) (LinearMap.hasCoeToFun.{u1, u1, u2, u3} R R M N (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) _inst_8 _inst_10 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) f)) -> (Submodule.Fg.{u1, u2} R M (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) _inst_8 (LinearMap.ker.{u1, u1, u2, u4, max u2 u4} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_8 _inst_12 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (LinearMap.{u1, u1, u2, u4} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_8 _inst_12) (LinearMap.semilinearMapClass.{u1, u1, u2, u4} R R M P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_8 _inst_12 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) (LinearMap.comp.{u1, u1, u1, u2, u3, u4} R R R M N P (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} M _inst_7) (AddCommGroup.toAddCommMonoid.{u3} N _inst_9) (AddCommGroup.toAddCommMonoid.{u4} P _inst_11) _inst_8 _inst_10 _inst_12 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6))) (RingHomCompTriple.right_ids.{u1, u1} R R (Ring.toSemiring.{u1} R _inst_6) (Ring.toSemiring.{u1} R _inst_6) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_6)))) g f)))
but is expected to have type
  forall {R : Type.{u4}} {M : Type.{u3}} {N : Type.{u2}} {P : Type.{u1}} [_inst_6 : Ring.{u4} R] [_inst_7 : AddCommGroup.{u3} M] [_inst_8 : Module.{u4, u3} R M (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7)] [_inst_9 : AddCommGroup.{u2} N] [_inst_10 : Module.{u4, u2} R N (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9)] [_inst_11 : AddCommGroup.{u1} P] [_inst_12 : Module.{u4, u1} R P (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11)] (f : LinearMap.{u4, u4, u3, u2} R R (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (RingHom.id.{u4} R (NonAssocRing.toNonAssocSemiring.{u4} R (Ring.toNonAssocRing.{u4} R _inst_6))) M N (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) _inst_8 _inst_10) (g : LinearMap.{u4, u4, u2, u1} R R (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (RingHom.id.{u4} R (NonAssocRing.toNonAssocSemiring.{u4} R (Ring.toNonAssocRing.{u4} R _inst_6))) N P (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_10 _inst_12), (Submodule.Fg.{u4, u3} R M (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) _inst_8 (LinearMap.ker.{u4, u4, u3, u2, max u2 u3} R R M N (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) _inst_8 _inst_10 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) (LinearMap.{u4, u4, u3, u2} R R (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) M N (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) _inst_8 _inst_10) (Submodule.instSLMC.{u4, u4, u3, u2} R R M N (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) _inst_8 _inst_10 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6)))) f)) -> (Submodule.Fg.{u4, u2} R N (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) _inst_10 (LinearMap.ker.{u4, u4, u2, u1, max u1 u2} R R N P (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_10 _inst_12 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) (LinearMap.{u4, u4, u2, u1} R R (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) N P (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_10 _inst_12) (Submodule.instSLMC.{u4, u4, u2, u1} R R N P (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_10 _inst_12 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6)))) g)) -> (Function.Surjective.{succ u3, succ u2} M N (Submodule.asFun.{u4, u3, u2} R M (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) _inst_8 N _inst_9 _inst_10 f)) -> (Submodule.Fg.{u4, u3} R M (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) _inst_8 (LinearMap.ker.{u4, u4, u3, u1, max u3 u1} R R M P (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_8 _inst_12 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) (LinearMap.{u4, u4, u3, u1} R R (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) M P (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_8 _inst_12) (LinearMap.instSemilinearMapClassLinearMap.{u4, u4, u3, u1} R R M P (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_8 _inst_12 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6)))) (LinearMap.comp.{u4, u4, u4, u3, u2, u1} R R R M N P (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_7) (AddCommGroup.toAddCommMonoid.{u2} N _inst_9) (AddCommGroup.toAddCommMonoid.{u1} P _inst_11) _inst_8 _inst_10 _inst_12 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6))) (RingHomCompTriple.ids.{u4, u4} R R (Ring.toSemiring.{u4} R _inst_6) (Ring.toSemiring.{u4} R _inst_6) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (Ring.toSemiring.{u4} R _inst_6)))) g f)))
Case conversion may be inaccurate. Consider using '#align submodule.fg_ker_comp Submodule.fg_ker_compₓ'. -/
/-- The kernel of the composition of two linear maps is finitely generated if both kernels are and
the first morphism is surjective. -/
theorem fg_ker_comp {R M N P : Type _} [Ring R] [AddCommGroup M] [Module R M] [AddCommGroup N]
    [Module R N] [AddCommGroup P] [Module R P] (f : M →ₗ[R] N) (g : N →ₗ[R] P) (hf1 : f.ker.Fg)
    (hf2 : g.ker.Fg) (hsur : Function.Surjective f) : (g.comp f).ker.Fg :=
  by
  rw [LinearMap.ker_comp]
  apply fg_of_fg_map_of_fg_inf_ker f
  · rwa [Submodule.map_comap_eq, LinearMap.range_eq_top.2 hsur, top_inf_eq]
  · rwa [inf_of_le_right (show f.ker ≤ comap f g.ker from comap_mono bot_le)]
#align submodule.fg_ker_comp Submodule.fg_ker_comp

/- warning: submodule.fg_restrict_scalars -> Submodule.fg_restrictScalars is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} {M : Type.{u3}} [_inst_6 : CommSemiring.{u1} R] [_inst_7 : Semiring.{u2} S] [_inst_8 : Algebra.{u1, u2} R S _inst_6 _inst_7] [_inst_9 : AddCommGroup.{u3} M] [_inst_10 : Module.{u2, u3} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)] [_inst_11 : Module.{u1, u3} R M (CommSemiring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)] [_inst_12 : IsScalarTower.{u1, u2, u3} R S M (SMulZeroClass.toHasSmul.{u1, u2} R S (AddZeroClass.toHasZero.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))))) (SMulWithZero.toSmulZeroClass.{u1, u2} R S (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))))) (MulActionWithZero.toSMulWithZero.{u1, u2} R S (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))))) (Module.toMulActionWithZero.{u1, u2} R S (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7))) (Algebra.toModule.{u1, u2} R S _inst_6 _inst_7 _inst_8))))) (SMulZeroClass.toHasSmul.{u2, u3} S M (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)))) (SMulWithZero.toSmulZeroClass.{u2, u3} S M (MulZeroClass.toHasZero.{u2} S (MulZeroOneClass.toMulZeroClass.{u2} S (MonoidWithZero.toMulZeroOneClass.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_7)))) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)))) (MulActionWithZero.toSMulWithZero.{u2, u3} S M (Semiring.toMonoidWithZero.{u2} S _inst_7) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)))) (Module.toMulActionWithZero.{u2, u3} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u3} M _inst_9) _inst_10)))) (SMulZeroClass.toHasSmul.{u1, u3} R M (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)))) (SMulWithZero.toSmulZeroClass.{u1, u3} R M (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)))) (MulActionWithZero.toSMulWithZero.{u1, u3} R M (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M (AddCommGroup.toAddCommMonoid.{u3} M _inst_9)))) (Module.toMulActionWithZero.{u1, u3} R M (CommSemiring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_9) _inst_11))))] (N : Submodule.{u2, u3} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u3} M _inst_9) _inst_10), (Submodule.Fg.{u2, u3} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u3} M _inst_9) _inst_10 N) -> (Function.Surjective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (algebraMap.{u1, u2} R S _inst_6 _inst_7 _inst_8))) -> (Submodule.Fg.{u1, u3} R M (CommSemiring.toSemiring.{u1} R _inst_6) (AddCommGroup.toAddCommMonoid.{u3} M _inst_9) _inst_11 (Submodule.restrictScalars.{u1, u2, u3} R S M _inst_7 (AddCommGroup.toAddCommMonoid.{u3} M _inst_9) (CommSemiring.toSemiring.{u1} R _inst_6) _inst_11 _inst_10 (SMulZeroClass.toHasSmul.{u1, u2} R S (AddZeroClass.toHasZero.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))))) (SMulWithZero.toSmulZeroClass.{u1, u2} R S (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))))) (MulActionWithZero.toSMulWithZero.{u1, u2} R S (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)))))) (Module.toMulActionWithZero.{u1, u2} R S (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7))) (Algebra.toModule.{u1, u2} R S _inst_6 _inst_7 _inst_8))))) _inst_12 N))
but is expected to have type
  forall {R : Type.{u3}} {S : Type.{u2}} {M : Type.{u1}} [_inst_6 : CommSemiring.{u3} R] [_inst_7 : Semiring.{u2} S] [_inst_8 : Algebra.{u3, u2} R S _inst_6 _inst_7] [_inst_9 : AddCommGroup.{u1} M] [_inst_10 : Module.{u2, u1} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u1} M _inst_9)] [_inst_11 : Module.{u3, u1} R M (CommSemiring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} M _inst_9)] [_inst_12 : IsScalarTower.{u3, u2, u1} R S M (Algebra.toSMul.{u3, u2} R S _inst_6 _inst_7 _inst_8) (SMulZeroClass.toSMul.{u2, u1} S M (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_9))))) (SMulWithZero.toSMulZeroClass.{u2, u1} S M (MonoidWithZero.toZero.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_7)) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_9))))) (MulActionWithZero.toSMulWithZero.{u2, u1} S M (Semiring.toMonoidWithZero.{u2} S _inst_7) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_9))))) (Module.toMulActionWithZero.{u2, u1} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u1} M _inst_9) _inst_10)))) (SMulZeroClass.toSMul.{u3, u1} R M (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_9))))) (SMulWithZero.toSMulZeroClass.{u3, u1} R M (CommMonoidWithZero.toZero.{u3} R (CommSemiring.toCommMonoidWithZero.{u3} R _inst_6)) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_9))))) (MulActionWithZero.toSMulWithZero.{u3, u1} R M (Semiring.toMonoidWithZero.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (NegZeroClass.toZero.{u1} M (SubNegZeroMonoid.toNegZeroClass.{u1} M (SubtractionMonoid.toSubNegZeroMonoid.{u1} M (SubtractionCommMonoid.toSubtractionMonoid.{u1} M (AddCommGroup.toDivisionAddCommMonoid.{u1} M _inst_9))))) (Module.toMulActionWithZero.{u3, u1} R M (CommSemiring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} M _inst_9) _inst_11))))] (N : Submodule.{u2, u1} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u1} M _inst_9) _inst_10), (Submodule.Fg.{u2, u1} S M _inst_7 (AddCommGroup.toAddCommMonoid.{u1} M _inst_9) _inst_10 N) -> (Function.Surjective.{succ u3, succ u2} R S (FunLike.coe.{max (succ u3) (succ u2), succ u3, succ u2} (RingHom.{u3, u2} R S (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u3 u2, u3, u2} (RingHom.{u3, u2} R S (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) R S (NonUnitalNonAssocSemiring.toMul.{u3} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} R (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7))) (NonUnitalRingHomClass.toMulHomClass.{max u3 u2, u3, u2} (RingHom.{u3, u2} R S (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} R (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_7)) (RingHomClass.toNonUnitalRingHomClass.{max u3 u2, u3, u2} (RingHom.{u3, u2} R S (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7)) R S (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7) (RingHom.instRingHomClassRingHom.{u3, u2} R S (Semiring.toNonAssocSemiring.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (Semiring.toNonAssocSemiring.{u2} S _inst_7))))) (algebraMap.{u3, u2} R S _inst_6 _inst_7 _inst_8))) -> (Submodule.Fg.{u3, u1} R M (CommSemiring.toSemiring.{u3} R _inst_6) (AddCommGroup.toAddCommMonoid.{u1} M _inst_9) _inst_11 (Submodule.restrictScalars.{u3, u2, u1} R S M _inst_7 (AddCommGroup.toAddCommMonoid.{u1} M _inst_9) (CommSemiring.toSemiring.{u3} R _inst_6) _inst_11 _inst_10 (Algebra.toSMul.{u3, u2} R S _inst_6 _inst_7 _inst_8) _inst_12 N))
Case conversion may be inaccurate. Consider using '#align submodule.fg_restrict_scalars Submodule.fg_restrictScalarsₓ'. -/
theorem fg_restrictScalars {R S M : Type _} [CommSemiring R] [Semiring S] [Algebra R S]
    [AddCommGroup M] [Module S M] [Module R M] [IsScalarTower R S M] (N : Submodule S M)
    (hfin : N.Fg) (h : Function.Surjective (algebraMap R S)) : (Submodule.restrictScalars R N).Fg :=
  by
  obtain ⟨X, rfl⟩ := hfin
  use X
  exact (Submodule.restrictScalars_span R S h ↑X).symm
#align submodule.fg_restrict_scalars Submodule.fg_restrictScalars

/- warning: submodule.fg.stablizes_of_supr_eq -> Submodule.Fg.stablizes_of_supᵢ_eq is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] {M' : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 M') -> (forall (N : OrderHom.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))), (Eq.{succ u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (supᵢ.{u2, 1} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toHasSup.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))) Nat (coeFn.{succ u2, succ u2} (OrderHom.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) (fun (_x : OrderHom.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) => Nat -> (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3)) (OrderHom.hasCoeToFun.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) N)) M') -> (Exists.{1} Nat (fun (n : Nat) => Eq.{succ u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) M' (coeFn.{succ u2, succ u2} (OrderHom.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) (fun (_x : OrderHom.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) => Nat -> (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3)) (OrderHom.hasCoeToFun.{0, u2} Nat (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) (PartialOrder.toPreorder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteSemilatticeInf.toPartialOrder.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toCompleteSemilatticeInf.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3))))) N n))))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] {M' : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3}, (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 M') -> (forall (N : OrderHom.{0, u1} Nat (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) (PartialOrder.toPreorder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3))))), (Eq.{succ u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (supᵢ.{u1, 1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (ConditionallyCompleteLattice.toSupSet.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.toConditionallyCompleteLattice.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3))) Nat (OrderHom.toFun.{0, u1} Nat (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) (PartialOrder.toPreorder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3)))) N)) M') -> (Exists.{1} Nat (fun (n : Nat) => Eq.{succ u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) M' (OrderHom.toFun.{0, u1} Nat (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) (PartialOrder.toPreorder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (OmegaCompletePartialOrder.toPartialOrder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (CompleteLattice.instOmegaCompletePartialOrder.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3)))) N n))))
Case conversion may be inaccurate. Consider using '#align submodule.fg.stablizes_of_supr_eq Submodule.Fg.stablizes_of_supᵢ_eqₓ'. -/
theorem Fg.stablizes_of_supᵢ_eq {M' : Submodule R M} (hM' : M'.Fg) (N : ℕ →o Submodule R M)
    (H : supᵢ N = M') : ∃ n, M' = N n :=
  by
  obtain ⟨S, hS⟩ := hM'
  have : ∀ s : S, ∃ n, (s : M) ∈ N n := fun s =>
    (Submodule.mem_supᵢ_of_chain N s).mp
      (by
        rw [H, ← hS]
        exact Submodule.subset_span s.2)
  choose f hf
  use S.attach.sup f
  apply le_antisymm
  · conv_lhs => rw [← hS]
    rw [Submodule.span_le]
    intro s hs
    exact N.2 (Finset.le_sup <| S.mem_attach ⟨s, hs⟩) (hf _)
  · rw [← H]
    exact le_supᵢ _ _
#align submodule.fg.stablizes_of_supr_eq Submodule.Fg.stablizes_of_supᵢ_eq

/- warning: submodule.fg_iff_compact -> Submodule.fg_iff_compact is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] (s : Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3), Iff (Submodule.Fg.{u1, u2} R M _inst_1 _inst_2 _inst_3 s) (CompleteLattice.IsCompactElement.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u1, u2} R M _inst_1 _inst_2 _inst_3) s)
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] (s : Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3), Iff (Submodule.Fg.{u2, u1} R M _inst_1 _inst_2 _inst_3 s) (CompleteLattice.IsCompactElement.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.completeLattice.{u2, u1} R M _inst_1 _inst_2 _inst_3) s)
Case conversion may be inaccurate. Consider using '#align submodule.fg_iff_compact Submodule.fg_iff_compactₓ'. -/
/-- Finitely generated submodules are precisely compact elements in the submodule lattice. -/
theorem fg_iff_compact (s : Submodule R M) : s.Fg ↔ CompleteLattice.IsCompactElement s := by
  classical
    -- Introduce shorthand for span of an element
    let sp : M → Submodule R M := fun a => span R {a}
    -- Trivial rewrite lemma; a small hack since simp (only) & rw can't accomplish this smoothly.
    have supr_rw : ∀ t : Finset M, (⨆ x ∈ t, sp x) = ⨆ x ∈ (↑t : Set M), sp x := fun t => by rfl
    constructor
    · rintro ⟨t, rfl⟩
      rw [span_eq_supr_of_singleton_spans, ← supr_rw, ← Finset.sup_eq_supᵢ t sp]
      apply CompleteLattice.finset_sup_compact_of_compact
      exact fun n _ => singleton_span_is_compact_element n
    · intro h
      -- s is the Sup of the spans of its elements.
      have sSup : s = Sup (sp '' ↑s) := by
        rw [supₛ_eq_supᵢ, supᵢ_image, ← span_eq_supr_of_singleton_spans, eq_comm, span_eq]
      -- by h, s is then below (and equal to) the sup of the spans of finitely many elements.
      obtain ⟨u, ⟨huspan, husup⟩⟩ := h (sp '' ↑s) (le_of_eq sSup)
      have ssup : s = u.sup id := by
        suffices : u.sup id ≤ s
        exact le_antisymm husup this
        rw [sSup, Finset.sup_id_eq_supₛ]
        exact supₛ_le_supₛ huspan
      obtain ⟨t, ⟨hts, rfl⟩⟩ := finset.subset_image_iff.mp huspan
      rw [Finset.sup_finset_image, Function.comp.left_id, Finset.sup_eq_supᵢ, supr_rw, ←
        span_eq_supr_of_singleton_spans, eq_comm] at ssup
      exact ⟨t, ssup⟩
#align submodule.fg_iff_compact Submodule.fg_iff_compact

end Submodule

namespace Submodule

section Map₂

variable {R M N P : Type _}

variable [CommSemiring R] [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P]

variable [Module R M] [Module R N] [Module R P]

/- warning: submodule.fg.map₂ -> Submodule.Fg.map₂ is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} {P : Type.{u4}} [_inst_1 : CommSemiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : AddCommMonoid.{u3} N] [_inst_4 : AddCommMonoid.{u4} P] [_inst_5 : Module.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2] [_inst_6 : Module.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_3] [_inst_7 : Module.{u1, u4} R P (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4] (f : LinearMap.{u1, u1, u2, max u3 u4} R R (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u1} R _inst_1) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) M (LinearMap.{u1, u1, u3, u4} R R (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u1} R _inst_1) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) N P _inst_3 _inst_4 _inst_6 _inst_7) _inst_2 (LinearMap.addCommMonoid.{u1, u1, u3, u4} R R N P (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u1} R _inst_1) _inst_3 _inst_4 _inst_6 _inst_7 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) _inst_5 (LinearMap.module.{u1, u1, u1, u3, u4} R R R N P (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u1} R _inst_1) _inst_3 _inst_4 _inst_6 _inst_7 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (CommSemiring.toSemiring.{u1} R _inst_1) _inst_7 (smulCommClass_self.{u1, u4} R P (CommSemiring.toCommMonoid.{u1} R _inst_1) (MulActionWithZero.toMulAction.{u1, u4} R P (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (AddZeroClass.toHasZero.{u4} P (AddMonoid.toAddZeroClass.{u4} P (AddCommMonoid.toAddMonoid.{u4} P _inst_4))) (Module.toMulActionWithZero.{u1, u4} R P (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4 _inst_7))))) {p : Submodule.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2 _inst_5} {q : Submodule.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_3 _inst_6}, (Submodule.Fg.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2 _inst_5 p) -> (Submodule.Fg.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_3 _inst_6 q) -> (Submodule.Fg.{u1, u4} R P (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4 _inst_7 (Submodule.map₂.{u1, u2, u3, u4} R M N P _inst_1 _inst_2 _inst_3 _inst_4 _inst_5 _inst_6 _inst_7 f p q))
but is expected to have type
  forall {R : Type.{u4}} {M : Type.{u3}} {N : Type.{u1}} {P : Type.{u2}} [_inst_1 : CommSemiring.{u4} R] [_inst_2 : AddCommMonoid.{u3} M] [_inst_3 : AddCommMonoid.{u1} N] [_inst_4 : AddCommMonoid.{u2} P] [_inst_5 : Module.{u4, u3} R M (CommSemiring.toSemiring.{u4} R _inst_1) _inst_2] [_inst_6 : Module.{u4, u1} R N (CommSemiring.toSemiring.{u4} R _inst_1) _inst_3] [_inst_7 : Module.{u4, u2} R P (CommSemiring.toSemiring.{u4} R _inst_1) _inst_4] (f : LinearMap.{u4, u4, u3, max u2 u1} R R (CommSemiring.toSemiring.{u4} R _inst_1) (CommSemiring.toSemiring.{u4} R _inst_1) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (CommSemiring.toSemiring.{u4} R _inst_1))) M (LinearMap.{u4, u4, u1, u2} R R (CommSemiring.toSemiring.{u4} R _inst_1) (CommSemiring.toSemiring.{u4} R _inst_1) (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (CommSemiring.toSemiring.{u4} R _inst_1))) N P _inst_3 _inst_4 _inst_6 _inst_7) _inst_2 (LinearMap.addCommMonoid.{u4, u4, u1, u2} R R N P (CommSemiring.toSemiring.{u4} R _inst_1) (CommSemiring.toSemiring.{u4} R _inst_1) _inst_3 _inst_4 _inst_6 _inst_7 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (CommSemiring.toSemiring.{u4} R _inst_1)))) _inst_5 (LinearMap.instModuleLinearMapAddCommMonoid.{u4, u4, u4, u1, u2} R R R N P (CommSemiring.toSemiring.{u4} R _inst_1) (CommSemiring.toSemiring.{u4} R _inst_1) _inst_3 _inst_4 _inst_6 _inst_7 (RingHom.id.{u4} R (Semiring.toNonAssocSemiring.{u4} R (CommSemiring.toSemiring.{u4} R _inst_1))) (CommSemiring.toSemiring.{u4} R _inst_1) _inst_7 (smulCommClass_self.{u4, u2} R P (CommSemiring.toCommMonoid.{u4} R _inst_1) (MulActionWithZero.toMulAction.{u4, u2} R P (Semiring.toMonoidWithZero.{u4} R (CommSemiring.toSemiring.{u4} R _inst_1)) (AddMonoid.toZero.{u2} P (AddCommMonoid.toAddMonoid.{u2} P _inst_4)) (Module.toMulActionWithZero.{u4, u2} R P (CommSemiring.toSemiring.{u4} R _inst_1) _inst_4 _inst_7))))) {p : Submodule.{u4, u3} R M (CommSemiring.toSemiring.{u4} R _inst_1) _inst_2 _inst_5} {q : Submodule.{u4, u1} R N (CommSemiring.toSemiring.{u4} R _inst_1) _inst_3 _inst_6}, (Submodule.Fg.{u4, u3} R M (CommSemiring.toSemiring.{u4} R _inst_1) _inst_2 _inst_5 p) -> (Submodule.Fg.{u4, u1} R N (CommSemiring.toSemiring.{u4} R _inst_1) _inst_3 _inst_6 q) -> (Submodule.Fg.{u4, u2} R P (CommSemiring.toSemiring.{u4} R _inst_1) _inst_4 _inst_7 (Submodule.map₂.{u4, u3, u1, u2} R M N P _inst_1 _inst_2 _inst_3 _inst_4 _inst_5 _inst_6 _inst_7 f p q))
Case conversion may be inaccurate. Consider using '#align submodule.fg.map₂ Submodule.Fg.map₂ₓ'. -/
theorem Fg.map₂ (f : M →ₗ[R] N →ₗ[R] P) {p : Submodule R M} {q : Submodule R N} (hp : p.Fg)
    (hq : q.Fg) : (map₂ f p q).Fg :=
  let ⟨sm, hfm, hm⟩ := fg_def.1 hp
  let ⟨sn, hfn, hn⟩ := fg_def.1 hq
  fg_def.2
    ⟨Set.image2 (fun m n => f m n) sm sn, hfm.image2 _ hfn,
      map₂_span_span R f sm sn ▸ hm ▸ hn ▸ rfl⟩
#align submodule.fg.map₂ Submodule.Fg.map₂

end Map₂

section Mul

variable {R : Type _} {A : Type _} [CommSemiring R] [Semiring A] [Algebra R A]

variable {M N : Submodule R A}

/- warning: submodule.fg.mul -> Submodule.Fg.mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} [_inst_1 : CommSemiring.{u1} R] [_inst_2 : Semiring.{u2} A] [_inst_3 : Algebra.{u1, u2} R A _inst_1 _inst_2] {M : Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)} {N : Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)}, (Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3) M) -> (Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3) N) -> (Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3) (HMul.hMul.{u2, u2, u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (instHMul.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (Submodule.mul.{u1, u2} R _inst_1 A _inst_2 _inst_3)) M N))
but is expected to have type
  forall {R : Type.{u2}} {A : Type.{u1}} [_inst_1 : CommSemiring.{u2} R] [_inst_2 : Semiring.{u1} A] [_inst_3 : Algebra.{u2, u1} R A _inst_1 _inst_2] {M : Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)} {N : Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)}, (Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3) M) -> (Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3) N) -> (Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3) (HMul.hMul.{u1, u1, u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (instHMul.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (Submodule.mul.{u2, u1} R _inst_1 A _inst_2 _inst_3)) M N))
Case conversion may be inaccurate. Consider using '#align submodule.fg.mul Submodule.Fg.mulₓ'. -/
theorem Fg.mul (hm : M.Fg) (hn : N.Fg) : (M * N).Fg :=
  hm.zipWith _ hn
#align submodule.fg.mul Submodule.Fg.mul

/- warning: submodule.fg.pow -> Submodule.Fg.pow is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} [_inst_1 : CommSemiring.{u1} R] [_inst_2 : Semiring.{u2} A] [_inst_3 : Algebra.{u1, u2} R A _inst_1 _inst_2] {M : Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)}, (Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3) M) -> (forall (n : Nat), Submodule.Fg.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3) (HPow.hPow.{u2, 0, u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) Nat (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (instHPow.{u2, 0} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) Nat (Monoid.Pow.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (MonoidWithZero.toMonoid.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (Semiring.toMonoidWithZero.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (IdemSemiring.toSemiring.{u2} (Submodule.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_2))) (Algebra.toModule.{u1, u2} R A _inst_1 _inst_2 _inst_3)) (Submodule.idemSemiring.{u1, u2} R _inst_1 A _inst_2 _inst_3)))))) M n))
but is expected to have type
  forall {R : Type.{u2}} {A : Type.{u1}} [_inst_1 : CommSemiring.{u2} R] [_inst_2 : Semiring.{u1} A] [_inst_3 : Algebra.{u2, u1} R A _inst_1 _inst_2] {M : Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)}, (Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3) M) -> (forall (n : Nat), Submodule.Fg.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3) (HPow.hPow.{u1, 0, u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) Nat (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (instHPow.{u1, 0} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) Nat (Monoid.Pow.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (MonoidWithZero.toMonoid.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (Semiring.toMonoidWithZero.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (IdemSemiring.toSemiring.{u1} (Submodule.{u2, u1} R A (CommSemiring.toSemiring.{u2} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} A (Semiring.toNonAssocSemiring.{u1} A _inst_2))) (Algebra.toModule.{u2, u1} R A _inst_1 _inst_2 _inst_3)) (Submodule.idemSemiring.{u2, u1} R _inst_1 A _inst_2 _inst_3)))))) M n))
Case conversion may be inaccurate. Consider using '#align submodule.fg.pow Submodule.Fg.powₓ'. -/
theorem Fg.pow (h : M.Fg) (n : ℕ) : (M ^ n).Fg :=
  Nat.recOn n ⟨{1}, by simp [one_eq_span]⟩ fun n ih => by simpa [pow_succ] using h.mul ih
#align submodule.fg.pow Submodule.Fg.pow

end Mul

end Submodule

namespace Ideal

variable {R : Type _} {M : Type _} [Semiring R] [AddCommMonoid M] [Module R M]

#print Ideal.Fg /-
/-- An ideal of `R` is finitely generated if it is the span of a finite subset of `R`.

This is defeq to `submodule.fg`, but unfolds more nicely. -/
def Fg (I : Ideal R) : Prop :=
  ∃ S : Finset R, Ideal.span ↑S = I
#align ideal.fg Ideal.Fg
-/

/- warning: ideal.fg.map -> Ideal.Fg.map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_4 : Semiring.{u1} R] [_inst_5 : Semiring.{u2} S] {I : Ideal.{u1} R _inst_4}, (Ideal.Fg.{u1} R _inst_4 I) -> (forall (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_4) (Semiring.toNonAssocSemiring.{u2} S _inst_5)), Ideal.Fg.{u2} S _inst_5 (Ideal.map.{u1, u2, max u1 u2} R S (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_4) (Semiring.toNonAssocSemiring.{u2} S _inst_5)) _inst_4 _inst_5 (RingHom.ringHomClass.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_4) (Semiring.toNonAssocSemiring.{u2} S _inst_5)) f I))
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_4 : Semiring.{u2} R] [_inst_5 : Semiring.{u1} S] {I : Ideal.{u2} R _inst_4}, (Ideal.Fg.{u2} R _inst_4 I) -> (forall (f : RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_4) (Semiring.toNonAssocSemiring.{u1} S _inst_5)), Ideal.Fg.{u1} S _inst_5 (Ideal.map.{u2, u1, max u2 u1} R S (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_4) (Semiring.toNonAssocSemiring.{u1} S _inst_5)) _inst_4 _inst_5 (RingHom.instRingHomClassRingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_4) (Semiring.toNonAssocSemiring.{u1} S _inst_5)) f I))
Case conversion may be inaccurate. Consider using '#align ideal.fg.map Ideal.Fg.mapₓ'. -/
/-- The image of a finitely generated ideal is finitely generated.

This is the `ideal` version of `submodule.fg.map`. -/
theorem Fg.map {R S : Type _} [Semiring R] [Semiring S] {I : Ideal R} (h : I.Fg) (f : R →+* S) :
    (I.map f).Fg := by
  classical
    obtain ⟨s, hs⟩ := h
    refine' ⟨s.image f, _⟩
    rw [Finset.coe_image, ← Ideal.map_span, hs]
#align ideal.fg.map Ideal.Fg.map

/- warning: ideal.fg_ker_comp -> Ideal.fg_ker_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} {A : Type.{u3}} [_inst_4 : CommRing.{u1} R] [_inst_5 : CommRing.{u2} S] [_inst_6 : CommRing.{u3} A] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) (g : RingHom.{u2, u3} S A (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_6)))), (Ideal.Fg.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (RingHom.ker.{u1, u2, max u1 u2} R S (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (Ring.toSemiring.{u2} S (CommRing.toRing.{u2} S _inst_5)) (RingHom.ringHomClass.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) f)) -> (Ideal.Fg.{u2} S (Ring.toSemiring.{u2} S (CommRing.toRing.{u2} S _inst_5)) (RingHom.ker.{u2, u3, max u2 u3} S A (RingHom.{u2, u3} S A (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_6)))) (Ring.toSemiring.{u2} S (CommRing.toRing.{u2} S _inst_5)) (Ring.toSemiring.{u3} A (CommRing.toRing.{u3} A _inst_6)) (RingHom.ringHomClass.{u2, u3} S A (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_6)))) g)) -> (Function.Surjective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) f)) -> (Ideal.Fg.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (RingHom.ker.{u1, u3, max u1 u3} R A (RingHom.{u1, u3} R A (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_6)))) (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_4)) (Ring.toSemiring.{u3} A (CommRing.toRing.{u3} A _inst_6)) (RingHom.ringHomClass.{u1, u3} R A (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_6)))) (RingHom.comp.{u1, u2, u3} R S A (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_6))) g f)))
but is expected to have type
  forall {R : Type.{u3}} {S : Type.{u2}} {A : Type.{u1}} [_inst_4 : CommRing.{u3} R] [_inst_5 : CommRing.{u2} S] [_inst_6 : CommRing.{u1} A] (f : RingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) (g : RingHom.{u2, u1} S A (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_6)))), (Ideal.Fg.{u3} R (Ring.toSemiring.{u3} R (CommRing.toRing.{u3} R _inst_4)) (RingHom.ker.{u3, u2, max u3 u2} R S (RingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) (Ring.toSemiring.{u3} R (CommRing.toRing.{u3} R _inst_4)) (Ring.toSemiring.{u2} S (CommRing.toRing.{u2} S _inst_5)) (RingHom.instRingHomClassRingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) f)) -> (Ideal.Fg.{u2} S (Ring.toSemiring.{u2} S (CommRing.toRing.{u2} S _inst_5)) (RingHom.ker.{u2, u1, max u2 u1} S A (RingHom.{u2, u1} S A (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_6)))) (Ring.toSemiring.{u2} S (CommRing.toRing.{u2} S _inst_5)) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_6)) (RingHom.instRingHomClassRingHom.{u2, u1} S A (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_6)))) g)) -> (Function.Surjective.{succ u3, succ u2} R S (FunLike.coe.{max (succ u3) (succ u2), succ u3, succ u2} (RingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u3 u2, u3, u2} (RingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) R S (NonUnitalNonAssocSemiring.toMul.{u3} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} R (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))))) (NonUnitalRingHomClass.toMulHomClass.{max u3 u2, u3, u2} (RingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} R (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) (RingHomClass.toNonUnitalRingHomClass.{max u3 u2, u3, u2} (RingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5)))) R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (RingHom.instRingHomClassRingHom.{u3, u2} R S (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))))))) f)) -> (Ideal.Fg.{u3} R (Ring.toSemiring.{u3} R (CommRing.toRing.{u3} R _inst_4)) (RingHom.ker.{u3, u1, max u3 u1} R A (RingHom.{u3, u1} R A (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_6)))) (Ring.toSemiring.{u3} R (CommRing.toRing.{u3} R _inst_4)) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_6)) (RingHom.instRingHomClassRingHom.{u3, u1} R A (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_6)))) (RingHom.comp.{u3, u2, u1} R S A (NonAssocRing.toNonAssocSemiring.{u3} R (Ring.toNonAssocRing.{u3} R (CommRing.toRing.{u3} R _inst_4))) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S (CommRing.toRing.{u2} S _inst_5))) (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_6))) g f)))
Case conversion may be inaccurate. Consider using '#align ideal.fg_ker_comp Ideal.fg_ker_compₓ'. -/
theorem fg_ker_comp {R S A : Type _} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.Fg) (hg : g.ker.Fg) (hsur : Function.Surjective f) :
    (g.comp f).ker.Fg := by
  letI : Algebra R S := RingHom.toAlgebra f
  letI : Algebra R A := RingHom.toAlgebra (g.comp f)
  letI : Algebra S A := RingHom.toAlgebra g
  letI : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl
  let f₁ := Algebra.linearMap R S
  let g₁ := (IsScalarTower.toAlgHom R S A).toLinearMap
  exact Submodule.fg_ker_comp f₁ g₁ hf (Submodule.fg_restrictScalars g.ker hg hsur) hsur
#align ideal.fg_ker_comp Ideal.fg_ker_comp

#print Ideal.exists_radical_pow_le_of_fg /-
theorem exists_radical_pow_le_of_fg {R : Type _} [CommSemiring R] (I : Ideal R) (h : I.radical.Fg) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  have := le_refl I.radical; revert this
  refine' Submodule.fg_induction _ _ (fun J => J ≤ I.radical → ∃ n : ℕ, J ^ n ≤ I) _ _ _ h
  · intro x hx
    obtain ⟨n, hn⟩ := hx (subset_span (Set.mem_singleton x))
    exact ⟨n, by rwa [← Ideal.span, span_singleton_pow, span_le, Set.singleton_subset_iff]⟩
  · intro J K hJ hK hJK
    obtain ⟨n, hn⟩ := hJ fun x hx => hJK <| Ideal.mem_sup_left hx
    obtain ⟨m, hm⟩ := hK fun x hx => hJK <| Ideal.mem_sup_right hx
    use n + m
    rw [← Ideal.add_eq_sup, add_pow, Ideal.sum_eq_sup, Finset.sup_le_iff]
    refine' fun i hi => ideal.mul_le_right.trans _
    obtain h | h := le_or_lt n i
    · exact ideal.mul_le_right.trans ((Ideal.pow_le_pow h).trans hn)
    · refine' ideal.mul_le_left.trans ((Ideal.pow_le_pow _).trans hm)
      rw [add_comm, Nat.add_sub_assoc h.le]
      apply Nat.le_add_right
#align ideal.exists_radical_pow_le_of_fg Ideal.exists_radical_pow_le_of_fg
-/

end Ideal

section ModuleAndAlgebra

variable (R A B M N : Type _)

#print Module.Finite /-
/-- A module over a semiring is `finite` if it is finitely generated as a module. -/
class Module.Finite [Semiring R] [AddCommMonoid M] [Module R M] : Prop where
  out : (⊤ : Submodule R M).Fg
#align module.finite Module.Finite
-/

namespace Module

variable [Semiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N]

/- warning: module.finite_def -> Module.finite_def is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_6 : Semiring.{u1} R] [_inst_7 : AddCommMonoid.{u2} M] [_inst_8 : Module.{u1, u2} R M _inst_6 _inst_7], Iff (Module.Finite.{u1, u2} R M _inst_6 _inst_7 _inst_8) (Submodule.Fg.{u1, u2} R M _inst_6 _inst_7 _inst_8 (Top.top.{u2} (Submodule.{u1, u2} R M _inst_6 _inst_7 _inst_8) (Submodule.hasTop.{u1, u2} R M _inst_6 _inst_7 _inst_8)))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_6 : Semiring.{u2} R] [_inst_7 : AddCommMonoid.{u1} M] [_inst_8 : Module.{u2, u1} R M _inst_6 _inst_7], Iff (Module.Finite.{u2, u1} R M _inst_6 _inst_7 _inst_8) (Submodule.Fg.{u2, u1} R M _inst_6 _inst_7 _inst_8 (Top.top.{u1} (Submodule.{u2, u1} R M _inst_6 _inst_7 _inst_8) (Submodule.instTopSubmodule.{u2, u1} R M _inst_6 _inst_7 _inst_8)))
Case conversion may be inaccurate. Consider using '#align module.finite_def Module.finite_defₓ'. -/
theorem finite_def {R M} [Semiring R] [AddCommMonoid M] [Module R M] :
    Finite R M ↔ (⊤ : Submodule R M).Fg :=
  ⟨fun h => h.1, fun h => ⟨h⟩⟩
#align module.finite_def Module.finite_def

namespace Finite

open _Root_.Submodule Set

#print Module.Finite.iff_addMonoid_fg /-
theorem iff_addMonoid_fg {M : Type _} [AddCommMonoid M] : Module.Finite ℕ M ↔ AddMonoid.Fg M :=
  ⟨fun h => AddMonoid.fg_def.2 <| (fg_iff_addSubmonoid_fg ⊤).1 (finite_def.1 h), fun h =>
    finite_def.2 <| (fg_iff_addSubmonoid_fg ⊤).2 (AddMonoid.fg_def.1 h)⟩
#align module.finite.iff_add_monoid_fg Module.Finite.iff_addMonoid_fg
-/

/- warning: module.finite.iff_add_group_fg -> Module.Finite.iff_addGroup_fg is a dubious translation:
lean 3 declaration is
  forall {G : Type.{u1}} [_inst_6 : AddCommGroup.{u1} G], Iff (Module.Finite.{0, u1} Int G Int.semiring (AddCommGroup.toAddCommMonoid.{u1} G _inst_6) (AddCommGroup.intModule.{u1} G _inst_6)) (AddGroup.Fg.{u1} G (AddCommGroup.toAddGroup.{u1} G _inst_6))
but is expected to have type
  forall {G : Type.{u1}} [_inst_6 : AddCommGroup.{u1} G], Iff (Module.Finite.{0, u1} Int G Int.instSemiringInt (AddCommGroup.toAddCommMonoid.{u1} G _inst_6) (AddCommGroup.intModule.{u1} G _inst_6)) (AddGroup.Fg.{u1} G (AddCommGroup.toAddGroup.{u1} G _inst_6))
Case conversion may be inaccurate. Consider using '#align module.finite.iff_add_group_fg Module.Finite.iff_addGroup_fgₓ'. -/
theorem iff_addGroup_fg {G : Type _} [AddCommGroup G] : Module.Finite ℤ G ↔ AddGroup.Fg G :=
  ⟨fun h => AddGroup.fg_def.2 <| (fg_iff_add_subgroup_fg ⊤).1 (finite_def.1 h), fun h =>
    finite_def.2 <| (fg_iff_add_subgroup_fg ⊤).2 (AddGroup.fg_def.1 h)⟩
#align module.finite.iff_add_group_fg Module.Finite.iff_addGroup_fg

variable {R M N}

/- warning: module.finite.exists_fin -> Module.Finite.exists_fin is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] [_inst_6 : Module.Finite.{u1, u2} R M _inst_1 _inst_2 _inst_3], Exists.{1} Nat (fun (n : Nat) => Exists.{succ u2} ((Fin n) -> M) (fun (s : (Fin n) -> M) => Eq.{succ u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.span.{u1, u2} R M _inst_1 _inst_2 _inst_3 (Set.range.{u2, 1} M (Fin n) s)) (Top.top.{u2} (Submodule.{u1, u2} R M _inst_1 _inst_2 _inst_3) (Submodule.hasTop.{u1, u2} R M _inst_1 _inst_2 _inst_3))))
but is expected to have type
  forall {R : Type.{u2}} {M : Type.{u1}} [_inst_1 : Semiring.{u2} R] [_inst_2 : AddCommMonoid.{u1} M] [_inst_3 : Module.{u2, u1} R M _inst_1 _inst_2] [_inst_6 : Module.Finite.{u2, u1} R M _inst_1 _inst_2 _inst_3], Exists.{1} Nat (fun (n : Nat) => Exists.{succ u1} ((Fin n) -> M) (fun (s : (Fin n) -> M) => Eq.{succ u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.span.{u2, u1} R M _inst_1 _inst_2 _inst_3 (Set.range.{u1, 1} M (Fin n) s)) (Top.top.{u1} (Submodule.{u2, u1} R M _inst_1 _inst_2 _inst_3) (Submodule.instTopSubmodule.{u2, u1} R M _inst_1 _inst_2 _inst_3))))
Case conversion may be inaccurate. Consider using '#align module.finite.exists_fin Module.Finite.exists_finₓ'. -/
theorem exists_fin [Finite R M] : ∃ (n : ℕ)(s : Fin n → M), span R (range s) = ⊤ :=
  Submodule.fg_iff_exists_fin_generating_family.mp out
#align module.finite.exists_fin Module.Finite.exists_fin

/- warning: module.finite.of_surjective -> Module.Finite.of_surjective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] [_inst_4 : AddCommMonoid.{u3} N] [_inst_5 : Module.{u1, u3} R N _inst_1 _inst_4] [hM : Module.Finite.{u1, u2} R M _inst_1 _inst_2 _inst_3] (f : LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M N _inst_2 _inst_4 _inst_3 _inst_5), (Function.Surjective.{succ u2, succ u3} M N (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M N _inst_2 _inst_4 _inst_3 _inst_5) (fun (_x : LinearMap.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) M N _inst_2 _inst_4 _inst_3 _inst_5) => M -> N) (LinearMap.hasCoeToFun.{u1, u1, u2, u3} R R M N _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) f)) -> (Module.Finite.{u1, u3} R N _inst_1 _inst_4 _inst_5)
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} {N : Type.{u1}} [_inst_1 : Semiring.{u3} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u3, u2} R M _inst_1 _inst_2] [_inst_4 : AddCommMonoid.{u1} N] [_inst_5 : Module.{u3, u1} R N _inst_1 _inst_4] [hM : Module.Finite.{u3, u2} R M _inst_1 _inst_2 _inst_3] (f : LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M N _inst_2 _inst_4 _inst_3 _inst_5), (Function.Surjective.{succ u2, succ u1} M N (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (LinearMap.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) M N _inst_2 _inst_4 _inst_3 _inst_5) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : M) => N) _x) (LinearMap.instFunLikeLinearMap.{u3, u3, u2, u1} R R M N _inst_1 _inst_1 _inst_2 _inst_4 _inst_3 _inst_5 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1))) f)) -> (Module.Finite.{u3, u1} R N _inst_1 _inst_4 _inst_5)
Case conversion may be inaccurate. Consider using '#align module.finite.of_surjective Module.Finite.of_surjectiveₓ'. -/
theorem of_surjective [hM : Finite R M] (f : M →ₗ[R] N) (hf : Surjective f) : Finite R N :=
  ⟨by
    rw [← LinearMap.range_eq_top.2 hf, ← Submodule.map_top]
    exact hM.1.map f⟩
#align module.finite.of_surjective Module.Finite.of_surjective

variable (R)

#print Module.Finite.self /-
instance self : Finite R R :=
  ⟨⟨{1}, by simpa only [Finset.coe_singleton] using Ideal.span_singleton_one⟩⟩
#align module.finite.self Module.Finite.self
-/

variable (M)

/- warning: module.finite.of_restrict_scalars_finite -> Module.Finite.of_restrictScalars_finite is a dubious translation:
lean 3 declaration is
  forall (R : Type.{u1}) (A : Type.{u2}) (M : Type.{u3}) [_inst_6 : CommSemiring.{u1} R] [_inst_7 : Semiring.{u2} A] [_inst_8 : AddCommMonoid.{u3} M] [_inst_9 : Module.{u1, u3} R M (CommSemiring.toSemiring.{u1} R _inst_6) _inst_8] [_inst_10 : Module.{u2, u3} A M _inst_7 _inst_8] [_inst_11 : Algebra.{u1, u2} R A _inst_6 _inst_7] [_inst_12 : IsScalarTower.{u1, u2, u3} R A M (SMulZeroClass.toHasSmul.{u1, u2} R A (AddZeroClass.toHasZero.{u2} A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_7)))))) (SMulWithZero.toSmulZeroClass.{u1, u2} R A (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u2} A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_7)))))) (MulActionWithZero.toSMulWithZero.{u1, u2} R A (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u2} A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_7)))))) (Module.toMulActionWithZero.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A _inst_7))) (Algebra.toModule.{u1, u2} R A _inst_6 _inst_7 _inst_11))))) (SMulZeroClass.toHasSmul.{u2, u3} A M (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M _inst_8))) (SMulWithZero.toSmulZeroClass.{u2, u3} A M (MulZeroClass.toHasZero.{u2} A (MulZeroOneClass.toMulZeroClass.{u2} A (MonoidWithZero.toMulZeroOneClass.{u2} A (Semiring.toMonoidWithZero.{u2} A _inst_7)))) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M _inst_8))) (MulActionWithZero.toSMulWithZero.{u2, u3} A M (Semiring.toMonoidWithZero.{u2} A _inst_7) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M _inst_8))) (Module.toMulActionWithZero.{u2, u3} A M _inst_7 _inst_8 _inst_10)))) (SMulZeroClass.toHasSmul.{u1, u3} R M (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M _inst_8))) (SMulWithZero.toSmulZeroClass.{u1, u3} R M (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M _inst_8))) (MulActionWithZero.toSMulWithZero.{u1, u3} R M (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u3} M (AddMonoid.toAddZeroClass.{u3} M (AddCommMonoid.toAddMonoid.{u3} M _inst_8))) (Module.toMulActionWithZero.{u1, u3} R M (CommSemiring.toSemiring.{u1} R _inst_6) _inst_8 _inst_9))))] [hM : Module.Finite.{u1, u3} R M (CommSemiring.toSemiring.{u1} R _inst_6) _inst_8 _inst_9], Module.Finite.{u2, u3} A M _inst_7 _inst_8 _inst_10
but is expected to have type
  forall (R : Type.{u3}) (A : Type.{u2}) (M : Type.{u1}) [_inst_6 : CommSemiring.{u3} R] [_inst_7 : Semiring.{u2} A] [_inst_8 : AddCommMonoid.{u1} M] [_inst_9 : Module.{u3, u1} R M (CommSemiring.toSemiring.{u3} R _inst_6) _inst_8] [_inst_10 : Module.{u2, u1} A M _inst_7 _inst_8] [_inst_11 : Algebra.{u3, u2} R A _inst_6 _inst_7] [_inst_12 : IsScalarTower.{u3, u2, u1} R A M (Algebra.toSMul.{u3, u2} R A _inst_6 _inst_7 _inst_11) (SMulZeroClass.toSMul.{u2, u1} A M (AddMonoid.toZero.{u1} M (AddCommMonoid.toAddMonoid.{u1} M _inst_8)) (SMulWithZero.toSMulZeroClass.{u2, u1} A M (MonoidWithZero.toZero.{u2} A (Semiring.toMonoidWithZero.{u2} A _inst_7)) (AddMonoid.toZero.{u1} M (AddCommMonoid.toAddMonoid.{u1} M _inst_8)) (MulActionWithZero.toSMulWithZero.{u2, u1} A M (Semiring.toMonoidWithZero.{u2} A _inst_7) (AddMonoid.toZero.{u1} M (AddCommMonoid.toAddMonoid.{u1} M _inst_8)) (Module.toMulActionWithZero.{u2, u1} A M _inst_7 _inst_8 _inst_10)))) (SMulZeroClass.toSMul.{u3, u1} R M (AddMonoid.toZero.{u1} M (AddCommMonoid.toAddMonoid.{u1} M _inst_8)) (SMulWithZero.toSMulZeroClass.{u3, u1} R M (CommMonoidWithZero.toZero.{u3} R (CommSemiring.toCommMonoidWithZero.{u3} R _inst_6)) (AddMonoid.toZero.{u1} M (AddCommMonoid.toAddMonoid.{u1} M _inst_8)) (MulActionWithZero.toSMulWithZero.{u3, u1} R M (Semiring.toMonoidWithZero.{u3} R (CommSemiring.toSemiring.{u3} R _inst_6)) (AddMonoid.toZero.{u1} M (AddCommMonoid.toAddMonoid.{u1} M _inst_8)) (Module.toMulActionWithZero.{u3, u1} R M (CommSemiring.toSemiring.{u3} R _inst_6) _inst_8 _inst_9))))] [hM : Module.Finite.{u3, u1} R M (CommSemiring.toSemiring.{u3} R _inst_6) _inst_8 _inst_9], Module.Finite.{u2, u1} A M _inst_7 _inst_8 _inst_10
Case conversion may be inaccurate. Consider using '#align module.finite.of_restrict_scalars_finite Module.Finite.of_restrictScalars_finiteₓ'. -/
theorem of_restrictScalars_finite (R A M : Type _) [CommSemiring R] [Semiring A] [AddCommMonoid M]
    [Module R M] [Module A M] [Algebra R A] [IsScalarTower R A M] [hM : Finite R M] : Finite A M :=
  by
  rw [finite_def, fg_def] at hM⊢
  obtain ⟨S, hSfin, hSgen⟩ := hM
  refine' ⟨S, hSfin, eq_top_iff.2 _⟩
  have := Submodule.span_le_restrictScalars R A S
  rw [hSgen] at this
  exact this
#align module.finite.of_restrict_scalars_finite Module.Finite.of_restrictScalars_finite

variable {R M}

/- warning: module.finite.prod -> Module.Finite.prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] [_inst_4 : AddCommMonoid.{u3} N] [_inst_5 : Module.{u1, u3} R N _inst_1 _inst_4] [hM : Module.Finite.{u1, u2} R M _inst_1 _inst_2 _inst_3] [hN : Module.Finite.{u1, u3} R N _inst_1 _inst_4 _inst_5], Module.Finite.{u1, max u2 u3} R (Prod.{u2, u3} M N) _inst_1 (Prod.addCommMonoid.{u2, u3} M N _inst_2 _inst_4) (Prod.module.{u1, u2, u3} R M N _inst_1 _inst_2 _inst_4 _inst_3 _inst_5)
but is expected to have type
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] [_inst_4 : AddCommMonoid.{u3} N] [_inst_5 : Module.{u1, u3} R N _inst_1 _inst_4] [hM : Module.Finite.{u1, u2} R M _inst_1 _inst_2 _inst_3] [hN : Module.Finite.{u1, u3} R N _inst_1 _inst_4 _inst_5], Module.Finite.{u1, max u3 u2} R (Prod.{u2, u3} M N) _inst_1 (Prod.instAddCommMonoidSum.{u2, u3} M N _inst_2 _inst_4) (Prod.module.{u1, u2, u3} R M N _inst_1 _inst_2 _inst_4 _inst_3 _inst_5)
Case conversion may be inaccurate. Consider using '#align module.finite.prod Module.Finite.prodₓ'. -/
instance prod [hM : Finite R M] [hN : Finite R N] : Finite R (M × N) :=
  ⟨by
    rw [← Submodule.prod_top]
    exact hM.1.Prod hN.1⟩
#align module.finite.prod Module.Finite.prod

#print Module.Finite.pi /-
instance pi {ι : Type _} {M : ι → Type _} [Finite ι] [∀ i, AddCommMonoid (M i)]
    [∀ i, Module R (M i)] [h : ∀ i, Finite R (M i)] : Finite R (∀ i, M i) :=
  ⟨by
    rw [← Submodule.pi_top]
    exact Submodule.fg_pi fun i => (h i).1⟩
#align module.finite.pi Module.Finite.pi
-/

/- warning: module.finite.equiv -> Module.Finite.equiv is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} [_inst_1 : Semiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M _inst_1 _inst_2] [_inst_4 : AddCommMonoid.{u3} N] [_inst_5 : Module.{u1, u3} R N _inst_1 _inst_4] [hM : Module.Finite.{u1, u2} R M _inst_1 _inst_2 _inst_3], (LinearEquiv.{u1, u1, u2, u3} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (RingHomInvPair.ids.{u1} R _inst_1) (RingHomInvPair.ids.{u1} R _inst_1) M N _inst_2 _inst_4 _inst_3 _inst_5) -> (Module.Finite.{u1, u3} R N _inst_1 _inst_4 _inst_5)
but is expected to have type
  forall {R : Type.{u3}} {M : Type.{u2}} {N : Type.{u1}} [_inst_1 : Semiring.{u3} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u3, u2} R M _inst_1 _inst_2] [_inst_4 : AddCommMonoid.{u1} N] [_inst_5 : Module.{u3, u1} R N _inst_1 _inst_4] [hM : Module.Finite.{u3, u2} R M _inst_1 _inst_2 _inst_3], (LinearEquiv.{u3, u3, u2, u1} R R _inst_1 _inst_1 (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) (RingHom.id.{u3} R (Semiring.toNonAssocSemiring.{u3} R _inst_1)) (RingHomInvPair.ids.{u3} R _inst_1) (RingHomInvPair.ids.{u3} R _inst_1) M N _inst_2 _inst_4 _inst_3 _inst_5) -> (Module.Finite.{u3, u1} R N _inst_1 _inst_4 _inst_5)
Case conversion may be inaccurate. Consider using '#align module.finite.equiv Module.Finite.equivₓ'. -/
theorem equiv [hM : Finite R M] (e : M ≃ₗ[R] N) : Finite R N :=
  of_surjective (e : M →ₗ[R] N) e.Surjective
#align module.finite.equiv Module.Finite.equiv

section Algebra

/- warning: module.finite.trans -> Module.Finite.trans is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} (A : Type.{u2}) (B : Type.{u3}) [_inst_6 : CommSemiring.{u1} R] [_inst_7 : CommSemiring.{u2} A] [_inst_8 : Algebra.{u1, u2} R A _inst_6 (CommSemiring.toSemiring.{u2} A _inst_7)] [_inst_9 : Semiring.{u3} B] [_inst_10 : Algebra.{u1, u3} R B _inst_6 _inst_9] [_inst_11 : Algebra.{u2, u3} A B _inst_7 _inst_9] [_inst_12 : IsScalarTower.{u1, u2, u3} R A B (SMulZeroClass.toHasSmul.{u1, u2} R A (AddZeroClass.toHasZero.{u2} A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7))))))) (SMulWithZero.toSmulZeroClass.{u1, u2} R A (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u2} A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7))))))) (MulActionWithZero.toSMulWithZero.{u1, u2} R A (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u2} A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7))))))) (Module.toMulActionWithZero.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7)))) (Algebra.toModule.{u1, u2} R A _inst_6 (CommSemiring.toSemiring.{u2} A _inst_7) _inst_8))))) (SMulZeroClass.toHasSmul.{u2, u3} A B (AddZeroClass.toHasZero.{u3} B (AddMonoid.toAddZeroClass.{u3} B (AddCommMonoid.toAddMonoid.{u3} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9)))))) (SMulWithZero.toSmulZeroClass.{u2, u3} A B (MulZeroClass.toHasZero.{u2} A (MulZeroOneClass.toMulZeroClass.{u2} A (MonoidWithZero.toMulZeroOneClass.{u2} A (Semiring.toMonoidWithZero.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7))))) (AddZeroClass.toHasZero.{u3} B (AddMonoid.toAddZeroClass.{u3} B (AddCommMonoid.toAddMonoid.{u3} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9)))))) (MulActionWithZero.toSMulWithZero.{u2, u3} A B (Semiring.toMonoidWithZero.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7)) (AddZeroClass.toHasZero.{u3} B (AddMonoid.toAddZeroClass.{u3} B (AddCommMonoid.toAddMonoid.{u3} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9)))))) (Module.toMulActionWithZero.{u2, u3} A B (CommSemiring.toSemiring.{u2} A _inst_7) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9))) (Algebra.toModule.{u2, u3} A B _inst_7 _inst_9 _inst_11))))) (SMulZeroClass.toHasSmul.{u1, u3} R B (AddZeroClass.toHasZero.{u3} B (AddMonoid.toAddZeroClass.{u3} B (AddCommMonoid.toAddMonoid.{u3} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9)))))) (SMulWithZero.toSmulZeroClass.{u1, u3} R B (MulZeroClass.toHasZero.{u1} R (MulZeroOneClass.toMulZeroClass.{u1} R (MonoidWithZero.toMulZeroOneClass.{u1} R (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6))))) (AddZeroClass.toHasZero.{u3} B (AddMonoid.toAddZeroClass.{u3} B (AddCommMonoid.toAddMonoid.{u3} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9)))))) (MulActionWithZero.toSMulWithZero.{u1, u3} R B (Semiring.toMonoidWithZero.{u1} R (CommSemiring.toSemiring.{u1} R _inst_6)) (AddZeroClass.toHasZero.{u3} B (AddMonoid.toAddZeroClass.{u3} B (AddCommMonoid.toAddMonoid.{u3} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9)))))) (Module.toMulActionWithZero.{u1, u3} R B (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9))) (Algebra.toModule.{u1, u3} R B _inst_6 _inst_9 _inst_10)))))] [_inst_13 : Module.Finite.{u1, u2} R A (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7)))) (Algebra.toModule.{u1, u2} R A _inst_6 (CommSemiring.toSemiring.{u2} A _inst_7) _inst_8)] [_inst_14 : Module.Finite.{u2, u3} A B (CommSemiring.toSemiring.{u2} A _inst_7) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9))) (Algebra.toModule.{u2, u3} A B _inst_7 _inst_9 _inst_11)], Module.Finite.{u1, u3} R B (CommSemiring.toSemiring.{u1} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} B (Semiring.toNonAssocSemiring.{u3} B _inst_9))) (Algebra.toModule.{u1, u3} R B _inst_6 _inst_9 _inst_10)
but is expected to have type
  forall {R : Type.{u3}} (A : Type.{u2}) (B : Type.{u1}) [_inst_6 : CommSemiring.{u3} R] [_inst_7 : CommSemiring.{u2} A] [_inst_8 : Algebra.{u3, u2} R A _inst_6 (CommSemiring.toSemiring.{u2} A _inst_7)] [_inst_9 : Semiring.{u1} B] [_inst_10 : Algebra.{u3, u1} R B _inst_6 _inst_9] [_inst_11 : Algebra.{u2, u1} A B _inst_7 _inst_9] [_inst_12 : IsScalarTower.{u3, u2, u1} R A B (Algebra.toSMul.{u3, u2} R A _inst_6 (CommSemiring.toSemiring.{u2} A _inst_7) _inst_8) (Algebra.toSMul.{u2, u1} A B _inst_7 _inst_9 _inst_11) (Algebra.toSMul.{u3, u1} R B _inst_6 _inst_9 _inst_10)] [_inst_13 : Module.Finite.{u3, u2} R A (CommSemiring.toSemiring.{u3} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (CommSemiring.toSemiring.{u2} A _inst_7)))) (Algebra.toModule.{u3, u2} R A _inst_6 (CommSemiring.toSemiring.{u2} A _inst_7) _inst_8)] [_inst_14 : Module.Finite.{u2, u1} A B (CommSemiring.toSemiring.{u2} A _inst_7) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B _inst_9))) (Algebra.toModule.{u2, u1} A B _inst_7 _inst_9 _inst_11)], Module.Finite.{u3, u1} R B (CommSemiring.toSemiring.{u3} R _inst_6) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B _inst_9))) (Algebra.toModule.{u3, u1} R B _inst_6 _inst_9 _inst_10)
Case conversion may be inaccurate. Consider using '#align module.finite.trans Module.Finite.transₓ'. -/
theorem trans {R : Type _} (A B : Type _) [CommSemiring R] [CommSemiring A] [Algebra R A]
    [Semiring B] [Algebra R B] [Algebra A B] [IsScalarTower R A B] :
    ∀ [Finite R A] [Finite A B], Finite R B
  | ⟨⟨s, hs⟩⟩, ⟨⟨t, ht⟩⟩ =>
    ⟨Submodule.fg_def.2
        ⟨Set.image2 (· • ·) (↑s : Set A) (↑t : Set B),
          Set.Finite.image2 _ s.finite_toSet t.finite_toSet, by
          rw [Set.image2_smul, Submodule.span_smul_of_span_eq_top hs (↑t : Set B), ht,
            Submodule.restrictScalars_top]⟩⟩
#align module.finite.trans Module.Finite.trans

end Algebra

end Finite

end Module

#print Module.Finite.base_change /-
instance Module.Finite.base_change [CommSemiring R] [Semiring A] [Algebra R A] [AddCommMonoid M]
    [Module R M] [h : Module.Finite R M] : Module.Finite A (TensorProduct R A M) := by
  classical
    obtain ⟨s, hs⟩ := h.out
    refine' ⟨⟨s.image (TensorProduct.mk R A M 1), eq_top_iff.mpr fun x _ => _⟩⟩
    apply TensorProduct.induction_on x
    · exact zero_mem _
    · intro x y
      rw [Finset.coe_image, ← Submodule.span_span_of_tower R, Submodule.span_image, hs,
        Submodule.map_top, LinearMap.range_coe]
      change _ ∈ Submodule.span A (Set.range <| TensorProduct.mk R A M 1)
      rw [← mul_one x, ← smul_eq_mul, ← TensorProduct.smul_tmul']
      exact Submodule.smul_mem _ x (Submodule.subset_span <| Set.mem_range_self y)
    · exact fun _ _ => Submodule.add_mem _
#align module.finite.base_change Module.Finite.base_change
-/

/- warning: module.finite.tensor_product -> Module.Finite.tensorProduct is a dubious translation:
lean 3 declaration is
  forall (R : Type.{u1}) (M : Type.{u2}) (N : Type.{u3}) [_inst_1 : CommSemiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2] [_inst_4 : AddCommMonoid.{u3} N] [_inst_5 : Module.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4] [hM : Module.Finite.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2 _inst_3] [hN : Module.Finite.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4 _inst_5], Module.Finite.{u1, max u2 u3} R (TensorProduct.{u1, u2, u3} R _inst_1 M N _inst_2 _inst_4 _inst_3 _inst_5) (CommSemiring.toSemiring.{u1} R _inst_1) (TensorProduct.addCommMonoid.{u1, u2, u3} R _inst_1 M N _inst_2 _inst_4 _inst_3 _inst_5) (TensorProduct.module.{u1, u2, u3} R _inst_1 M N _inst_2 _inst_4 _inst_3 _inst_5)
but is expected to have type
  forall (R : Type.{u1}) (M : Type.{u2}) (N : Type.{u3}) [_inst_1 : CommSemiring.{u1} R] [_inst_2 : AddCommMonoid.{u2} M] [_inst_3 : Module.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2] [_inst_4 : AddCommMonoid.{u3} N] [_inst_5 : Module.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4] [hM : Module.Finite.{u1, u2} R M (CommSemiring.toSemiring.{u1} R _inst_1) _inst_2 _inst_3] [hN : Module.Finite.{u1, u3} R N (CommSemiring.toSemiring.{u1} R _inst_1) _inst_4 _inst_5], Module.Finite.{u1, max u3 u2} R (TensorProduct.{u1, u2, u3} R _inst_1 M N _inst_2 _inst_4 _inst_3 _inst_5) (CommSemiring.toSemiring.{u1} R _inst_1) (TensorProduct.addCommMonoid.{u1, u2, u3} R _inst_1 M N _inst_2 _inst_4 _inst_3 _inst_5) (TensorProduct.instModuleTensorProductToSemiringAddCommMonoid.{u1, u2, u3} R _inst_1 M N _inst_2 _inst_4 _inst_3 _inst_5)
Case conversion may be inaccurate. Consider using '#align module.finite.tensor_product Module.Finite.tensorProductₓ'. -/
instance Module.Finite.tensorProduct [CommSemiring R] [AddCommMonoid M] [Module R M]
    [AddCommMonoid N] [Module R N] [hM : Module.Finite R M] [hN : Module.Finite R N] :
    Module.Finite R (TensorProduct R M N)
    where out := (TensorProduct.map₂_mk_top_top_eq_top R M N).subst (hM.out.zipWith _ hN.out)
#align module.finite.tensor_product Module.Finite.tensorProduct

end ModuleAndAlgebra

namespace RingHom

variable {A B C : Type _} [CommRing A] [CommRing B] [CommRing C]

#print RingHom.Finite /-
/-- A ring morphism `A →+* B` is `finite` if `B` is finitely generated as `A`-module. -/
def Finite (f : A →+* B) : Prop :=
  letI : Algebra A B := f.to_algebra
  Module.Finite A B
#align ring_hom.finite RingHom.Finite
-/

namespace Finite

variable (A)

#print RingHom.Finite.id /-
theorem id : Finite (RingHom.id A) :=
  Module.Finite.self A
#align ring_hom.finite.id RingHom.Finite.id
-/

variable {A}

/- warning: ring_hom.finite.of_surjective -> RingHom.Finite.of_surjective is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u1}} {B : Type.{u2}} [_inst_1 : CommRing.{u1} A] [_inst_2 : CommRing.{u2} B] (f : RingHom.{u1, u2} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))), (Function.Surjective.{succ u1, succ u2} A B (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))) (fun (_x : RingHom.{u1, u2} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))) => A -> B) (RingHom.hasCoeToFun.{u1, u2} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))) f)) -> (RingHom.Finite.{u1, u2} A B _inst_1 _inst_2 f)
but is expected to have type
  forall {A : Type.{u2}} {B : Type.{u1}} [_inst_1 : CommRing.{u2} A] [_inst_2 : CommRing.{u1} B] (f : RingHom.{u2, u1} A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2)))), (Function.Surjective.{succ u2, succ u1} A B (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2)))) A (fun (_x : A) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : A) => B) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2)))) A B (NonUnitalNonAssocSemiring.toMul.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))))) (NonUnitalNonAssocSemiring.toMul.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2))))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2)))) A B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2)))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2)))) A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2))) (RingHom.instRingHomClassRingHom.{u2, u1} A B (NonAssocRing.toNonAssocSemiring.{u2} A (Ring.toNonAssocRing.{u2} A (CommRing.toRing.{u2} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u1} B (Ring.toNonAssocRing.{u1} B (CommRing.toRing.{u1} B _inst_2))))))) f)) -> (RingHom.Finite.{u2, u1} A B _inst_1 _inst_2 f)
Case conversion may be inaccurate. Consider using '#align ring_hom.finite.of_surjective RingHom.Finite.of_surjectiveₓ'. -/
theorem of_surjective (f : A →+* B) (hf : Surjective f) : f.Finite :=
  letI := f.to_algebra
  Module.Finite.of_surjective (Algebra.ofId A B).toLinearMap hf
#align ring_hom.finite.of_surjective RingHom.Finite.of_surjective

/- warning: ring_hom.finite.comp -> RingHom.Finite.comp is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u1}} {B : Type.{u2}} {C : Type.{u3}} [_inst_1 : CommRing.{u1} A] [_inst_2 : CommRing.{u2} B] [_inst_3 : CommRing.{u3} C] {g : RingHom.{u2, u3} B C (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u3} C (Ring.toNonAssocRing.{u3} C (CommRing.toRing.{u3} C _inst_3)))} {f : RingHom.{u1, u2} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))}, (RingHom.Finite.{u2, u3} B C _inst_2 _inst_3 g) -> (RingHom.Finite.{u1, u2} A B _inst_1 _inst_2 f) -> (RingHom.Finite.{u1, u3} A C _inst_1 _inst_3 (RingHom.comp.{u1, u2, u3} A B C (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u3} C (Ring.toNonAssocRing.{u3} C (CommRing.toRing.{u3} C _inst_3))) g f))
but is expected to have type
  forall {A : Type.{u1}} {B : Type.{u3}} {C : Type.{u2}} [_inst_1 : CommRing.{u1} A] [_inst_2 : CommRing.{u3} B] [_inst_3 : CommRing.{u2} C] {g : RingHom.{u3, u2} B C (NonAssocRing.toNonAssocSemiring.{u3} B (Ring.toNonAssocRing.{u3} B (CommRing.toRing.{u3} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u2} C (Ring.toNonAssocRing.{u2} C (CommRing.toRing.{u2} C _inst_3)))} {f : RingHom.{u1, u3} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u3} B (Ring.toNonAssocRing.{u3} B (CommRing.toRing.{u3} B _inst_2)))}, (RingHom.Finite.{u3, u2} B C _inst_2 _inst_3 g) -> (RingHom.Finite.{u1, u3} A B _inst_1 _inst_2 f) -> (RingHom.Finite.{u1, u2} A C _inst_1 _inst_3 (RingHom.comp.{u1, u3, u2} A B C (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u3} B (Ring.toNonAssocRing.{u3} B (CommRing.toRing.{u3} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u2} C (Ring.toNonAssocRing.{u2} C (CommRing.toRing.{u2} C _inst_3))) g f))
Case conversion may be inaccurate. Consider using '#align ring_hom.finite.comp RingHom.Finite.compₓ'. -/
theorem comp {g : B →+* C} {f : A →+* B} (hg : g.Finite) (hf : f.Finite) : (g.comp f).Finite :=
  @Module.Finite.trans A B C _ _ f.toAlgebra _ (g.comp f).toAlgebra g.toAlgebra
    (by
      fconstructor
      intro a b c
      simp only [Algebra.smul_def, RingHom.map_mul, mul_assoc]
      rfl)
    hf hg
#align ring_hom.finite.comp RingHom.Finite.comp

/- warning: ring_hom.finite.of_comp_finite -> RingHom.Finite.of_comp_finite is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u1}} {B : Type.{u2}} {C : Type.{u3}} [_inst_1 : CommRing.{u1} A] [_inst_2 : CommRing.{u2} B] [_inst_3 : CommRing.{u3} C] {f : RingHom.{u1, u2} A B (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))} {g : RingHom.{u2, u3} B C (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u3} C (Ring.toNonAssocRing.{u3} C (CommRing.toRing.{u3} C _inst_3)))}, (RingHom.Finite.{u1, u3} A C _inst_1 _inst_3 (RingHom.comp.{u1, u2, u3} A B C (NonAssocRing.toNonAssocSemiring.{u1} A (Ring.toNonAssocRing.{u1} A (CommRing.toRing.{u1} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u3} C (Ring.toNonAssocRing.{u3} C (CommRing.toRing.{u3} C _inst_3))) g f)) -> (RingHom.Finite.{u2, u3} B C _inst_2 _inst_3 g)
but is expected to have type
  forall {A : Type.{u3}} {B : Type.{u2}} {C : Type.{u1}} [_inst_1 : CommRing.{u3} A] [_inst_2 : CommRing.{u2} B] [_inst_3 : CommRing.{u1} C] {f : RingHom.{u3, u2} A B (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2)))} {g : RingHom.{u2, u1} B C (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u1} C (Ring.toNonAssocRing.{u1} C (CommRing.toRing.{u1} C _inst_3)))}, (RingHom.Finite.{u3, u1} A C _inst_1 _inst_3 (RingHom.comp.{u3, u2, u1} A B C (NonAssocRing.toNonAssocSemiring.{u3} A (Ring.toNonAssocRing.{u3} A (CommRing.toRing.{u3} A _inst_1))) (NonAssocRing.toNonAssocSemiring.{u2} B (Ring.toNonAssocRing.{u2} B (CommRing.toRing.{u2} B _inst_2))) (NonAssocRing.toNonAssocSemiring.{u1} C (Ring.toNonAssocRing.{u1} C (CommRing.toRing.{u1} C _inst_3))) g f)) -> (RingHom.Finite.{u2, u1} B C _inst_2 _inst_3 g)
Case conversion may be inaccurate. Consider using '#align ring_hom.finite.of_comp_finite RingHom.Finite.of_comp_finiteₓ'. -/
theorem of_comp_finite {f : A →+* B} {g : B →+* C} (h : (g.comp f).Finite) : g.Finite :=
  by
  letI := f.to_algebra
  letI := g.to_algebra
  letI := (g.comp f).toAlgebra
  letI : IsScalarTower A B C := RestrictScalars.isScalarTower A B C
  letI : Module.Finite A C := h
  exact Module.Finite.of_restrictScalars_finite A B C
#align ring_hom.finite.of_comp_finite RingHom.Finite.of_comp_finite

end Finite

end RingHom

namespace AlgHom

variable {R A B C : Type _} [CommRing R]

variable [CommRing A] [CommRing B] [CommRing C]

variable [Algebra R A] [Algebra R B] [Algebra R C]

#print AlgHom.Finite /-
/-- An algebra morphism `A →ₐ[R] B` is finite if it is finite as ring morphism.
In other words, if `B` is finitely generated as `A`-module. -/
def Finite (f : A →ₐ[R] B) : Prop :=
  f.toRingHom.Finite
#align alg_hom.finite AlgHom.Finite
-/

namespace Finite

variable (R A)

/- warning: alg_hom.finite.id -> AlgHom.Finite.id is a dubious translation:
lean 3 declaration is
  forall (R : Type.{u1}) (A : Type.{u2}) [_inst_1 : CommRing.{u1} R] [_inst_2 : CommRing.{u2} A] [_inst_5 : Algebra.{u1, u2} R A (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))], AlgHom.Finite.{u1, u2, u2} R A A _inst_1 _inst_2 _inst_2 _inst_5 _inst_5 (AlgHom.id.{u1, u2} R A (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) _inst_5)
but is expected to have type
  forall (R : Type.{u2}) (A : Type.{u1}) [_inst_1 : CommRing.{u2} R] [_inst_2 : CommRing.{u1} A] [_inst_5 : Algebra.{u2, u1} R A (CommRing.toCommSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_2))], AlgHom.Finite.{u2, u1, u1} R A A _inst_1 _inst_2 _inst_2 _inst_5 _inst_5 (AlgHom.id.{u2, u1} R A (CommRing.toCommSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_2)) _inst_5)
Case conversion may be inaccurate. Consider using '#align alg_hom.finite.id AlgHom.Finite.idₓ'. -/
theorem id : Finite (AlgHom.id R A) :=
  RingHom.Finite.id A
#align alg_hom.finite.id AlgHom.Finite.id

variable {R A}

/- warning: alg_hom.finite.comp -> AlgHom.Finite.comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} {B : Type.{u3}} {C : Type.{u4}} [_inst_1 : CommRing.{u1} R] [_inst_2 : CommRing.{u2} A] [_inst_3 : CommRing.{u3} B] [_inst_4 : CommRing.{u4} C] [_inst_5 : Algebra.{u1, u2} R A (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))] [_inst_6 : Algebra.{u1, u3} R B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3))] [_inst_7 : Algebra.{u1, u4} R C (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u4} C (CommRing.toRing.{u4} C _inst_4))] {g : AlgHom.{u1, u3, u4} R B C (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) (Ring.toSemiring.{u4} C (CommRing.toRing.{u4} C _inst_4)) _inst_6 _inst_7} {f : AlgHom.{u1, u2, u3} R A B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6}, (AlgHom.Finite.{u1, u3, u4} R B C _inst_1 _inst_3 _inst_4 _inst_6 _inst_7 g) -> (AlgHom.Finite.{u1, u2, u3} R A B _inst_1 _inst_2 _inst_3 _inst_5 _inst_6 f) -> (AlgHom.Finite.{u1, u2, u4} R A C _inst_1 _inst_2 _inst_4 _inst_5 _inst_7 (AlgHom.comp.{u1, u2, u3, u4} R A B C (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) (Ring.toSemiring.{u4} C (CommRing.toRing.{u4} C _inst_4)) _inst_5 _inst_6 _inst_7 g f))
but is expected to have type
  forall {R : Type.{u4}} {A : Type.{u1}} {B : Type.{u3}} {C : Type.{u2}} [_inst_1 : CommRing.{u4} R] [_inst_2 : CommRing.{u1} A] [_inst_3 : CommRing.{u3} B] [_inst_4 : CommRing.{u2} C] [_inst_5 : Algebra.{u4, u1} R A (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_2))] [_inst_6 : Algebra.{u4, u3} R B (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3))] [_inst_7 : Algebra.{u4, u2} R C (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u2} C (CommRing.toRing.{u2} C _inst_4))] {g : AlgHom.{u4, u3, u2} R B C (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) (Ring.toSemiring.{u2} C (CommRing.toRing.{u2} C _inst_4)) _inst_6 _inst_7} {f : AlgHom.{u4, u1, u3} R A B (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6}, (AlgHom.Finite.{u4, u3, u2} R B C _inst_1 _inst_3 _inst_4 _inst_6 _inst_7 g) -> (AlgHom.Finite.{u4, u1, u3} R A B _inst_1 _inst_2 _inst_3 _inst_5 _inst_6 f) -> (AlgHom.Finite.{u4, u1, u2} R A C _inst_1 _inst_2 _inst_4 _inst_5 _inst_7 (AlgHom.comp.{u4, u1, u3, u2} R A B C (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u1} A (CommRing.toRing.{u1} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) (Ring.toSemiring.{u2} C (CommRing.toRing.{u2} C _inst_4)) _inst_5 _inst_6 _inst_7 g f))
Case conversion may be inaccurate. Consider using '#align alg_hom.finite.comp AlgHom.Finite.compₓ'. -/
theorem comp {g : B →ₐ[R] C} {f : A →ₐ[R] B} (hg : g.Finite) (hf : f.Finite) : (g.comp f).Finite :=
  RingHom.Finite.comp hg hf
#align alg_hom.finite.comp AlgHom.Finite.comp

/- warning: alg_hom.finite.of_surjective -> AlgHom.Finite.of_surjective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} {B : Type.{u3}} [_inst_1 : CommRing.{u1} R] [_inst_2 : CommRing.{u2} A] [_inst_3 : CommRing.{u3} B] [_inst_5 : Algebra.{u1, u2} R A (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))] [_inst_6 : Algebra.{u1, u3} R B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3))] (f : AlgHom.{u1, u2, u3} R A B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6), (Function.Surjective.{succ u2, succ u3} A B (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (AlgHom.{u1, u2, u3} R A B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6) (fun (_x : AlgHom.{u1, u2, u3} R A B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6) => A -> B) ([anonymous].{u1, u2, u3} R A B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6) f)) -> (AlgHom.Finite.{u1, u2, u3} R A B _inst_1 _inst_2 _inst_3 _inst_5 _inst_6 f)
but is expected to have type
  forall {R : Type.{u3}} {A : Type.{u2}} {B : Type.{u1}} [_inst_1 : CommRing.{u3} R] [_inst_2 : CommRing.{u2} A] [_inst_3 : CommRing.{u1} B] [_inst_5 : Algebra.{u3, u2} R A (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))] [_inst_6 : Algebra.{u3, u1} R B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3))] (f : AlgHom.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6), (Function.Surjective.{succ u2, succ u1} A B (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (AlgHom.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6) A (fun (_x : A) => (fun (x._@.Mathlib.Algebra.Hom.GroupAction._hyg.2186 : A) => B) _x) (SMulHomClass.toFunLike.{max u2 u1, u3, u2, u1} (AlgHom.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6) R A B (SMulZeroClass.toSMul.{u3, u2} R A (AddMonoid.toZero.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))))))) (DistribSMul.toSMulZeroClass.{u3, u2} R A (AddMonoid.toAddZeroClass.{u2} A (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))))))) (DistribMulAction.toDistribSMul.{u3, u2} R A (MonoidWithZero.toMonoid.{u3} R (Semiring.toMonoidWithZero.{u3} R (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)))) (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)))))) (Module.toDistribMulAction.{u3, u2} R A (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))))) (Algebra.toModule.{u3, u2} R A (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) _inst_5))))) (SMulZeroClass.toSMul.{u3, u1} R B (AddMonoid.toZero.{u1} B (AddCommMonoid.toAddMonoid.{u1} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3))))))) (DistribSMul.toSMulZeroClass.{u3, u1} R B (AddMonoid.toAddZeroClass.{u1} B (AddCommMonoid.toAddMonoid.{u1} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3))))))) (DistribMulAction.toDistribSMul.{u3, u1} R B (MonoidWithZero.toMonoid.{u3} R (Semiring.toMonoidWithZero.{u3} R (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)))) (AddCommMonoid.toAddMonoid.{u1} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)))))) (Module.toDistribMulAction.{u3, u1} R B (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3))))) (Algebra.toModule.{u3, u1} R B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_6))))) (DistribMulActionHomClass.toSMulHomClass.{max u2 u1, u3, u2, u1} (AlgHom.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6) R A B (MonoidWithZero.toMonoid.{u3} R (Semiring.toMonoidWithZero.{u3} R (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)))) (AddCommMonoid.toAddMonoid.{u2} A (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)))))) (AddCommMonoid.toAddMonoid.{u1} B (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)))))) (Module.toDistribMulAction.{u3, u2} R A (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))))) (Algebra.toModule.{u3, u2} R A (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) _inst_5)) (Module.toDistribMulAction.{u3, u1} R B (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3))))) (Algebra.toModule.{u3, u1} R B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_6)) (NonUnitalAlgHomClass.toDistribMulActionHomClass.{max u2 u1, u3, u2, u1} (AlgHom.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6) R A B (MonoidWithZero.toMonoid.{u3} R (Semiring.toMonoidWithZero.{u3} R (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)))) (Module.toDistribMulAction.{u3, u2} R A (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} A (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} A (Semiring.toNonAssocSemiring.{u2} A (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))))) (Algebra.toModule.{u3, u2} R A (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) _inst_5)) (Module.toDistribMulAction.{u3, u1} R B (CommSemiring.toSemiring.{u3} R (CommRing.toCommSemiring.{u3} R _inst_1)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} B (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} B (Semiring.toNonAssocSemiring.{u1} B (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3))))) (Algebra.toModule.{u3, u1} R B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_6)) (AlgHom.instNonUnitalAlgHomClassToMonoidToMonoidWithZeroToSemiringToNonUnitalNonAssocSemiringToNonAssocSemiringToNonUnitalNonAssocSemiringToNonAssocSemiringToDistribMulActionToAddCommMonoidToModuleToDistribMulActionToAddCommMonoidToModule.{u3, u2, u1, max u2 u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6 (AlgHom.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6) (AlgHom.algHomClass.{u3, u2, u1} R A B (CommRing.toCommSemiring.{u3} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u1} B (CommRing.toRing.{u1} B _inst_3)) _inst_5 _inst_6))))) f)) -> (AlgHom.Finite.{u3, u2, u1} R A B _inst_1 _inst_2 _inst_3 _inst_5 _inst_6 f)
Case conversion may be inaccurate. Consider using '#align alg_hom.finite.of_surjective AlgHom.Finite.of_surjectiveₓ'. -/
theorem of_surjective (f : A →ₐ[R] B) (hf : Surjective f) : f.Finite :=
  RingHom.Finite.of_surjective f hf
#align alg_hom.finite.of_surjective AlgHom.Finite.of_surjective

/- warning: alg_hom.finite.of_comp_finite -> AlgHom.Finite.of_comp_finite is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {A : Type.{u2}} {B : Type.{u3}} {C : Type.{u4}} [_inst_1 : CommRing.{u1} R] [_inst_2 : CommRing.{u2} A] [_inst_3 : CommRing.{u3} B] [_inst_4 : CommRing.{u4} C] [_inst_5 : Algebra.{u1, u2} R A (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2))] [_inst_6 : Algebra.{u1, u3} R B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3))] [_inst_7 : Algebra.{u1, u4} R C (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u4} C (CommRing.toRing.{u4} C _inst_4))] {f : AlgHom.{u1, u2, u3} R A B (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) _inst_5 _inst_6} {g : AlgHom.{u1, u3, u4} R B C (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) (Ring.toSemiring.{u4} C (CommRing.toRing.{u4} C _inst_4)) _inst_6 _inst_7}, (AlgHom.Finite.{u1, u2, u4} R A C _inst_1 _inst_2 _inst_4 _inst_5 _inst_7 (AlgHom.comp.{u1, u2, u3, u4} R A B C (CommRing.toCommSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} A (CommRing.toRing.{u2} A _inst_2)) (Ring.toSemiring.{u3} B (CommRing.toRing.{u3} B _inst_3)) (Ring.toSemiring.{u4} C (CommRing.toRing.{u4} C _inst_4)) _inst_5 _inst_6 _inst_7 g f)) -> (AlgHom.Finite.{u1, u3, u4} R B C _inst_1 _inst_3 _inst_4 _inst_6 _inst_7 g)
but is expected to have type
  forall {R : Type.{u4}} {A : Type.{u3}} {B : Type.{u2}} {C : Type.{u1}} [_inst_1 : CommRing.{u4} R] [_inst_2 : CommRing.{u3} A] [_inst_3 : CommRing.{u2} B] [_inst_4 : CommRing.{u1} C] [_inst_5 : Algebra.{u4, u3} R A (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u3} A (CommRing.toRing.{u3} A _inst_2))] [_inst_6 : Algebra.{u4, u2} R B (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u2} B (CommRing.toRing.{u2} B _inst_3))] [_inst_7 : Algebra.{u4, u1} R C (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u1} C (CommRing.toRing.{u1} C _inst_4))] {f : AlgHom.{u4, u3, u2} R A B (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u3} A (CommRing.toRing.{u3} A _inst_2)) (Ring.toSemiring.{u2} B (CommRing.toRing.{u2} B _inst_3)) _inst_5 _inst_6} {g : AlgHom.{u4, u2, u1} R B C (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u2} B (CommRing.toRing.{u2} B _inst_3)) (Ring.toSemiring.{u1} C (CommRing.toRing.{u1} C _inst_4)) _inst_6 _inst_7}, (AlgHom.Finite.{u4, u3, u1} R A C _inst_1 _inst_2 _inst_4 _inst_5 _inst_7 (AlgHom.comp.{u4, u3, u2, u1} R A B C (CommRing.toCommSemiring.{u4} R _inst_1) (Ring.toSemiring.{u3} A (CommRing.toRing.{u3} A _inst_2)) (Ring.toSemiring.{u2} B (CommRing.toRing.{u2} B _inst_3)) (Ring.toSemiring.{u1} C (CommRing.toRing.{u1} C _inst_4)) _inst_5 _inst_6 _inst_7 g f)) -> (AlgHom.Finite.{u4, u2, u1} R B C _inst_1 _inst_3 _inst_4 _inst_6 _inst_7 g)
Case conversion may be inaccurate. Consider using '#align alg_hom.finite.of_comp_finite AlgHom.Finite.of_comp_finiteₓ'. -/
theorem of_comp_finite {f : A →ₐ[R] B} {g : B →ₐ[R] C} (h : (g.comp f).Finite) : g.Finite :=
  RingHom.Finite.of_comp_finite h
#align alg_hom.finite.of_comp_finite AlgHom.Finite.of_comp_finite

end Finite

end AlgHom