l3lab/ntp-mathlib huggingface dataset:
theorem Submodule.rank_le_one_iff_isPrincipal (W : Submodule K V) :
    Module.rank K W ≤ 1 ↔ W.IsPrincipal := by
  simp only [rank_le_one_iff, Submodule.IsPrincipal_iff, le_antisymm_iff, le_span_singleton_iff,
    span_singleton_le_iff_mem]
  constructor
  · rintro ⟨⟨m, hm⟩, hm'⟩
    choose f hf using hm'
    exact ⟨m, ⟨fun v hv => ⟨f ⟨v, hv⟩, congr_arg ((↑) : W → V) (hf ⟨v, hv⟩)⟩, hm⟩⟩
  · 

Proof state:
case mpr
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
W : Submodule K V
⊢ (∃ a, (∀ v ∈ W, ∃ r, r • a = v) ∧ a ∈ W) → ∃ v₀, ∀ (v : ↥W), ∃ r, r • v₀ = v

Next tactic:
rintro ⟨a, ⟨h, ha⟩⟩
theorem Submodule.rank_le_one_iff_isPrincipal (W : Submodule K V) :
    Module.rank K W ≤ 1 ↔ W.IsPrincipal := by
  simp only [rank_le_one_iff, Submodule.IsPrincipal_iff, le_antisymm_iff, le_span_singleton_iff,
    span_singleton_le_iff_mem]
  constructor
  · rintro ⟨⟨m, hm⟩, hm'⟩
    choose f hf using hm'
    exact ⟨m, ⟨fun v hv => ⟨f ⟨v, hv⟩, congr_arg ((↑) : W → V) (hf ⟨v, hv⟩)⟩, hm⟩⟩
  · rintro ⟨a, ⟨h, ha⟩⟩
    

Proof state:
case mpr.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
W : Submodule K V
a : V
h : ∀ v ∈ W, ∃ r, r • a = v
ha : a ∈ W
⊢ ∃ v₀, ∀ (v : ↥W), ∃ r, r • v₀ = v

Next tactic:
choose f hf using h
theorem Submodule.rank_le_one_iff_isPrincipal (W : Submodule K V) :
    Module.rank K W ≤ 1 ↔ W.IsPrincipal := by
  simp only [rank_le_one_iff, Submodule.IsPrincipal_iff, le_antisymm_iff, le_span_singleton_iff,
    span_singleton_le_iff_mem]
  constructor
  · rintro ⟨⟨m, hm⟩, hm'⟩
    choose f hf using hm'
    exact ⟨m, ⟨fun v hv => ⟨f ⟨v, hv⟩, congr_arg ((↑) : W → V) (hf ⟨v, hv⟩)⟩, hm⟩⟩
  · rintro ⟨a, ⟨h, ha⟩⟩
    choose f hf using h
    

Proof state:
case mpr.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
W : Submodule K V
a : V
ha : a ∈ W
f : (v : V) → v ∈ W → K
hf : ∀ (v : V) (a_1 : v ∈ W), f v a_1 • a = v
⊢ ∃ v₀, ∀ (v : ↥W), ∃ r, r • v₀ = v

Next tactic:
exact ⟨⟨a, ha⟩, fun v => ⟨f v.1 v.2, Subtype.ext (hf v.1 v.2)⟩⟩
theorem Module.rank_le_one_iff_top_isPrincipal :
    Module.rank K V ≤ 1 ↔ (⊤ : Submodule K V).IsPrincipal := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
⊢ Module.rank K V ≤ 1 ↔ IsPrincipal ⊤

Next tactic:
rw [← Submodule.rank_le_one_iff_isPrincipal, rank_top]
@[simp]
theorem rank_zero [Nontrivial K] : rank (0 : V →ₗ[K] V') = 0 := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁷ : Ring K
inst✝⁶ : AddCommGroup V
inst✝⁵ : Module K V
inst✝⁴ : AddCommGroup V₁
inst✝³ : Module K V₁
inst✝² : AddCommGroup V'
inst✝¹ : Module K V'
inst✝ : Nontrivial K
⊢ rank 0 = 0

Next tactic:
rw [rank, LinearMap.range_zero, rank_bot]
theorem rank_comp_le_left (g : V →ₗ[K] V') (f : V' →ₗ[K] V'') : rank (f.comp g) ≤ rank f := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁸ : Ring K
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module K V
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : Module K V₁
inst✝³ : AddCommGroup V'
inst✝² : Module K V'
inst✝¹ : AddCommGroup V''
inst✝ : Module K V''
g : V →ₗ[K] V'
f : V' →ₗ[K] V''
⊢ rank (f ∘ₗ g) ≤ rank f

Next tactic:
refine' rank_le_of_submodule _ _ _
theorem rank_comp_le_left (g : V →ₗ[K] V') (f : V' →ₗ[K] V'') : rank (f.comp g) ≤ rank f := by
  refine' rank_le_of_submodule _ _ _
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁸ : Ring K
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module K V
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : Module K V₁
inst✝³ : AddCommGroup V'
inst✝² : Module K V'
inst✝¹ : AddCommGroup V''
inst✝ : Module K V''
g : V →ₗ[K] V'
f : V' →ₗ[K] V''
⊢ range (f ∘ₗ g) ≤ range f

Next tactic:
rw [LinearMap.range_comp]
theorem rank_comp_le_left (g : V →ₗ[K] V') (f : V' →ₗ[K] V'') : rank (f.comp g) ≤ rank f := by
  refine' rank_le_of_submodule _ _ _
  rw [LinearMap.range_comp]
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁸ : Ring K
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module K V
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : Module K V₁
inst✝³ : AddCommGroup V'
inst✝² : Module K V'
inst✝¹ : AddCommGroup V''
inst✝ : Module K V''
g : V →ₗ[K] V'
f : V' →ₗ[K] V''
⊢ Submodule.map f (range g) ≤ range f

Next tactic:
exact LinearMap.map_le_range
theorem lift_rank_comp_le_right (g : V →ₗ[K] V') (f : V' →ₗ[K] V'') :
    Cardinal.lift.{v'} (rank (f.comp g)) ≤ Cardinal.lift.{v''} (rank g) := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁸ : Ring K
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module K V
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : Module K V₁
inst✝³ : AddCommGroup V'
inst✝² : Module K V'
inst✝¹ : AddCommGroup V''
inst✝ : Module K V''
g : V →ₗ[K] V'
f : V' →ₗ[K] V''
⊢ lift.{v', v''} (rank (f ∘ₗ g)) ≤ lift.{v'', v'} (rank g)

Next tactic:
rw [rank, rank, LinearMap.range_comp]
theorem lift_rank_comp_le_right (g : V →ₗ[K] V') (f : V' →ₗ[K] V'') :
    Cardinal.lift.{v'} (rank (f.comp g)) ≤ Cardinal.lift.{v''} (rank g) := by
  rw [rank, rank, LinearMap.range_comp]; 

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁸ : Ring K
inst✝⁷ : AddCommGroup V
inst✝⁶ : Module K V
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : Module K V₁
inst✝³ : AddCommGroup V'
inst✝² : Module K V'
inst✝¹ : AddCommGroup V''
inst✝ : Module K V''
g : V →ₗ[K] V'
f : V' →ₗ[K] V''
⊢ lift.{v', v''} (Module.rank K ↥(Submodule.map f (range g))) ≤ lift.{v'', v'} (Module.rank K ↥(range g))

Next tactic:
exact lift_rank_map_le _ _
theorem rank_comp_le_right (g : V →ₗ[K] V') (f : V' →ₗ[K] V'₁) : rank (f.comp g) ≤ rank g := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝¹⁰ : Ring K
inst✝⁹ : AddCommGroup V
inst✝⁸ : Module K V
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : Module K V₁
inst✝⁵ : AddCommGroup V'
inst✝⁴ : Module K V'
inst✝³ : AddCommGroup V''
inst✝² : Module K V''
inst✝¹ : AddCommGroup V'₁
inst✝ : Module K V'₁
g : V →ₗ[K] V'
f : V' →ₗ[K] V'₁
⊢ rank (f ∘ₗ g) ≤ rank g

Next tactic:
simpa only [Cardinal.lift_id] using lift_rank_comp_le_right g f
/-- The rank of the composition of two maps is less than the minimum of their ranks.

See `lift_rank_comp_le` for the universe-polymorphic version. -/
theorem rank_comp_le (g : V →ₗ[K] V') (f : V' →ₗ[K] V'₁) :
    rank (f.comp g) ≤ min (rank f) (rank g) := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝¹⁰ : Ring K
inst✝⁹ : AddCommGroup V
inst✝⁸ : Module K V
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : Module K V₁
inst✝⁵ : AddCommGroup V'
inst✝⁴ : Module K V'
inst✝³ : AddCommGroup V''
inst✝² : Module K V''
inst✝¹ : AddCommGroup V'₁
inst✝ : Module K V'₁
g : V →ₗ[K] V'
f : V' →ₗ[K] V'₁
⊢ rank (f ∘ₗ g) ≤ min (rank f) (rank g)

Next tactic:
simpa only [Cardinal.lift_id] using lift_rank_comp_le g f
theorem rank_add_le (f g : V →ₗ[K] V') : rank (f + g) ≤ rank f + rank g :=
  calc
    rank (f + g) ≤ Module.rank K (LinearMap.range f ⊔ LinearMap.range g : Submodule K V') := by
      

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f g : V →ₗ[K] V'
⊢ rank (f + g) ≤ Module.rank K ↥(range f ⊔ range g)

Next tactic:
refine' rank_le_of_submodule _ _ _
theorem rank_add_le (f g : V →ₗ[K] V') : rank (f + g) ≤ rank f + rank g :=
  calc
    rank (f + g) ≤ Module.rank K (LinearMap.range f ⊔ LinearMap.range g : Submodule K V') := by
      refine' rank_le_of_submodule _ _ _
      

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f g : V →ₗ[K] V'
⊢ range (f + g) ≤ range f ⊔ range g

Next tactic:
exact LinearMap.range_le_iff_comap.2 <| eq_top_iff'.2 fun x =>
        show f x + g x ∈ (LinearMap.range f ⊔ LinearMap.range g : Submodule K V') from
        mem_sup.2 ⟨_, ⟨x, rfl⟩, _, ⟨x, rfl⟩, rfl⟩
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 ∧ LinearIndependent K fun x : s => f x := by
  

Proof state:
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
c : Cardinal.{v'}
f : V →ₗ[K] V'
⊢ c ≤ rank f ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndependent K fun (x : ↑s) => f ↑x

Next tactic:
rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  

Proof state:
case intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
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 : rangeRestrict f ∘ₗ g = id
⊢ c ≤ rank f ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndependent K fun (x : ↑s) => f ↑x

Next tactic:
have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  

Proof state:
case intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
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 : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
⊢ c ≤ rank f ↔ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndependent K fun (x : ↑s) => f ↑x

Next tactic:
refine' ⟨fun h => _, _⟩
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · 

Proof state:
case intro.refine'_1
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
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 : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
h : c ≤ rank f
⊢ ∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndependent K fun (x : ↑s) => f ↑x

Next tactic:
rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    

Proof state:
case intro.refine'_1.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
s : Set ↥(range f)
si : LinearIndependent (ι := { x // x ∈ s }) K Subtype.val
h : #↑s ≤ rank f
⊢ ∃ s_1, lift.{v', v} #↑s_1 = lift.{v, v'} #↑s ∧ LinearIndependent K fun (x : ↑s_1) => f ↑x

Next tactic:
refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    

Proof state:
case intro.refine'_1.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
s : Set ↥(range f)
si : LinearIndependent (ι := { x // x ∈ s }) K Subtype.val
h : #↑s ≤ rank f
⊢ LinearIndependent K fun (x : ↑(⇑g '' s)) => f ↑x

Next tactic:
replace fg : ∀ x, f (g x) = x
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · 

Proof state:
case fg
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
s : Set ↥(range f)
si : LinearIndependent (ι := { x // x ∈ s }) K Subtype.val
h : #↑s ≤ rank f
⊢ ∀ (x : ↥(range f)), f (g x) = ↑x

Next tactic:
intro x
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · intro x
      

Proof state:
case fg
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
s : Set ↥(range f)
si : LinearIndependent (ι := { x // x ∈ s }) K Subtype.val
h : #↑s ≤ rank f
x : ↥(range f)
⊢ f (g x) = ↑x

Next tactic:
convert congr_arg Subtype.val (fg x)
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · intro x
      convert congr_arg Subtype.val (fg x)
    

Proof state:
case intro.refine'_1.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
s : Set ↥(range f)
si : LinearIndependent (ι := { x // x ∈ s }) K Subtype.val
h : #↑s ≤ rank f
fg : ∀ (x : ↥(range f)), f (g x) = ↑x
⊢ LinearIndependent K fun (x : ↑(⇑g '' s)) => f ↑x

Next tactic:
replace si : LinearIndependent K fun x : s => f (g x)
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · intro x
      convert congr_arg Subtype.val (fg x)
    replace si : LinearIndependent K fun x : s => f (g x)
    · 

Proof state:
case si
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
s : Set ↥(range f)
si : LinearIndependent (ι := { x // x ∈ s }) K Subtype.val
h : #↑s ≤ rank f
fg : ∀ (x : ↥(range f)), f (g x) = ↑x
⊢ LinearIndependent K fun (x : ↑s) => f (g ↑x)

Next tactic:
simpa only [fg] using si.map' _ (ker_subtype _)
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · intro x
      convert congr_arg Subtype.val (fg x)
    replace si : LinearIndependent K fun x : s => f (g x)
    · simpa only [fg] using si.map' _ (ker_subtype _)
    

Proof state:
case intro.refine'_1.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
inst✝³ : AddCommGroup V₁
inst✝² : Module K V₁
inst✝¹ : AddCommGroup V'
inst✝ : Module K V'
f : V →ₗ[K] V'
g : ↥(range f) →ₗ[K] V
hg : rangeRestrict f ∘ₗ g = id
s : Set ↥(range f)
h : #↑s ≤ rank f
fg : ∀ (x : ↥(range f)), f (g x) = ↑x
si : LinearIndependent K fun (x : ↑s) => f (g ↑x)
⊢ LinearIndependent K fun (x : ↑(⇑g '' s)) => f ↑x

Next tactic:
exact si.image_of_comp s g f
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · intro x
      convert congr_arg Subtype.val (fg x)
    replace si : LinearIndependent K fun x : s => f (g x)
    · simpa only [fg] using si.map' _ (ker_subtype _)
    exact si.image_of_comp s g f
  · 

Proof state:
case intro.refine'_2
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
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 : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
⊢ (∃ s, lift.{v', v} #↑s = lift.{v, v'} c ∧ LinearIndependent K fun (x : ↑s) => f ↑x) → c ≤ rank f

Next tactic:
rintro ⟨s, hsc, si⟩
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 ∧ LinearIndependent K fun x : s => f x := by
  rcases f.rangeRestrict.exists_rightInverse_of_surjective f.range_rangeRestrict with ⟨g, hg⟩
  have fg : LeftInverse f.rangeRestrict g := LinearMap.congr_fun hg
  refine' ⟨fun h => _, _⟩
  · rcases _root_.le_rank_iff_exists_linearIndependent.1 h with ⟨s, rfl, si⟩
    refine' ⟨g '' s, Cardinal.mk_image_eq_lift _ _ fg.injective, _⟩
    replace fg : ∀ x, f (g x) = x
    · intro x
      convert congr_arg Subtype.val (fg x)
    replace si : LinearIndependent K fun x : s => f (g x)
    · simpa only [fg] using si.map' _ (ker_subtype _)
    exact si.image_of_comp s g f
  · rintro ⟨s, hsc, si⟩
    

Proof state:
case intro.refine'_2.intro.intro
K R : Type u
V V₁ V₂ V₃ : Type v
V' V'₁ : Type v'
V'' : Type v''
ι : Type w
ι' : Type w'
η : Type u₁'
φ : η → Type u_1
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup V
inst✝⁴ : Module K V
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 : rangeRestrict f ∘ₗ g = id
fg : LeftInverse ⇑(rangeRestrict f) ⇑g
s : Set V
hsc : lift.{v', v} #↑s = lift.{v, v'} c
si : LinearIndependent K fun (x : ↑s) => f ↑x
⊢ c ≤ rank f

Next tactic:
have : LinearIndependent K fun x : s => f.rangeRestrict x :=
      LinearIndependent.of_comp f.range.subtype (by convert si)