l3lab/ntp-mathlib huggingface dataset:
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 

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
x : R
hx : Submodule.span R {x} ≤ radical I
n : ℕ
hn : x ^ n ∈ I
⊢ Submodule.span R {x} ^ n ≤ I

Next tactic:
rwa [← Ideal.span, span_singleton_pow, span_le, Set.singleton_subset_iff]
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]⟩
  · 

Proof state:
case refine'_2
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
⊢ ∀ (M₁ M₂ : Submodule R R),
    (fun J => J ≤ radical I → ∃ n, J ^ n ≤ I) M₁ →
      (fun J => J ≤ radical I → ∃ n, J ^ n ≤ I) M₂ → (fun J => J ≤ radical I → ∃ n, J ^ n ≤ I) (M₁ ⊔ M₂)

Next tactic:
intro J K hJ hK hJK
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
    

Proof state:
case refine'_2
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
⊢ ∃ n, (J ⊔ K) ^ n ≤ I

Next tactic:
obtain ⟨n, hn⟩ := hJ fun x hx => hJK <| Ideal.mem_sup_left hx
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
    

Proof state:
case refine'_2.intro
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
⊢ ∃ n, (J ⊔ K) ^ n ≤ I

Next tactic:
obtain ⟨m, hm⟩ := hK fun x hx => hJK <| Ideal.mem_sup_right hx
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
    

Proof state:
case refine'_2.intro.intro
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
⊢ ∃ n, (J ⊔ K) ^ n ≤ I

Next tactic:
use n + m
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
    

Proof state:
case h
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
⊢ (J ⊔ K) ^ (n + m) ≤ I

Next tactic:
rw [← Ideal.add_eq_sup, add_pow, Ideal.sum_eq_sup, Finset.sup_le_iff]
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]
    

Proof state:
case h
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
⊢ ∀ b ∈ Finset.range (n + m + 1), J ^ b * K ^ (n + m - b) * ↑(Nat.choose (n + m) b) ≤ I

Next tactic:
refine' fun i _ => Ideal.mul_le_right.trans _
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 _ => Ideal.mul_le_right.trans _
    

Proof state:
case h
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
i : ℕ
x✝ : i ∈ Finset.range (n + m + 1)
⊢ J ^ i * K ^ (n + m - i) ≤ I

Next tactic:
obtain h | h := le_or_lt n i
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 _ => Ideal.mul_le_right.trans _
    obtain h | h := le_or_lt n i
    · 

Proof state:
case h.inl
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h✝ : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
i : ℕ
x✝ : i ∈ Finset.range (n + m + 1)
h : n ≤ i
⊢ J ^ i * K ^ (n + m - i) ≤ I

Next tactic:
apply Ideal.mul_le_right.trans ((Ideal.pow_le_pow_right h).trans hn)
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 _ => Ideal.mul_le_right.trans _
    obtain h | h := le_or_lt n i
    · apply Ideal.mul_le_right.trans ((Ideal.pow_le_pow_right h).trans hn)
    · 

Proof state:
case h.inr
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h✝ : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
i : ℕ
x✝ : i ∈ Finset.range (n + m + 1)
h : i < n
⊢ J ^ i * K ^ (n + m - i) ≤ I

Next tactic:
apply Ideal.mul_le_left.trans
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 _ => Ideal.mul_le_right.trans _
    obtain h | h := le_or_lt n i
    · apply Ideal.mul_le_right.trans ((Ideal.pow_le_pow_right h).trans hn)
    · apply Ideal.mul_le_left.trans
      

Proof state:
case h.inr
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h✝ : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
i : ℕ
x✝ : i ∈ Finset.range (n + m + 1)
h : i < n
⊢ K ^ (n + m - i) ≤ I

Next tactic:
refine' (Ideal.pow_le_pow_right _).trans hm
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 _ => Ideal.mul_le_right.trans _
    obtain h | h := le_or_lt n i
    · apply Ideal.mul_le_right.trans ((Ideal.pow_le_pow_right h).trans hn)
    · apply Ideal.mul_le_left.trans
      refine' (Ideal.pow_le_pow_right _).trans hm
      

Proof state:
case h.inr
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h✝ : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
i : ℕ
x✝ : i ∈ Finset.range (n + m + 1)
h : i < n
⊢ m ≤ n + m - i

Next tactic:
rw [add_comm, Nat.add_sub_assoc h.le]
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 _ => Ideal.mul_le_right.trans _
    obtain h | h := le_or_lt n i
    · apply Ideal.mul_le_right.trans ((Ideal.pow_le_pow_right h).trans hn)
    · apply Ideal.mul_le_left.trans
      refine' (Ideal.pow_le_pow_right _).trans hm
      rw [add_comm, Nat.add_sub_assoc h.le]
      

Proof state:
case h.inr
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h✝ : FG (radical I)
J K : Submodule R R
hJ : J ≤ radical I → ∃ n, J ^ n ≤ I
hK : K ≤ radical I → ∃ n, K ^ n ≤ I
hJK : J ⊔ K ≤ radical I
n : ℕ
hn : J ^ n ≤ I
m : ℕ
hm : K ^ m ≤ I
i : ℕ
x✝ : i ∈ Finset.range (n + m + 1)
h : i < n
⊢ m ≤ m + (n - i)

Next tactic:
apply Nat.le_add_right
lemma exists_fin' (R M : Type*) [CommSemiring R] [AddCommMonoid M] [Module R M] [Finite R M] :
    ∃ (n : ℕ) (f : (Fin n → R) →ₗ[R] M), Surjective f := by
  

Proof state:
R✝ : Type u_1
A : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝⁸ : Semiring R✝
inst✝⁷ : AddCommMonoid M✝
inst✝⁶ : Module R✝ M✝
inst✝⁵ : AddCommMonoid N
inst✝⁴ : Module R✝ N
R : Type u_6
M : Type u_7
inst✝³ : CommSemiring R
inst✝² : AddCommMonoid M
inst✝¹ : Module R M
inst✝ : Finite R M
⊢ ∃ n f, Surjective ⇑f

Next tactic:
have ⟨n, s, hs⟩ := exists_fin (R := R) (M := M)
lemma exists_fin' (R M : Type*) [CommSemiring R] [AddCommMonoid M] [Module R M] [Finite R M] :
    ∃ (n : ℕ) (f : (Fin n → R) →ₗ[R] M), Surjective f := by
  have ⟨n, s, hs⟩ := exists_fin (R := R) (M := M)
  

Proof state:
R✝ : Type u_1
A : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝⁸ : Semiring R✝
inst✝⁷ : AddCommMonoid M✝
inst✝⁶ : Module R✝ M✝
inst✝⁵ : AddCommMonoid N
inst✝⁴ : Module R✝ N
R : Type u_6
M : Type u_7
inst✝³ : CommSemiring R
inst✝² : AddCommMonoid M
inst✝¹ : Module R M
inst✝ : Finite R M
n : ℕ
s : Fin n → M
hs : span R (range s) = ⊤
⊢ ∃ n f, Surjective ⇑f

Next tactic:
exact ⟨n, piEquiv (Fin n) R M s, by simpa⟩
lemma exists_fin' (R M : Type*) [CommSemiring R] [AddCommMonoid M] [Module R M] [Finite R M] :
    ∃ (n : ℕ) (f : (Fin n → R) →ₗ[R] M), Surjective f := by
  have ⟨n, s, hs⟩ := exists_fin (R := R) (M := M)
  exact ⟨n, piEquiv (Fin n) R M s, by 

Proof state:
R✝ : Type u_1
A : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝⁸ : Semiring R✝
inst✝⁷ : AddCommMonoid M✝
inst✝⁶ : Module R✝ M✝
inst✝⁵ : AddCommMonoid N
inst✝⁴ : Module R✝ N
R : Type u_6
M : Type u_7
inst✝³ : CommSemiring R
inst✝² : AddCommMonoid M
inst✝¹ : Module R M
inst✝ : Finite R M
n : ℕ
s : Fin n → M
hs : span R (range s) = ⊤
⊢ Surjective ⇑((piEquiv (Fin n) R M) s)

Next tactic:
simpa
theorem of_surjective [hM : Finite R M] (f : M →ₗ[R] N) (hf : Surjective f) : Finite R N :=
  ⟨by
    

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
hM : Finite R M
f : M →ₗ[R] N
hf : Surjective ⇑f
⊢ FG ⊤

Next tactic:
rw [← LinearMap.range_eq_top.2 hf, ← Submodule.map_top]
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]
    

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
hM : Finite R M
f : M →ₗ[R] N
hf : Surjective ⇑f
⊢ FG (map f ⊤)

Next tactic:
exact hM.1.map f
instance self : Finite R R :=
  ⟨⟨{1}, by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
⊢ span R ↑{1} = ⊤

Next tactic:
simpa only [Finset.coe_singleton] using Ideal.span_singleton_one
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
  

Proof state:
R✝ : Type u_1
A✝ : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝¹¹ : Semiring R✝
inst✝¹⁰ : AddCommMonoid M✝
inst✝⁹ : Module R✝ M✝
inst✝⁸ : AddCommMonoid N
inst✝⁷ : Module R✝ N
R : Type u_6
A : Type u_7
M : Type u_8
inst✝⁶ : CommSemiring R
inst✝⁵ : Semiring A
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
inst✝² : Module A M
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A M
hM : Finite R M
⊢ Finite A M

Next tactic:
rw [finite_def, Submodule.fg_def] at hM ⊢
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, Submodule.fg_def] at hM ⊢
  

Proof state:
R✝ : Type u_1
A✝ : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝¹¹ : Semiring R✝
inst✝¹⁰ : AddCommMonoid M✝
inst✝⁹ : Module R✝ M✝
inst✝⁸ : AddCommMonoid N
inst✝⁷ : Module R✝ N
R : Type u_6
A : Type u_7
M : Type u_8
inst✝⁶ : CommSemiring R
inst✝⁵ : Semiring A
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
inst✝² : Module A M
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A M
hM : ∃ S, Set.Finite S ∧ span R S = ⊤
⊢ ∃ S, Set.Finite S ∧ span A S = ⊤

Next tactic:
obtain ⟨S, hSfin, hSgen⟩ := hM
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, Submodule.fg_def] at hM ⊢
  obtain ⟨S, hSfin, hSgen⟩ := hM
  

Proof state:
case intro.intro
R✝ : Type u_1
A✝ : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝¹¹ : Semiring R✝
inst✝¹⁰ : AddCommMonoid M✝
inst✝⁹ : Module R✝ M✝
inst✝⁸ : AddCommMonoid N
inst✝⁷ : Module R✝ N
R : Type u_6
A : Type u_7
M : Type u_8
inst✝⁶ : CommSemiring R
inst✝⁵ : Semiring A
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
inst✝² : Module A M
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A M
S : Set M
hSfin : Set.Finite S
hSgen : span R S = ⊤
⊢ ∃ S, Set.Finite S ∧ span A S = ⊤

Next tactic:
refine' ⟨S, hSfin, eq_top_iff.2 _⟩
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, Submodule.fg_def] at hM ⊢
  obtain ⟨S, hSfin, hSgen⟩ := hM
  refine' ⟨S, hSfin, eq_top_iff.2 _⟩
  

Proof state:
case intro.intro
R✝ : Type u_1
A✝ : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝¹¹ : Semiring R✝
inst✝¹⁰ : AddCommMonoid M✝
inst✝⁹ : Module R✝ M✝
inst✝⁸ : AddCommMonoid N
inst✝⁷ : Module R✝ N
R : Type u_6
A : Type u_7
M : Type u_8
inst✝⁶ : CommSemiring R
inst✝⁵ : Semiring A
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
inst✝² : Module A M
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A M
S : Set M
hSfin : Set.Finite S
hSgen : span R S = ⊤
⊢ ⊤ ≤ span A S

Next tactic:
have := Submodule.span_le_restrictScalars R A S
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, Submodule.fg_def] at hM ⊢
  obtain ⟨S, hSfin, hSgen⟩ := hM
  refine' ⟨S, hSfin, eq_top_iff.2 _⟩
  have := Submodule.span_le_restrictScalars R A S
  

Proof state:
case intro.intro
R✝ : Type u_1
A✝ : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝¹¹ : Semiring R✝
inst✝¹⁰ : AddCommMonoid M✝
inst✝⁹ : Module R✝ M✝
inst✝⁸ : AddCommMonoid N
inst✝⁷ : Module R✝ N
R : Type u_6
A : Type u_7
M : Type u_8
inst✝⁶ : CommSemiring R
inst✝⁵ : Semiring A
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
inst✝² : Module A M
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A M
S : Set M
hSfin : Set.Finite S
hSgen : span R S = ⊤
this : span R S ≤ restrictScalars R (span A S)
⊢ ⊤ ≤ span A S

Next tactic:
rw [hSgen] at this
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, Submodule.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
  

Proof state:
case intro.intro
R✝ : Type u_1
A✝ : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝¹¹ : Semiring R✝
inst✝¹⁰ : AddCommMonoid M✝
inst✝⁹ : Module R✝ M✝
inst✝⁸ : AddCommMonoid N
inst✝⁷ : Module R✝ N
R : Type u_6
A : Type u_7
M : Type u_8
inst✝⁶ : CommSemiring R
inst✝⁵ : Semiring A
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
inst✝² : Module A M
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A M
S : Set M
hSfin : Set.Finite S
hSgen : span R S = ⊤
this : ⊤ ≤ restrictScalars R (span A S)
⊢ ⊤ ≤ span A S

Next tactic:
exact this
instance prod [hM : Finite R M] [hN : Finite R N] : Finite R (M × N) :=
  ⟨by
    

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
hM : Finite R M
hN : Finite R N
⊢ FG ⊤

Next tactic:
rw [← Submodule.prod_top]
instance prod [hM : Finite R M] [hN : Finite R N] : Finite R (M × N) :=
  ⟨by
    rw [← Submodule.prod_top]
    

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M : Type u_4
N : Type u_5
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : AddCommMonoid N
inst✝ : Module R N
hM : Finite R M
hN : Finite R N
⊢ FG (Submodule.prod ⊤ ⊤)

Next tactic:
exact hM.1.prod hN.1
instance pi {ι : Type*} {M : ι → Type*} [_root_.Finite ι] [∀ i, AddCommMonoid (M i)]
    [∀ i, Module R (M i)] [h : ∀ i, Finite R (M i)] : Finite R (∀ i, M i) :=
  ⟨by
    

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
M✝ : Type u_4
N : Type u_5
inst✝⁷ : Semiring R
inst✝⁶ : AddCommMonoid M✝
inst✝⁵ : Module R M✝
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
ι : Type u_6
M : ι → Type u_7
inst✝² : _root_.Finite ι
inst✝¹ : (i : ι) → AddCommMonoid (M i)
inst✝ : (i : ι) → Module R (M i)
h : ∀ (i : ι), Finite R (M i)
⊢ FG ⊤

Next tactic:
rw [← Submodule.pi_top]