-- Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean
theorem LinearMap.lTensor_range :
    range (lTensor Q g) =
      range (lTensor Q (Submodule.subtype (range g)))

Proof state:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q (range g).subtype ∘ₗ lTensor Q g.rangeRestrict) = range (lTensor Q (range g).subtype)

Tactic:
apply range_comp_of_range_eq_top

Result:
case hf
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q g.rangeRestrict) = ⊤

Proof state:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q g) = range (lTensor Q (range g).subtype)

Tactic:
nth_rewrite 1 [this]

Result:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q ((range g).subtype ∘ₗ g.rangeRestrict)) = range (lTensor Q (range g).subtype)

Proof state:
case hf
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q g.rangeRestrict) = ⊤

Tactic:
rw [range_eq_top]

Result:
case hf
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ Function.Surjective ⇑(lTensor Q g.rangeRestrict)

Proof state:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
⊢ range (lTensor Q g) = range (lTensor Q (range g).subtype)

Tactic:
have : g = (Submodule.subtype _).comp g.rangeRestrict := rfl

Result:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q g) = range (lTensor Q (range g).subtype)

Proof state:
case hf
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ Function.Surjective ⇑(lTensor Q g.rangeRestrict)

Tactic:
apply lTensor_surjective

Result:
case hf.hg
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ Function.Surjective ⇑g.rangeRestrict

Proof state:
case hf.hg
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ Function.Surjective ⇑g.rangeRestrict

Tactic:
rw [← range_eq_top, range_rangeRestrict]

Result:
no goals

Proof state:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q ((range g).subtype ∘ₗ g.rangeRestrict)) = range (lTensor Q (range g).subtype)

Tactic:
rw [lTensor_comp]

Result:
R : Type u_1
inst✝⁶ : CommSemiring R
N : Type u_3
P : Type u_4
Q : Type u_5
inst✝⁵ : AddCommMonoid N
inst✝⁴ : AddCommMonoid P
inst✝³ : AddCommMonoid Q
inst✝² : Module R N
inst✝¹ : Module R P
inst✝ : Module R Q
g : N →ₗ[R] P
this : g = (range g).subtype ∘ₗ g.rangeRestrict
⊢ range (lTensor Q (range g).subtype ∘ₗ lTensor Q g.rangeRestrict) = range (lTensor Q (range g).subtype)