l3lab/ntp-mathlib huggingface dataset:
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
    let this :=
      extendCofanIsColimit (fun i => F.obj (f i))
        (isColimitOfHasCoproductOfPreservesColimit F _)
        (isColimitOfHasBinaryCoproductOfPreservesColimit F _ _)
    refine' IsColimit.ofIsoColimit this _
    apply Cocones.ext _ _
    apply Iso.refl _
    rintro ⟨j⟩
    refine' Fin.inductionOn j ?_ ?_
    · 

Proof state:
case mk.refine'_1
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsColimit
  (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
    (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))) :=
  extendCofanIsColimit (fun i => F.obj (f i)) (isColimitOfHasCoproductOfPreservesColimit F fun i => f (Fin.succ i))
    (isColimitOfHasBinaryCoproductOfPreservesColimit F (f 0) (∐ fun i => f (Fin.succ i)))
j : Fin (n + 1)
⊢ (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
              (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))).ι.app
        { as := 0 } ≫
      (Iso.refl
          (extendCofan
              (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
              (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))).pt).hom =
    (Cofan.mk (F.obj (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt)
            fun j =>
            F.map
              (Fin.cases
                (BinaryCofan.inl
                  (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                (fun i =>
                  (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).ι.app { as := i } ≫
                    BinaryCofan.inr
                      (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                j)).ι.app
      { as := 0 }

Next tactic:
apply Category.comp_id
/-- If `F` preserves the initial object and binary coproducts, then it preserves colimits of shape
`Discrete (Fin n)`.
-/
def preservesShapeFinOfPreservesBinaryAndInitial (n : ℕ) :
    PreservesColimitsOfShape (Discrete (Fin n)) F where
  preservesColimit {K} := by
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
K : Discrete (Fin n) ⥤ C
⊢ PreservesColimit K F

Next tactic:
let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _
/-- If `F` preserves the initial object and binary coproducts, then it preserves colimits of shape
`Discrete (Fin n)`.
-/
def preservesShapeFinOfPreservesBinaryAndInitial (n : ℕ) :
    PreservesColimitsOfShape (Discrete (Fin n)) F where
  preservesColimit {K} := by
    let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
K : Discrete (Fin n) ⥤ C
that : (Discrete.functor fun n_1 => K.obj { as := n_1 }) ≅ K :=
  Discrete.natIso fun x =>
    match x with
    | { as := i } => Iso.refl ((Discrete.functor fun n_1 => K.obj { as := n_1 }).obj { as := i })
⊢ PreservesColimit K F

Next tactic:
haveI := preservesFinOfPreservesBinaryAndInitial F n fun n => K.obj ⟨n⟩
/-- If `F` preserves the initial object and binary coproducts, then it preserves colimits of shape
`Discrete (Fin n)`.
-/
def preservesShapeFinOfPreservesBinaryAndInitial (n : ℕ) :
    PreservesColimitsOfShape (Discrete (Fin n)) F where
  preservesColimit {K} := by
    let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _
    haveI := preservesFinOfPreservesBinaryAndInitial F n fun n => K.obj ⟨n⟩
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
K : Discrete (Fin n) ⥤ C
that : (Discrete.functor fun n_1 => K.obj { as := n_1 }) ≅ K :=
  Discrete.natIso fun x =>
    match x with
    | { as := i } => Iso.refl ((Discrete.functor fun n_1 => K.obj { as := n_1 }).obj { as := i })
this : PreservesColimit (Discrete.functor fun n_1 => K.obj { as := n_1 }) F
⊢ PreservesColimit K F

Next tactic:
apply preservesColimitOfIsoDiagram F that
/-- If `F` preserves the initial object and binary coproducts then it preserves finite products. -/
def preservesFiniteCoproductsOfPreservesBinaryAndInitial (J : Type) [Fintype J] :
    PreservesColimitsOfShape (Discrete J) F := by
  

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteCoproducts C
J : Type
inst✝ : Fintype J
⊢ PreservesColimitsOfShape (Discrete J) F

Next tactic:
classical
    let e := Fintype.equivFin J
    haveI := preservesShapeFinOfPreservesBinaryAndInitial F (Fintype.card J)
    apply preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence e).symm
/-- If `F` preserves the initial object and binary coproducts then it preserves finite products. -/
def preservesFiniteCoproductsOfPreservesBinaryAndInitial (J : Type) [Fintype J] :
    PreservesColimitsOfShape (Discrete J) F := by
  classical
    

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteCoproducts C
J : Type
inst✝ : Fintype J
⊢ PreservesColimitsOfShape (Discrete J) F

Next tactic:
let e := Fintype.equivFin J
/-- If `F` preserves the initial object and binary coproducts then it preserves finite products. -/
def preservesFiniteCoproductsOfPreservesBinaryAndInitial (J : Type) [Fintype J] :
    PreservesColimitsOfShape (Discrete J) F := by
  classical
    let e := Fintype.equivFin J
    

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteCoproducts C
J : Type
inst✝ : Fintype J
e : J ≃ Fin (Fintype.card J) := Fintype.equivFin J
⊢ PreservesColimitsOfShape (Discrete J) F

Next tactic:
haveI := preservesShapeFinOfPreservesBinaryAndInitial F (Fintype.card J)
/-- If `F` preserves the initial object and binary coproducts then it preserves finite products. -/
def preservesFiniteCoproductsOfPreservesBinaryAndInitial (J : Type) [Fintype J] :
    PreservesColimitsOfShape (Discrete J) F := by
  classical
    let e := Fintype.equivFin J
    haveI := preservesShapeFinOfPreservesBinaryAndInitial F (Fintype.card J)
    

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteCoproducts C
J : Type
inst✝ : Fintype J
e : J ≃ Fin (Fintype.card J) := Fintype.equivFin J
this : PreservesColimitsOfShape (Discrete (Fin (Fintype.card J))) F
⊢ PreservesColimitsOfShape (Discrete J) F

Next tactic:
apply preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence e).symm
example [h : Nonempty α] [IsEmpty β] : IsEmpty (α → β) := by 

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
h : Nonempty α
inst✝ : IsEmpty β
⊢ IsEmpty (α → β)

Next tactic:
infer_instance
@[simp]
theorem isEmpty_Prop {p : Prop} : IsEmpty p ↔ ¬p := by
  

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
p : Prop
⊢ IsEmpty p ↔ ¬p

Next tactic:
simp only [← not_nonempty_iff, nonempty_Prop]
@[simp]
theorem isEmpty_pi {π : α → Sort*} : IsEmpty (∀ a, π a) ↔ ∃ a, IsEmpty (π a) := by
  

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
π : α → Sort u_4
⊢ IsEmpty ((a : α) → π a) ↔ ∃ a, IsEmpty (π a)

Next tactic:
simp only [← not_nonempty_iff, Classical.nonempty_pi, not_forall]
@[simp]
theorem isEmpty_sigma {α} {E : α → Type*} : IsEmpty (Sigma E) ↔ ∀ a, IsEmpty (E a) := by
  

Proof state:
α✝ : Sort u_1
β : Sort u_2
γ : Sort u_3
α : Type u_5
E : α → Type u_4
⊢ IsEmpty (Sigma E) ↔ ∀ (a : α), IsEmpty (E a)

Next tactic:
simp only [← not_nonempty_iff, nonempty_sigma, not_exists]
@[simp]
theorem isEmpty_psigma {α} {E : α → Sort*} : IsEmpty (PSigma E) ↔ ∀ a, IsEmpty (E a) := by
  

Proof state:
α✝ : Sort u_1
β : Sort u_2
γ : Sort u_3
α : Sort u_5
E : α → Sort u_4
⊢ IsEmpty (PSigma E) ↔ ∀ (a : α), IsEmpty (E a)

Next tactic:
simp only [← not_nonempty_iff, nonempty_psigma, not_exists]
@[simp]
theorem isEmpty_subtype (p : α → Prop) : IsEmpty (Subtype p) ↔ ∀ x, ¬p x := by
  

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
p : α → Prop
⊢ IsEmpty (Subtype p) ↔ ∀ (x : α), ¬p x

Next tactic:
simp only [← not_nonempty_iff, nonempty_subtype, not_exists]
@[simp]
theorem isEmpty_prod {α β : Type*} : IsEmpty (α × β) ↔ IsEmpty α ∨ IsEmpty β := by
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
α : Type u_4
β : Type u_5
⊢ IsEmpty (α × β) ↔ IsEmpty α ∨ IsEmpty β

Next tactic:
simp only [← not_nonempty_iff, nonempty_prod, not_and_or]
@[simp]
theorem isEmpty_pprod : IsEmpty (PProd α β) ↔ IsEmpty α ∨ IsEmpty β := by
  

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
⊢ IsEmpty (PProd α β) ↔ IsEmpty α ∨ IsEmpty β

Next tactic:
simp only [← not_nonempty_iff, nonempty_pprod, not_and_or]
@[simp]
theorem isEmpty_sum {α β} : IsEmpty (Sum α β) ↔ IsEmpty α ∧ IsEmpty β := by
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
α : Type u_4
β : Type u_5
⊢ IsEmpty (α ⊕ β) ↔ IsEmpty α ∧ IsEmpty β

Next tactic:
simp only [← not_nonempty_iff, nonempty_sum, not_or]
@[simp]
theorem isEmpty_psum {α β} : IsEmpty (PSum α β) ↔ IsEmpty α ∧ IsEmpty β := by
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
α : Sort u_4
β : Sort u_5
⊢ IsEmpty (α ⊕' β) ↔ IsEmpty α ∧ IsEmpty β

Next tactic:
simp only [← not_nonempty_iff, nonempty_psum, not_or]
@[simp]
theorem isEmpty_ulift {α} : IsEmpty (ULift α) ↔ IsEmpty α := by
  

Proof state:
α✝ : Sort u_1
β : Sort u_2
γ : Sort u_3
α : Type u_4
⊢ IsEmpty (ULift.{u_5, u_4} α) ↔ IsEmpty α

Next tactic:
simp only [← not_nonempty_iff, nonempty_ulift]
@[simp]
theorem isEmpty_plift {α} : IsEmpty (PLift α) ↔ IsEmpty α := by
  

Proof state:
α✝ : Sort u_1
β : Sort u_2
γ : Sort u_3
α : Sort u_4
⊢ IsEmpty (PLift α) ↔ IsEmpty α

Next tactic:
simp only [← not_nonempty_iff, nonempty_plift]
@[simp]
theorem finrank_ulift : finrank R (ULift M) = finrank R M := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁴ : Ring R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
⊢ finrank R (ULift.{u_1, v} M) = finrank R M

Next tactic:
simp_rw [finrank, rank_ulift, toNat_lift]
/-- The rank of a finite module is finite. -/
theorem rank_lt_aleph0 : Module.rank R M < ℵ₀ := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁷ : Ring R
inst✝⁶ : StrongRankCondition R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : Module.Finite R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
inst✝ : Module.Finite R N
⊢ Module.rank R M < ℵ₀

Next tactic:
simp only [Module.rank_def]
/-- The rank of a finite module is finite. -/
theorem rank_lt_aleph0 : Module.rank R M < ℵ₀ := by
  simp only [Module.rank_def]
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁷ : Ring R
inst✝⁶ : StrongRankCondition R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : Module.Finite R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
inst✝ : Module.Finite R N
⊢ ⨆ ι, #↑↑ι < ℵ₀

Next tactic:
letI := nontrivial_of_invariantBasisNumber R
/-- The rank of a finite module is finite. -/
theorem rank_lt_aleph0 : Module.rank R M < ℵ₀ := by
  simp only [Module.rank_def]
  letI := nontrivial_of_invariantBasisNumber R
  -- porting note: can't use `‹_›` as that pulls the unused `N` into the context
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁷ : Ring R
inst✝⁶ : StrongRankCondition R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : Module.Finite R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
inst✝ : Module.Finite R N
this : Nontrivial R := nontrivial_of_invariantBasisNumber R
⊢ ⨆ ι, #↑↑ι < ℵ₀

Next tactic:
obtain ⟨S, hS⟩ := Module.finite_def.mp ‹Module.Finite R M›
/-- The rank of a finite module is finite. -/
theorem rank_lt_aleph0 : Module.rank R M < ℵ₀ := by
  simp only [Module.rank_def]
  letI := nontrivial_of_invariantBasisNumber R
  -- porting note: can't use `‹_›` as that pulls the unused `N` into the context
  obtain ⟨S, hS⟩ := Module.finite_def.mp ‹Module.Finite R M›
  

Proof state:
case intro
R : Type u
M : Type v
N : Type w
inst✝⁷ : Ring R
inst✝⁶ : StrongRankCondition R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : Module.Finite R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
inst✝ : Module.Finite R N
this : Nontrivial R := nontrivial_of_invariantBasisNumber R
S : Finset M
hS : Submodule.span R ↑S = ⊤
⊢ ⨆ ι, #↑↑ι < ℵ₀

Next tactic:
refine' (ciSup_le' fun i => _).trans_lt (nat_lt_aleph0 S.card)
/-- The rank of a finite module is finite. -/
theorem rank_lt_aleph0 : Module.rank R M < ℵ₀ := by
  simp only [Module.rank_def]
  letI := nontrivial_of_invariantBasisNumber R
  -- porting note: can't use `‹_›` as that pulls the unused `N` into the context
  obtain ⟨S, hS⟩ := Module.finite_def.mp ‹Module.Finite R M›
  refine' (ciSup_le' fun i => _).trans_lt (nat_lt_aleph0 S.card)
  

Proof state:
case intro
R : Type u
M : Type v
N : Type w
inst✝⁷ : Ring R
inst✝⁶ : StrongRankCondition R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : Module.Finite R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
inst✝ : Module.Finite R N
this : Nontrivial R := nontrivial_of_invariantBasisNumber R
S : Finset M
hS : Submodule.span R ↑S = ⊤
i : { s // LinearIndependent (ι := { x // x ∈ s }) R Subtype.val }
⊢ #↑↑i ≤ ↑(Finset.card S)

Next tactic:
exact linearIndependent_le_span_finset _ i.prop S hS
/-- If `M` is finite, `finrank M = rank M`. -/
@[simp]
theorem finrank_eq_rank : ↑(finrank R M) = Module.rank R M := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁷ : Ring R
inst✝⁶ : StrongRankCondition R
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
inst✝³ : Module.Finite R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
inst✝ : Module.Finite R N
⊢ ↑(finrank R M) = Module.rank R M

Next tactic:
rw [finrank, cast_toNat_of_lt_aleph0 (rank_lt_aleph0 R M)]
/-- The finrank of a free module `M` over `R` is the cardinality of `ChooseBasisIndex R M`. -/
theorem finrank_eq_card_chooseBasisIndex :
    finrank R M = card (ChooseBasisIndex R M) := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁹ : Ring R
inst✝⁸ : StrongRankCondition R
inst✝⁷ : AddCommGroup M
inst✝⁶ : Module R M
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Module.Free R N
inst✝ : Module.Finite R N
⊢ finrank R M = card (ChooseBasisIndex R M)

Next tactic:
simp [finrank, rank_eq_card_chooseBasisIndex]
@[simp]
theorem finrank_finsupp {ι : Type v} [Fintype ι] : finrank R (ι →₀ M) = card ι * finrank R M := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝¹⁰ : Ring R
inst✝⁹ : StrongRankCondition R
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : AddCommGroup N
inst✝³ : Module R N
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
ι : Type v
inst✝ : Fintype ι
⊢ finrank R (ι →₀ M) = card ι * finrank R M

Next tactic:
rw [finrank, finrank, rank_finsupp, ← mk_toNat_eq_card, toNat_mul, toNat_lift, toNat_lift]
/-- The finrank of `(ι →₀ R)` is `Fintype.card ι`. -/
@[simp]
theorem finrank_finsupp_self {ι : Type v} [Fintype ι] : finrank R (ι →₀ R) = card ι := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝¹⁰ : Ring R
inst✝⁹ : StrongRankCondition R
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : AddCommGroup N
inst✝³ : Module R N
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
ι : Type v
inst✝ : Fintype ι
⊢ finrank R (ι →₀ R) = card ι

Next tactic:
rw [finrank, rank_finsupp_self, ← mk_toNat_eq_card, toNat_lift]
/-- The finrank of `(ι → R)` is `Fintype.card ι`. -/
theorem finrank_pi {ι : Type v} [Fintype ι] : finrank R (ι → R) = card ι := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝¹⁰ : Ring R
inst✝⁹ : StrongRankCondition R
inst✝⁸ : AddCommGroup M
inst✝⁷ : Module R M
inst✝⁶ : Module.Free R M
inst✝⁵ : Module.Finite R M
inst✝⁴ : AddCommGroup N
inst✝³ : Module R N
inst✝² : Module.Free R N
inst✝¹ : Module.Finite R N
ι : Type v
inst✝ : Fintype ι
⊢ finrank R (ι → R) = card ι

Next tactic:
simp [finrank]
/-- The finrank of the direct sum is the sum of the finranks. -/
@[simp]
theorem finrank_directSum {ι : Type v} [Fintype ι] (M : ι → Type w) [∀ i : ι, AddCommGroup (M i)]
    [∀ i : ι, Module R (M i)] [∀ i : ι, Module.Free R (M i)] [∀ i : ι, Module.Finite R (M i)] :
    finrank R (⨁ i, M i) = ∑ i, finrank R (M i) := by
  

Proof state:
R : Type u
M✝ : Type v
N : Type w
inst✝¹⁴ : Ring R
inst✝¹³ : StrongRankCondition R
inst✝¹² : AddCommGroup M✝
inst✝¹¹ : Module R M✝
inst✝¹⁰ : Module.Free R M✝
inst✝⁹ : Module.Finite R M✝
inst✝⁸ : AddCommGroup N
inst✝⁷ : Module R N
inst✝⁶ : Module.Free R N
inst✝⁵ : Module.Finite R N
ι : Type v
inst✝⁴ : Fintype ι
M : ι → Type w
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : ∀ (i : ι), Module.Free R (M i)
inst✝ : ∀ (i : ι), Module.Finite R (M i)
⊢ finrank R (⨁ (i : ι), M i) = ∑ i : ι, finrank R (M i)

Next tactic:
letI := nontrivial_of_invariantBasisNumber R
/-- The finrank of the direct sum is the sum of the finranks. -/
@[simp]
theorem finrank_directSum {ι : Type v} [Fintype ι] (M : ι → Type w) [∀ i : ι, AddCommGroup (M i)]
    [∀ i : ι, Module R (M i)] [∀ i : ι, Module.Free R (M i)] [∀ i : ι, Module.Finite R (M i)] :
    finrank R (⨁ i, M i) = ∑ i, finrank R (M i) := by
  letI := nontrivial_of_invariantBasisNumber R
  

Proof state:
R : Type u
M✝ : Type v
N : Type w
inst✝¹⁴ : Ring R
inst✝¹³ : StrongRankCondition R
inst✝¹² : AddCommGroup M✝
inst✝¹¹ : Module R M✝
inst✝¹⁰ : Module.Free R M✝
inst✝⁹ : Module.Finite R M✝
inst✝⁸ : AddCommGroup N
inst✝⁷ : Module R N
inst✝⁶ : Module.Free R N
inst✝⁵ : Module.Finite R N
ι : Type v
inst✝⁴ : Fintype ι
M : ι → Type w
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : ∀ (i : ι), Module.Free R (M i)
inst✝ : ∀ (i : ι), Module.Finite R (M i)
this : Nontrivial R := nontrivial_of_invariantBasisNumber R
⊢ finrank R (⨁ (i : ι), M i) = ∑ i : ι, finrank R (M i)

Next tactic:
simp only [finrank, fun i => rank_eq_card_chooseBasisIndex R (M i), rank_directSum, ← mk_sigma,
    mk_toNat_eq_card, card_sigma]
/-- The finrank of `M × N` is `(finrank R M) + (finrank R N)`. -/
@[simp]
theorem finrank_prod : finrank R (M × N) = finrank R M + finrank R N := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁹ : Ring R
inst✝⁸ : StrongRankCondition R
inst✝⁷ : AddCommGroup M
inst✝⁶ : Module R M
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Module.Free R N
inst✝ : Module.Finite R N
⊢ finrank R (M × N) = finrank R M + finrank R N

Next tactic:
simp [finrank, rank_lt_aleph0 R M, rank_lt_aleph0 R N]
/-- The finrank of a finite product is the sum of the finranks. -/
theorem finrank_pi_fintype {ι : Type v} [Fintype ι] {M : ι → Type w} [∀ i : ι, AddCommGroup (M i)]
    [∀ i : ι, Module R (M i)] [∀ i : ι, Module.Free R (M i)] [∀ i : ι, Module.Finite R (M i)] :
    finrank R (∀ i, M i) = ∑ i, finrank R (M i) := by
  

Proof state:
R : Type u
M✝ : Type v
N : Type w
inst✝¹⁴ : Ring R
inst✝¹³ : StrongRankCondition R
inst✝¹² : AddCommGroup M✝
inst✝¹¹ : Module R M✝
inst✝¹⁰ : Module.Free R M✝
inst✝⁹ : Module.Finite R M✝
inst✝⁸ : AddCommGroup N
inst✝⁷ : Module R N
inst✝⁶ : Module.Free R N
inst✝⁵ : Module.Finite R N
ι : Type v
inst✝⁴ : Fintype ι
M : ι → Type w
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : ∀ (i : ι), Module.Free R (M i)
inst✝ : ∀ (i : ι), Module.Finite R (M i)
⊢ finrank R ((i : ι) → M i) = ∑ i : ι, finrank R (M i)

Next tactic:
letI := nontrivial_of_invariantBasisNumber R
/-- The finrank of a finite product is the sum of the finranks. -/
theorem finrank_pi_fintype {ι : Type v} [Fintype ι] {M : ι → Type w} [∀ i : ι, AddCommGroup (M i)]
    [∀ i : ι, Module R (M i)] [∀ i : ι, Module.Free R (M i)] [∀ i : ι, Module.Finite R (M i)] :
    finrank R (∀ i, M i) = ∑ i, finrank R (M i) := by
  letI := nontrivial_of_invariantBasisNumber R
  

Proof state:
R : Type u
M✝ : Type v
N : Type w
inst✝¹⁴ : Ring R
inst✝¹³ : StrongRankCondition R
inst✝¹² : AddCommGroup M✝
inst✝¹¹ : Module R M✝
inst✝¹⁰ : Module.Free R M✝
inst✝⁹ : Module.Finite R M✝
inst✝⁸ : AddCommGroup N
inst✝⁷ : Module R N
inst✝⁶ : Module.Free R N
inst✝⁵ : Module.Finite R N
ι : Type v
inst✝⁴ : Fintype ι
M : ι → Type w
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : ∀ (i : ι), Module.Free R (M i)
inst✝ : ∀ (i : ι), Module.Finite R (M i)
this : Nontrivial R := nontrivial_of_invariantBasisNumber R
⊢ finrank R ((i : ι) → M i) = ∑ i : ι, finrank R (M i)

Next tactic:
simp only [finrank, fun i => rank_eq_card_chooseBasisIndex R (M i), rank_pi, ← mk_sigma,
    mk_toNat_eq_card, card_sigma]
/-- If `m` and `n` are `Fintype`, the finrank of `m × n` matrices is
  `(Fintype.card m) * (Fintype.card n)`. -/
theorem finrank_matrix (m n : Type*) [Fintype m] [Fintype n] :
    finrank R (Matrix m n R) = card m * card n := by 

Proof state:
R : Type u
M : Type v
N : Type w
inst✝¹¹ : Ring R
inst✝¹⁰ : StrongRankCondition R
inst✝⁹ : AddCommGroup M
inst✝⁸ : Module R M
inst✝⁷ : Module.Free R M
inst✝⁶ : Module.Finite R M
inst✝⁵ : AddCommGroup N
inst✝⁴ : Module R N
inst✝³ : Module.Free R N
inst✝² : Module.Finite R N
m : Type u_1
n : Type u_2
inst✝¹ : Fintype m
inst✝ : Fintype n
⊢ finrank R (Matrix m n R) = card m * card n

Next tactic:
simp [finrank]
/-- Two finite and free modules are isomorphic if they have the same (finite) rank. -/
theorem nonempty_linearEquiv_of_finrank_eq (cond : finrank R M = finrank R N) :
    Nonempty (M ≃ₗ[R] N) :=
  nonempty_linearEquiv_of_lift_rank_eq <| by 

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁹ : Ring R
inst✝⁸ : StrongRankCondition R
inst✝⁷ : AddCommGroup M
inst✝⁶ : Module R M
inst✝⁵ : Module.Free R M
inst✝⁴ : Module.Finite R M
inst✝³ : AddCommGroup N
inst✝² : Module R N
inst✝¹ : Module.Free R N
inst✝ : Module.Finite R N
cond : finrank R M = finrank R N
⊢ Cardinal.lift.{w, v} (Module.rank R M) = Cardinal.lift.{v, w} (Module.rank R N)

Next tactic:
simp only [← finrank_eq_rank, cond, lift_natCast]