l3lab/ntp-mathlib huggingface dataset:
instance Pi.infinite_of_left {ι : Sort*} {π : ι → Sort _} [∀ i, Nontrivial <| π i] [Infinite ι] :
    Infinite (∀ i : ι, π i) := by
  choose m n hm using fun i => exists_pair_ne (π i)
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : ι → Type ?u.7233
inst✝¹ : ∀ (i : ι), Nontrivial (π i)
inst✝ : Infinite ι
m n : (i : ι) → π i
hm : ∀ (i : ι), m i ≠ n i
⊢ Infinite ((i : ι) → π i)

Next tactic:
refine' Infinite.of_injective (fun i => update m i (n i)) fun x y h => of_not_not fun hne => _
instance Pi.infinite_of_left {ι : Sort*} {π : ι → Sort _} [∀ i, Nontrivial <| π i] [Infinite ι] :
    Infinite (∀ i : ι, π i) := by
  choose m n hm using fun i => exists_pair_ne (π i)
  refine' Infinite.of_injective (fun i => update m i (n i)) fun x y h => of_not_not fun hne => _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : ι → Type ?u.7233
inst✝¹ : ∀ (i : ι), Nontrivial (π i)
inst✝ : Infinite ι
m n : (i : ι) → π i
hm : ∀ (i : ι), m i ≠ n i
x y : ι
h : (fun i => update m i (n i)) x = (fun i => update m i (n i)) y
hne : ¬x = y
⊢ False

Next tactic:
simp_rw [update_eq_iff, update_noteq hne] at h
instance Pi.infinite_of_left {ι : Sort*} {π : ι → Sort _} [∀ i, Nontrivial <| π i] [Infinite ι] :
    Infinite (∀ i : ι, π i) := by
  choose m n hm using fun i => exists_pair_ne (π i)
  refine' Infinite.of_injective (fun i => update m i (n i)) fun x y h => of_not_not fun hne => _
  simp_rw [update_eq_iff, update_noteq hne] at h
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
π : ι → Type ?u.7233
inst✝¹ : ∀ (i : ι), Nontrivial (π i)
inst✝ : Infinite ι
m n : (i : ι) → π i
hm : ∀ (i : ι), m i ≠ n i
x y : ι
hne : ¬x = y
h : n x = m x ∧ ∀ (x_1 : ι), x_1 ≠ x → m x_1 = update m y (n y) x_1
⊢ False

Next tactic:
exact (hm x h.1.symm).elim
theorem LinearMap.lift_rank_le_of_injective (f : M →ₗ[R] M') (i : Injective f) :
    Cardinal.lift.{v'} (Module.rank R M) ≤ Cardinal.lift.{v} (Module.rank R M') := 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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
i : Injective ⇑f
⊢ lift.{v', v} (Module.rank R M) ≤ lift.{v, v'} (Module.rank R M')

Next tactic:
simp only [Module.rank_def]
theorem LinearMap.lift_rank_le_of_injective (f : M →ₗ[R] M') (i : Injective f) :
    Cardinal.lift.{v'} (Module.rank R M) ≤ Cardinal.lift.{v} (Module.rank R M') := by
  simp only [Module.rank_def]
  

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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
i : Injective ⇑f
⊢ lift.{v', v} (⨆ ι, #↑↑ι) ≤ lift.{v, v'} (⨆ ι, #↑↑ι)

Next tactic:
rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _),
    Cardinal.lift_iSup (Cardinal.bddAbove_range.{v, v} _)]
theorem LinearMap.lift_rank_le_of_injective (f : M →ₗ[R] M') (i : Injective f) :
    Cardinal.lift.{v'} (Module.rank R M) ≤ Cardinal.lift.{v} (Module.rank R M') := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _),
    Cardinal.lift_iSup (Cardinal.bddAbove_range.{v, v} _)]
  

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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
i : Injective ⇑f
⊢ ⨆ i, lift.{v', v} #↑↑i ≤ ⨆ i, lift.{v, v'} #↑↑i

Next tactic:
apply ciSup_mono' (Cardinal.bddAbove_range.{v', v} _)
theorem LinearMap.lift_rank_le_of_injective (f : M →ₗ[R] M') (i : Injective f) :
    Cardinal.lift.{v'} (Module.rank R M) ≤ Cardinal.lift.{v} (Module.rank R M') := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _),
    Cardinal.lift_iSup (Cardinal.bddAbove_range.{v, v} _)]
  apply ciSup_mono' (Cardinal.bddAbove_range.{v', v} _)
  

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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
i : Injective ⇑f
⊢ ∀ (i : { s // LinearIndependent (ι := { x // x ∈ s }) R Subtype.val }), ∃ i', lift.{v', v} #↑↑i ≤ lift.{v, v'} #↑↑i'

Next tactic:
rintro ⟨s, li⟩
theorem LinearMap.lift_rank_le_of_injective (f : M →ₗ[R] M') (i : Injective f) :
    Cardinal.lift.{v'} (Module.rank R M) ≤ Cardinal.lift.{v} (Module.rank R M') := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _),
    Cardinal.lift_iSup (Cardinal.bddAbove_range.{v, v} _)]
  apply ciSup_mono' (Cardinal.bddAbove_range.{v', v} _)
  rintro ⟨s, li⟩
  

Proof state:
case mk
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
i : Injective ⇑f
s : Set M
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ ∃ i', lift.{v', v} #↑↑{ val := s, property := li } ≤ lift.{v, v'} #↑↑i'

Next tactic:
refine' ⟨⟨f '' s, _⟩, Cardinal.lift_mk_le'.mpr ⟨(Equiv.Set.image f s i).toEmbedding⟩⟩
theorem LinearMap.lift_rank_le_of_injective (f : M →ₗ[R] M') (i : Injective f) :
    Cardinal.lift.{v'} (Module.rank R M) ≤ Cardinal.lift.{v} (Module.rank R M') := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _),
    Cardinal.lift_iSup (Cardinal.bddAbove_range.{v, v} _)]
  apply ciSup_mono' (Cardinal.bddAbove_range.{v', v} _)
  rintro ⟨s, li⟩
  refine' ⟨⟨f '' s, _⟩, Cardinal.lift_mk_le'.mpr ⟨(Equiv.Set.image f s i).toEmbedding⟩⟩
  

Proof state:
case mk
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
i : Injective ⇑f
s : Set M
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ LinearIndependent (ι := { x // x ∈ ⇑f '' s }) R Subtype.val

Next tactic:
exact (li.map' _ <| LinearMap.ker_eq_bot_of_injective i).image
theorem rank_le {n : ℕ}
    (H : ∀ s : Finset M, (LinearIndependent R fun i : s => (i : M)) → s.card ≤ n) :
    Module.rank R M ≤ n := 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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
n : ℕ
H : ∀ (s : Finset M), (LinearIndependent R fun i => ↑i) → Finset.card s ≤ n
⊢ Module.rank R M ≤ ↑n

Next tactic:
rw [Module.rank_def]
theorem rank_le {n : ℕ}
    (H : ∀ s : Finset M, (LinearIndependent R fun i : s => (i : M)) → s.card ≤ n) :
    Module.rank R M ≤ n := by
  rw [Module.rank_def]
  

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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
n : ℕ
H : ∀ (s : Finset M), (LinearIndependent R fun i => ↑i) → Finset.card s ≤ n
⊢ ⨆ ι, #↑↑ι ≤ ↑n

Next tactic:
apply ciSup_le'
theorem rank_le {n : ℕ}
    (H : ∀ s : Finset M, (LinearIndependent R fun i : s => (i : M)) → s.card ≤ n) :
    Module.rank R M ≤ n := by
  rw [Module.rank_def]
  apply ciSup_le'
  

Proof state:
case h
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
n : ℕ
H : ∀ (s : Finset M), (LinearIndependent R fun i => ↑i) → Finset.card s ≤ n
⊢ ∀ (i : { s // LinearIndependent (ι := { x // x ∈ s }) R Subtype.val }), #↑↑i ≤ ↑n

Next tactic:
rintro ⟨s, li⟩
theorem rank_le {n : ℕ}
    (H : ∀ s : Finset M, (LinearIndependent R fun i : s => (i : M)) → s.card ≤ n) :
    Module.rank R M ≤ n := by
  rw [Module.rank_def]
  apply ciSup_le'
  rintro ⟨s, li⟩
  

Proof state:
case h.mk
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
n : ℕ
H : ∀ (s : Finset M), (LinearIndependent R fun i => ↑i) → Finset.card s ≤ n
s : Set M
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ #↑↑{ val := s, property := li } ≤ ↑n

Next tactic:
exact linearIndependent_bounded_of_finset_linearIndependent_bounded H _ li
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := 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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
⊢ lift.{v, v'} (Module.rank R ↥(LinearMap.range f)) ≤ lift.{v', v} (Module.rank R M)

Next tactic:
simp only [Module.rank_def]
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  

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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
⊢ lift.{v, v'} (⨆ ι, #↑↑ι) ≤ lift.{v', v} (⨆ ι, #↑↑ι)

Next tactic:
rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  

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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
⊢ ⨆ i, lift.{v, v'} #↑↑i ≤ lift.{v', v} (⨆ ι, #↑↑ι)

Next tactic:
apply ciSup_le'
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  

Proof state:
case h
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
⊢ ∀ (i : { s // LinearIndependent (ι := { x // x ∈ s }) R Subtype.val }), lift.{v, v'} #↑↑i ≤ lift.{v', v} (⨆ ι, #↑↑ι)

Next tactic:
rintro ⟨s, li⟩
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  

Proof state:
case h.mk
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ lift.{v, v'} #↑↑{ val := s, property := li } ≤ lift.{v', v} (⨆ ι, #↑↑ι)

Next tactic:
apply le_trans
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  apply le_trans
  

Proof state:
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ lift.{v, v'} #↑↑{ val := s, property := li } ≤ ?h.mk.b
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ ?h.mk.b ≤ lift.{v', v} (⨆ ι, #↑↑ι)
case h.mk.b
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ Cardinal.{max v' v}

Next tactic:
swap
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  apply le_trans
  swap
  · 

Proof state:
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ ?h.mk.b ≤ lift.{v', v} (⨆ ι, #↑↑ι)

Next tactic:
apply Cardinal.lift_le.mpr
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  apply le_trans
  swap
  · apply Cardinal.lift_le.mpr
    

Proof state:
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ ?m.21035 ≤ ⨆ ι, #↑↑ι
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ Cardinal.{v}

Next tactic:
refine' le_ciSup (Cardinal.bddAbove_range.{v, v} _) ⟨rangeSplitting f '' s, _⟩
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  apply le_trans
  swap
  · apply Cardinal.lift_le.mpr
    refine' le_ciSup (Cardinal.bddAbove_range.{v, v} _) ⟨rangeSplitting f '' s, _⟩
    

Proof state:
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ LinearIndependent (ι := { x // x ∈ rangeSplitting ⇑f '' s }) R Subtype.val

Next tactic:
apply LinearIndependent.of_comp f.rangeRestrict
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  apply le_trans
  swap
  · apply Cardinal.lift_le.mpr
    refine' le_ciSup (Cardinal.bddAbove_range.{v, v} _) ⟨rangeSplitting f '' s, _⟩
    apply LinearIndependent.of_comp f.rangeRestrict
    

Proof state:
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ LinearIndependent (ι := { x // x ∈ rangeSplitting ⇑f '' s }) R (⇑(LinearMap.rangeRestrict f) ∘ Subtype.val)

Next tactic:
convert li.comp (Equiv.Set.rangeSplittingImageEquiv f s) (Equiv.injective _) using 1
/-- The rank of the range of a linear map is at most the rank of the source. -/
-- The proof is: a free submodule of the range lifts to a free submodule of the
-- source, by arbitrarily lifting a basis.
theorem lift_rank_range_le (f : M →ₗ[R] M') : Cardinal.lift.{v}
    (Module.rank R (LinearMap.range f)) ≤ Cardinal.lift.{v'} (Module.rank R M) := by
  simp only [Module.rank_def]
  rw [Cardinal.lift_iSup (Cardinal.bddAbove_range.{v', v'} _)]
  apply ciSup_le'
  rintro ⟨s, li⟩
  apply le_trans
  swap
  · apply Cardinal.lift_le.mpr
    refine' le_ciSup (Cardinal.bddAbove_range.{v, v} _) ⟨rangeSplitting f '' s, _⟩
    apply LinearIndependent.of_comp f.rangeRestrict
    convert li.comp (Equiv.Set.rangeSplittingImageEquiv f s) (Equiv.injective _) using 1
  · 

Proof state:
case h.mk.a
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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
s : Set ↥(LinearMap.range f)
li : LinearIndependent (ι := { x // x ∈ s }) R Subtype.val
⊢ lift.{v, v'} #↑↑{ val := s, property := li } ≤
    lift.{v', v}
      #↑↑{ val := rangeSplitting ⇑f '' s,
              property := (_ : LinearIndependent (ι := { x // x ∈ rangeSplitting ⇑f '' s }) R Subtype.val) }

Next tactic:
exact (Cardinal.lift_mk_eq'.mpr ⟨Equiv.Set.rangeSplittingImageEquiv f s⟩).ge
theorem rank_range_le (f : M →ₗ[R] M₁) : Module.rank R (LinearMap.range f) ≤ Module.rank R M := 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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M₁
⊢ Module.rank R ↥(LinearMap.range f) ≤ Module.rank R M

Next tactic:
simpa using lift_rank_range_le f
theorem lift_rank_map_le (f : M →ₗ[R] M') (p : Submodule R M) :
    Cardinal.lift.{v} (Module.rank R (p.map f)) ≤ Cardinal.lift.{v'} (Module.rank R p) := 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 R
M : Type v
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
M' : Type v'
inst✝³ : AddCommGroup M'
inst✝² : Module R M'
M₁ : Type v
inst✝¹ : AddCommGroup M₁
inst✝ : Module R M₁
f : M →ₗ[R] M'
p : Submodule R M
⊢ lift.{v, v'} (Module.rank R ↥(Submodule.map f p)) ≤ lift.{v', v} (Module.rank R ↥p)

Next tactic:
have h := lift_rank_range_le (f.comp (Submodule.subtype p))