-- Mathlib/LinearAlgebra/TensorProduct/Finiteness.lean
theorem exists_finite_submodule_of_finite (s : Set (M ⊗[R] N)) (hs : s.Finite) :
    ∃ (M' : Submodule R M) (N' : Submodule R N), Module.Finite R M' ∧ Module.Finite R N' ∧
      s ⊆ LinearMap.range (mapIncl M' N')

Proof state:
case intro.intro.intro.intro.refine_3.intro.intro.intro.intro.intro.intro.intro.intro.refine_2
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
x y : M ⊗[R] N
M₁' : Submodule R M
N₁' : Submodule R N
hM₁' : M₁'.FG
hN₁' : N₁'.FG
h₁ : insert x s ⊆ ↑(LinearMap.range (mapIncl M₁' N₁'))
M₂' : Submodule R M
N₂' : Submodule R N
hM₂' : M₂'.FG
hN₂' : N₂'.FG
h₂ : insert y s ⊆ ↑(LinearMap.range (mapIncl M₂' N₂'))
⊢ y ∈ LinearMap.range (mapIncl (M₁' ⊔ M₂') (N₁' ⊔ N₂'))

Tactic:
exact range_mapIncl_mono le_sup_right le_sup_right (h₂ (Set.mem_insert y s))

Result:
no goals

Proof state:
case intro.intro.intro.intro.refine_2.refine_2
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
x : M
y : N
z : M ⊗[R] N
hz : z ∈ s
⊢ z ∈ ↑(LinearMap.range (mapIncl (M' ⊔ span R {x}) (N' ⊔ span R {y})))

Tactic:
exact range_mapIncl_mono le_sup_left le_sup_left (h hz)

Result:
no goals

Proof state:
case intro.intro.intro.intro.refine_3.intro.intro.intro.intro.intro.intro.intro.intro.refine_1
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
x y : M ⊗[R] N
M₁' : Submodule R M
N₁' : Submodule R N
hM₁' : M₁'.FG
hN₁' : N₁'.FG
h₁ : insert x s ⊆ ↑(LinearMap.range (mapIncl M₁' N₁'))
M₂' : Submodule R M
N₂' : Submodule R N
hM₂' : M₂'.FG
hN₂' : N₂'.FG
h₂ : insert y s ⊆ ↑(LinearMap.range (mapIncl M₂' N₂'))
⊢ x ∈ LinearMap.range (mapIncl (M₁' ⊔ M₂') (N₁' ⊔ N₂'))

Tactic:
exact range_mapIncl_mono le_sup_left le_sup_left (h₁ (Set.mem_insert x s))

Result:
no goals

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s : Set (M ⊗[R] N)
hs : s.Finite
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Tactic:
refine hs.induction_on _ ⟨_, _, fg_bot, fg_bot, Set.empty_subset _⟩ ?_

Result:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s : Set (M ⊗[R] N)
hs : s.Finite
⊢ ∀ {a : M ⊗[R] N} {s : Set (M ⊗[R] N)},
    a ∉ s →
      s.Finite →
        (∃ M' N', M'.FG ∧ N'.FG ∧ s ⊆ ↑(LinearMap.range (mapIncl M' N'))) →
          ∃ M' N', M'.FG ∧ N'.FG ∧ insert a s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Proof state:
case intro.intro.intro.intro
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ insert a s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Tactic:
refine TensorProduct.induction_on a ?_ (fun x y ↦ ?_) fun x y hx hy ↦ ?_

Result:
case intro.intro.intro.intro.refine_1
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ insert 0 s ⊆ ↑(LinearMap.range (mapIncl M' N'))

case intro.intro.intro.intro.refine_2
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
x : M
y : N
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ insert (x ⊗ₜ[R] y) s ⊆ ↑(LinearMap.range (mapIncl M' N'))

case intro.intro.intro.intro.refine_3
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
x y : M ⊗[R] N
hx : ∃ M' N', M'.FG ∧ N'.FG ∧ insert x s ⊆ ↑(LinearMap.range (mapIncl M' N'))
hy : ∃ M' N', M'.FG ∧ N'.FG ∧ insert y s ⊆ ↑(LinearMap.range (mapIncl M' N'))
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ insert (x + y) s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s : Set (M ⊗[R] N)
hs : s.Finite
⊢ ∀ {a : M ⊗[R] N} {s : Set (M ⊗[R] N)},
    a ∉ s →
      s.Finite →
        (∃ M' N', M'.FG ∧ N'.FG ∧ s ⊆ ↑(LinearMap.range (mapIncl M' N'))) →
          ∃ M' N', M'.FG ∧ N'.FG ∧ insert a s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Tactic:
rintro a s - - ⟨M', N', hM', hN', h⟩

Result:
case intro.intro.intro.intro
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ insert a s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s : Set (M ⊗[R] N)
hs : s.Finite
⊢ ∃ M' N', Module.Finite R ↥M' ∧ Module.Finite R ↥N' ∧ s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Tactic:
simp_rw [Module.Finite.iff_fg]

Result:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s : Set (M ⊗[R] N)
hs : s.Finite
⊢ ∃ M' N', M'.FG ∧ N'.FG ∧ s ⊆ ↑(LinearMap.range (mapIncl M' N'))

Proof state:
case intro.intro.intro.intro.refine_3.intro.intro.intro.intro.intro.intro.intro.intro.refine_3
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : AddCommMonoid N
inst✝¹ : Module R M
inst✝ : Module R N
s✝ : Set (M ⊗[R] N)
hs : s✝.Finite
a : M ⊗[R] N
s : Set (M ⊗[R] N)
M' : Submodule R M
N' : Submodule R N
hM' : M'.FG
hN' : N'.FG
h : s ⊆ ↑(LinearMap.range (mapIncl M' N'))
x y : M ⊗[R] N
M₁' : Submodule R M
N₁' : Submodule R N
hM₁' : M₁'.FG
hN₁' : N₁'.FG
h₁ : insert x s ⊆ ↑(LinearMap.range (mapIncl M₁' N₁'))
M₂' : Submodule R M
N₂' : Submodule R N
hM₂' : M₂'.FG
hN₂' : N₂'.FG
h₂ : insert y s ⊆ ↑(LinearMap.range (mapIncl M₂' N₂'))
z : M ⊗[R] N
hz : z ∈ s
⊢ z ∈ ↑(LinearMap.range (mapIncl (M₁' ⊔ M₂') (N₁' ⊔ N₂')))

Tactic:
exact range_mapIncl_mono le_sup_left le_sup_left (h₁ (Set.subset_insert x s hz))

Result:
no goals