-- Mathlib/LinearAlgebra/Dimension/LinearMap.lean
theorem le_rank_iff_exists_linearIndependent {c : Cardinal} {f : V →ₗ[K] V'} :
    c ≤ rank f ↔ ∃ s : Set V,
    Cardinal.lift.{v'} #s = Cardinal.lift.{v} c ∧ LinearIndepOn K f s

Proof state:
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
⊢ c ≤ f.rank ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

Tactic:
rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩

Result:
case intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
⊢ c ≤ f.rank ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

Proof state:
case intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
⊢ c ≤ f.rank ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

Tactic:
have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg

Result:
case intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
⊢ c ≤ f.rank ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

Proof state:
case intro.refine_1
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
h : c ≤ f.rank
⊢ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

Tactic:
rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩

Result:
case intro.refine_1.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set ↥(range f)
si : LinearIndepOn K _root_.id s
h : #↑s ≤ f.rank
⊢ ∃ s_1, lift.{v', v} #↑s_1 = lift.{v, v'} #↑s ∧ LinearIndepOn K (⇑f) s_1

Proof state:
case intro.refine_2
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
⊢ (∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s) → c ≤ f.rank

Tactic:
rintro ⟨s, hsc, si⟩

Result:
case intro.refine_2.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set V
hsc : lift.{v', v} #↑s = lift.{v, v'} c
si : LinearIndepOn K (⇑f) s
⊢ c ≤ f.rank

Proof state:
case intro.refine_1.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set ↥(range f)
si : LinearIndepOn K _root_.id s
h : #↑s ≤ f.rank
⊢ ∃ s_1, lift.{v', v} #↑s_1 = lift.{v, v'} #↑s ∧ LinearIndepOn K (⇑f) s_1

Tactic:
refine ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, ?_⟩

Result:
case intro.refine_1.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set ↥(range f)
si : LinearIndepOn K _root_.id s
h : #↑s ≤ f.rank
⊢ LinearIndepOn K (⇑f) (⇑g '' s)

Proof state:
case intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
⊢ c ≤ f.rank ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

Tactic:
refine ⟨fun h => ?_, ?_⟩

Result:
case intro.refine_1
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
h : c ≤ f.rank
⊢ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s

case intro.refine_2
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
⊢ (∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndepOn K (⇑f) s) → c ≤ f.rank

Proof state:
case intro.refine_2.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set V
hsc : lift.{v', v} #↑s = lift.{v, v'} c
si : LinearIndepOn K (⇑f) s
this : LinearIndepOn K (⇑f.rangeRestrict) s
⊢ c ≤ f.rank

Tactic:
convert this.id_image.cardinal_le_rank

Result:
case h.e'_3
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set V
hsc : lift.{v', v} #↑s = lift.{v, v'} c
si : LinearIndepOn K (⇑f) s
this : LinearIndepOn K (⇑f.rangeRestrict) s
⊢ c = #↑(⇑f.rangeRestrict '' s)

Proof state:
case intro.refine_1.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set ↥(range f)
si : LinearIndepOn K _root_.id s
h : #↑s ≤ f.rank
⊢ LinearIndepOn K (⇑f) (⇑g '' s)

Tactic:
replace fg : ∀ x, f (g x) = x := by
  intro x
  convert congr_arg Subtype.val (fg x)

Result:
case intro.refine_1.intro.intro
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
s : Set ↥(range f)
si : LinearIndepOn K _root_.id s
h : #↑s ≤ f.rank
fg : ∀ (x : ↥(range f)), f (g x) = ↑x
⊢ LinearIndepOn K (⇑f) (⇑g '' s)

Proof state:
case h.e'_3.h
K : Type u
V : Type v
V' : Type v'
inst✝⁴ : DivisionRing K
inst✝³ : AddCommGroup V
inst✝² : Module K V
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : f.rangeRestrict ∘ₗ g = id
fg : LeftInverse ⇑f.rangeRestrict ⇑g
s : Set V
hsc : lift.{v', v} #↑s = lift.{v, v'} c
si : LinearIndepOn K (⇑f) s
this : LinearIndepOn K (⇑f.rangeRestrict) s
⊢ InjOn (⇑f.rangeRestrict) s

Tactic:
exact injOn_iff_injective.2 this.injective

Result:
no goals