set_theory.cardinal.finiteMathlib.SetTheory.Cardinal.Finite

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

feat(set_theory/cardinal/finite): prove lemmas to handle part_enat.card (#19198)

Prove some lemmas that allow to handle part_enat.card of finite cardinals, analogous to those about nat.card

Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr>

Diff
@@ -120,4 +120,92 @@ lemma card_eq_coe_fintype_card [fintype α] : card α = fintype.card α := mk_to
 @[simp]
 lemma card_eq_top_of_infinite [infinite α] : card α = ⊤ := mk_to_part_enat_of_infinite
 
+lemma card_congr {α : Type*} {β : Type*} (f : α ≃ β) :
+  part_enat.card α = part_enat.card β :=
+cardinal.to_part_enat_congr f
+
+lemma card_ulift (α : Type*) : card (ulift α) = card α :=
+card_congr equiv.ulift
+
+@[simp] lemma card_plift (α : Type*) : card (plift α) = card α :=
+card_congr equiv.plift
+
+lemma card_image_of_inj_on {α : Type*} {β : Type*} {f : α → β} {s : set α} (h : set.inj_on f s) :
+  card (f '' s) = card s :=
+card_congr (equiv.set.image_of_inj_on f s h).symm
+
+lemma card_image_of_injective {α : Type*} {β : Type*}
+  (f : α → β) (s : set α) (h : function.injective f) :
+  card (f '' s) = card s :=
+card_image_of_inj_on (set.inj_on_of_injective h s)
+
+-- Should I keep the 6 following lemmas ?
+@[simp]
+lemma _root_.cardinal.coe_nat_le_to_part_enat_iff {n : ℕ} {c : cardinal} :
+  ↑n ≤ to_part_enat c ↔ ↑n ≤ c :=
+by rw [← to_part_enat_cast n, to_part_enat_le_iff_le_of_le_aleph_0 (le_of_lt (nat_lt_aleph_0 n))]
+
+@[simp]
+lemma _root_.cardinal.to_part_enat_le_coe_nat_iff {c : cardinal} {n : ℕ} :
+  to_part_enat c ≤ n ↔ c ≤ n :=
+by rw [← to_part_enat_cast n,
+ to_part_enat_le_iff_le_of_lt_aleph_0 (nat_lt_aleph_0 n)]
+
+@[simp]
+lemma _root_.cardinal.coe_nat_eq_to_part_enat_iff {n : ℕ} {c : cardinal} :
+  ↑n = to_part_enat c ↔ ↑n = c :=
+by rw [le_antisymm_iff, le_antisymm_iff,
+  cardinal.coe_nat_le_to_part_enat_iff,  cardinal.to_part_enat_le_coe_nat_iff]
+
+@[simp]
+lemma _root_.cardinal.to_part_enat_eq_coe_nat_iff {c : cardinal} {n : ℕ} :
+  to_part_enat c = n ↔ c = n:=
+by rw [eq_comm, cardinal.coe_nat_eq_to_part_enat_iff, eq_comm]
+
+@[simp]
+lemma _root_.cardinal.coe_nat_lt_coe_iff_lt {n : ℕ} {c : cardinal} :
+  ↑n < to_part_enat c ↔ ↑n < c :=
+by simp only [← not_le, cardinal.to_part_enat_le_coe_nat_iff]
+
+@[simp]
+lemma _root_.cardinal.lt_coe_nat_iff_lt {n : ℕ} {c : cardinal} :
+  to_part_enat c < n ↔ c < n :=
+by simp only [← not_le, cardinal.coe_nat_le_to_part_enat_iff]
+
+lemma card_eq_zero_iff_empty (α : Type*) : card α = 0 ↔ is_empty α :=
+begin
+  rw ← cardinal.mk_eq_zero_iff,
+  conv_rhs { rw ← nat.cast_zero },
+  rw ← cardinal.to_part_enat_eq_coe_nat_iff,
+  simp only [part_enat.card, nat.cast_zero]
+end
+
+lemma card_le_one_iff_subsingleton (α : Type*) : card α ≤ 1 ↔ subsingleton α :=
+begin
+  rw ← le_one_iff_subsingleton,
+  conv_rhs { rw ← nat.cast_one},
+  rw ← cardinal.to_part_enat_le_coe_nat_iff,
+  simp only [part_enat.card, nat.cast_one]
+end
+
+lemma one_lt_card_iff_nontrivial (α : Type*) : 1 < card α ↔ nontrivial α :=
+begin
+  rw ← one_lt_iff_nontrivial,
+  conv_rhs { rw ← nat.cast_one},
+  rw ← cardinal.coe_nat_lt_coe_iff_lt,
+  simp only [part_enat.card, nat.cast_one]
+end
+
+lemma is_finite_of_card {α : Type*} {n : ℕ} (hα : part_enat.card α = n) :
+  finite α :=
+begin
+  apply or.resolve_right (finite_or_infinite α),
+  intro h, resetI,
+  apply part_enat.coe_ne_top n,
+  rw ← hα,
+  exact part_enat.card_eq_top_of_infinite,
+end
+
+
+
 end part_enat

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(first ported)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2021 Aaron Anderson. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
 -/
-import Data.Zmod.Defs
+import Data.ZMod.Defs
 import SetTheory.Cardinal.Basic
 
 #align_import set_theory.cardinal.finite from "leanprover-community/mathlib"@"3ff3f2d6a3118b8711063de7111a0d77a53219a8"
Diff
@@ -205,17 +205,17 @@ theorem card_congr {α : Type _} {β : Type _} (f : α ≃ β) : PartENat.card 
 #align part_enat.card_congr PartENat.card_congr
 -/
 
-#print PartENat.card_uLift /-
-theorem card_uLift (α : Type _) : card (ULift α) = card α :=
+#print PartENat.card_ulift /-
+theorem card_ulift (α : Type _) : card (ULift α) = card α :=
   card_congr Equiv.ulift
-#align part_enat.card_ulift PartENat.card_uLift
+#align part_enat.card_ulift PartENat.card_ulift
 -/
 
-#print PartENat.card_pLift /-
+#print PartENat.card_plift /-
 @[simp]
-theorem card_pLift (α : Type _) : card (PLift α) = card α :=
+theorem card_plift (α : Type _) : card (PLift α) = card α :=
   card_congr Equiv.plift
-#align part_enat.card_plift PartENat.card_pLift
+#align part_enat.card_plift PartENat.card_plift
 -/
 
 #print PartENat.card_image_of_injOn /-
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2021 Aaron Anderson. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
 -/
-import Mathbin.Data.Zmod.Defs
-import Mathbin.SetTheory.Cardinal.Basic
+import Data.Zmod.Defs
+import SetTheory.Cardinal.Basic
 
 #align_import set_theory.cardinal.finite from "leanprover-community/mathlib"@"3ff3f2d6a3118b8711063de7111a0d77a53219a8"
 
Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2021 Aaron Anderson. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
-
-! This file was ported from Lean 3 source module set_theory.cardinal.finite
-! leanprover-community/mathlib commit 3ff3f2d6a3118b8711063de7111a0d77a53219a8
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Data.Zmod.Defs
 import Mathbin.SetTheory.Cardinal.Basic
 
+#align_import set_theory.cardinal.finite from "leanprover-community/mathlib"@"3ff3f2d6a3118b8711063de7111a0d77a53219a8"
+
 /-!
 # Finite Cardinality Functions
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
 
 ! This file was ported from Lean 3 source module set_theory.cardinal.finite
-! leanprover-community/mathlib commit 34ee86e6a59d911a8e4f89b68793ee7577ae79c7
+! leanprover-community/mathlib commit 3ff3f2d6a3118b8711063de7111a0d77a53219a8
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -202,5 +202,115 @@ theorem card_eq_top_of_infinite [Infinite α] : card α = ⊤ :=
 #align part_enat.card_eq_top_of_infinite PartENat.card_eq_top_of_infinite
 -/
 
+#print PartENat.card_congr /-
+theorem card_congr {α : Type _} {β : Type _} (f : α ≃ β) : PartENat.card α = PartENat.card β :=
+  Cardinal.toPartENat_congr f
+#align part_enat.card_congr PartENat.card_congr
+-/
+
+#print PartENat.card_uLift /-
+theorem card_uLift (α : Type _) : card (ULift α) = card α :=
+  card_congr Equiv.ulift
+#align part_enat.card_ulift PartENat.card_uLift
+-/
+
+#print PartENat.card_pLift /-
+@[simp]
+theorem card_pLift (α : Type _) : card (PLift α) = card α :=
+  card_congr Equiv.plift
+#align part_enat.card_plift PartENat.card_pLift
+-/
+
+#print PartENat.card_image_of_injOn /-
+theorem card_image_of_injOn {α : Type _} {β : Type _} {f : α → β} {s : Set α} (h : Set.InjOn f s) :
+    card (f '' s) = card s :=
+  card_congr (Equiv.Set.imageOfInjOn f s h).symm
+#align part_enat.card_image_of_inj_on PartENat.card_image_of_injOn
+-/
+
+#print PartENat.card_image_of_injective /-
+theorem card_image_of_injective {α : Type _} {β : Type _} (f : α → β) (s : Set α)
+    (h : Function.Injective f) : card (f '' s) = card s :=
+  card_image_of_injOn (Set.injOn_of_injective h s)
+#align part_enat.card_image_of_injective PartENat.card_image_of_injective
+-/
+
+#print Cardinal.natCast_le_toPartENat_iff /-
+-- Should I keep the 6 following lemmas ?
+@[simp]
+theorem Cardinal.natCast_le_toPartENat_iff {n : ℕ} {c : Cardinal} : ↑n ≤ toPartENat c ↔ ↑n ≤ c := by
+  rw [← to_part_enat_cast n, Cardinal.toPartENat_le_iff_of_le_aleph0 (le_of_lt (nat_lt_aleph_0 n))]
+#align cardinal.coe_nat_le_to_part_enat_iff Cardinal.natCast_le_toPartENat_iff
+-/
+
+#print Cardinal.toPartENat_le_natCast_iff /-
+@[simp]
+theorem Cardinal.toPartENat_le_natCast_iff {c : Cardinal} {n : ℕ} : toPartENat c ≤ n ↔ c ≤ n := by
+  rw [← to_part_enat_cast n, Cardinal.toPartENat_le_iff_of_lt_aleph0 (nat_lt_aleph_0 n)]
+#align cardinal.to_part_enat_le_coe_nat_iff Cardinal.toPartENat_le_natCast_iff
+-/
+
+#print Cardinal.natCast_eq_toPartENat_iff /-
+@[simp]
+theorem Cardinal.natCast_eq_toPartENat_iff {n : ℕ} {c : Cardinal} : ↑n = toPartENat c ↔ ↑n = c := by
+  rw [le_antisymm_iff, le_antisymm_iff, Cardinal.natCast_le_toPartENat_iff,
+    Cardinal.toPartENat_le_natCast_iff]
+#align cardinal.coe_nat_eq_to_part_enat_iff Cardinal.natCast_eq_toPartENat_iff
+-/
+
+@[simp]
+theorem Cardinal.toPartENat_eq_coe_nat_iff {c : Cardinal} {n : ℕ} : toPartENat c = n ↔ c = n := by
+  rw [eq_comm, Cardinal.natCast_eq_toPartENat_iff, eq_comm]
+#align cardinal.to_part_enat_eq_coe_nat_iff Cardinal.toPartENat_eq_coe_nat_iff
+
+@[simp]
+theorem Cardinal.coe_nat_lt_coe_iff_lt {n : ℕ} {c : Cardinal} : ↑n < toPartENat c ↔ ↑n < c := by
+  simp only [← not_le, Cardinal.toPartENat_le_natCast_iff]
+#align cardinal.coe_nat_lt_coe_iff_lt Cardinal.coe_nat_lt_coe_iff_lt
+
+@[simp]
+theorem Cardinal.lt_coe_nat_iff_lt {n : ℕ} {c : Cardinal} : toPartENat c < n ↔ c < n := by
+  simp only [← not_le, Cardinal.natCast_le_toPartENat_iff]
+#align cardinal.lt_coe_nat_iff_lt Cardinal.lt_coe_nat_iff_lt
+
+#print PartENat.card_eq_zero_iff_empty /-
+theorem card_eq_zero_iff_empty (α : Type _) : card α = 0 ↔ IsEmpty α :=
+  by
+  rw [← Cardinal.mk_eq_zero_iff]
+  conv_rhs => rw [← Nat.cast_zero]
+  rw [← Cardinal.toPartENat_eq_coe_nat_iff]
+  simp only [PartENat.card, Nat.cast_zero]
+#align part_enat.card_eq_zero_iff_empty PartENat.card_eq_zero_iff_empty
+-/
+
+#print PartENat.card_le_one_iff_subsingleton /-
+theorem card_le_one_iff_subsingleton (α : Type _) : card α ≤ 1 ↔ Subsingleton α :=
+  by
+  rw [← le_one_iff_subsingleton]
+  conv_rhs => rw [← Nat.cast_one]
+  rw [← Cardinal.toPartENat_le_natCast_iff]
+  simp only [PartENat.card, Nat.cast_one]
+#align part_enat.card_le_one_iff_subsingleton PartENat.card_le_one_iff_subsingleton
+-/
+
+#print PartENat.one_lt_card_iff_nontrivial /-
+theorem one_lt_card_iff_nontrivial (α : Type _) : 1 < card α ↔ Nontrivial α :=
+  by
+  rw [← one_lt_iff_nontrivial]
+  conv_rhs => rw [← Nat.cast_one]
+  rw [← Cardinal.coe_nat_lt_coe_iff_lt]
+  simp only [PartENat.card, Nat.cast_one]
+#align part_enat.one_lt_card_iff_nontrivial PartENat.one_lt_card_iff_nontrivial
+-/
+
+theorem is_finite_of_card {α : Type _} {n : ℕ} (hα : PartENat.card α = n) : Finite α :=
+  by
+  apply Or.resolve_right (finite_or_infinite α)
+  intro h; skip
+  apply PartENat.natCast_ne_top n
+  rw [← hα]
+  exact PartENat.card_eq_top_of_infinite
+#align part_enat.is_finite_of_card PartENat.is_finite_of_card
+
 end PartENat
 
Diff
@@ -64,13 +64,17 @@ theorem finite_of_card_ne_zero (h : Nat.card α ≠ 0) : Finite α :=
 #align nat.finite_of_card_ne_zero Nat.finite_of_card_ne_zero
 -/
 
+#print Nat.card_congr /-
 theorem card_congr (f : α ≃ β) : Nat.card α = Nat.card β :=
   Cardinal.toNat_congr f
 #align nat.card_congr Nat.card_congr
+-/
 
+#print Nat.card_eq_of_bijective /-
 theorem card_eq_of_bijective (f : α → β) (hf : Function.Bijective f) : Nat.card α = Nat.card β :=
   card_congr (Equiv.ofBijective f hf)
 #align nat.card_eq_of_bijective Nat.card_eq_of_bijective
+-/
 
 #print Nat.card_eq_of_equiv_fin /-
 theorem card_eq_of_equiv_fin {α : Type _} {n : ℕ} (f : α ≃ Fin n) : Nat.card α = n := by
@@ -127,15 +131,19 @@ theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp
 #align nat.card_of_is_empty Nat.card_of_isEmpty
 -/
 
+#print Nat.card_prod /-
 @[simp]
 theorem card_prod (α β : Type _) : Nat.card (α × β) = Nat.card α * Nat.card β := by
   simp only [Nat.card, mk_prod, to_nat_mul, to_nat_lift]
 #align nat.card_prod Nat.card_prod
+-/
 
+#print Nat.card_ulift /-
 @[simp]
 theorem card_ulift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
   card_congr Equiv.ulift
 #align nat.card_ulift Nat.card_ulift
+-/
 
 #print Nat.card_plift /-
 @[simp]
@@ -150,11 +158,13 @@ theorem card_pi {β : α → Type _} [Fintype α] : Nat.card (∀ a, β a) = ∏
 #align nat.card_pi Nat.card_pi
 -/
 
+#print Nat.card_fun /-
 theorem card_fun [Finite α] : Nat.card (α → β) = Nat.card β ^ Nat.card α :=
   by
   haveI := Fintype.ofFinite α
   rw [Nat.card_pi, Finset.prod_const, Finset.card_univ, ← Nat.card_eq_fintype_card]
 #align nat.card_fun Nat.card_fun
+-/
 
 #print Nat.card_zmod /-
 @[simp]
@@ -178,10 +188,12 @@ def card (α : Type _) : PartENat :=
 #align part_enat.card PartENat.card
 -/
 
+#print PartENat.card_eq_coe_fintype_card /-
 @[simp]
 theorem card_eq_coe_fintype_card [Fintype α] : card α = Fintype.card α :=
   mk_toPartENat_eq_coe_card
 #align part_enat.card_eq_coe_fintype_card PartENat.card_eq_coe_fintype_card
+-/
 
 #print PartENat.card_eq_top_of_infinite /-
 @[simp]
Diff
@@ -30,7 +30,7 @@ open Cardinal
 
 noncomputable section
 
-open BigOperators
+open scoped BigOperators
 
 variable {α β : Type _}
 
Diff
@@ -64,22 +64,10 @@ theorem finite_of_card_ne_zero (h : Nat.card α ≠ 0) : Finite α :=
 #align nat.finite_of_card_ne_zero Nat.finite_of_card_ne_zero
 -/
 
-/- warning: nat.card_congr -> Nat.card_congr is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, (Equiv.{succ u1, succ u2} α β) -> (Eq.{1} Nat (Nat.card.{u1} α) (Nat.card.{u2} β))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, (Equiv.{succ u2, succ u1} α β) -> (Eq.{1} Nat (Nat.card.{u2} α) (Nat.card.{u1} β))
-Case conversion may be inaccurate. Consider using '#align nat.card_congr Nat.card_congrₓ'. -/
 theorem card_congr (f : α ≃ β) : Nat.card α = Nat.card β :=
   Cardinal.toNat_congr f
 #align nat.card_congr Nat.card_congr
 
-/- warning: nat.card_eq_of_bijective -> Nat.card_eq_of_bijective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (f : α -> β), (Function.Bijective.{succ u1, succ u2} α β f) -> (Eq.{1} Nat (Nat.card.{u1} α) (Nat.card.{u2} β))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (f : α -> β), (Function.Bijective.{succ u2, succ u1} α β f) -> (Eq.{1} Nat (Nat.card.{u2} α) (Nat.card.{u1} β))
-Case conversion may be inaccurate. Consider using '#align nat.card_eq_of_bijective Nat.card_eq_of_bijectiveₓ'. -/
 theorem card_eq_of_bijective (f : α → β) (hf : Function.Bijective f) : Nat.card α = Nat.card β :=
   card_congr (Equiv.ofBijective f hf)
 #align nat.card_eq_of_bijective Nat.card_eq_of_bijective
@@ -139,23 +127,11 @@ theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp
 #align nat.card_of_is_empty Nat.card_of_isEmpty
 -/
 
-/- warning: nat.card_prod -> Nat.card_prod is a dubious translation:
-lean 3 declaration is
-  forall (α : Type.{u1}) (β : Type.{u2}), Eq.{1} Nat (Nat.card.{max u1 u2} (Prod.{u1, u2} α β)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Nat.card.{u1} α) (Nat.card.{u2} β))
-but is expected to have type
-  forall (α : Type.{u2}) (β : Type.{u1}), Eq.{1} Nat (Nat.card.{max u1 u2} (Prod.{u2, u1} α β)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Nat.card.{u2} α) (Nat.card.{u1} β))
-Case conversion may be inaccurate. Consider using '#align nat.card_prod Nat.card_prodₓ'. -/
 @[simp]
 theorem card_prod (α β : Type _) : Nat.card (α × β) = Nat.card α * Nat.card β := by
   simp only [Nat.card, mk_prod, to_nat_mul, to_nat_lift]
 #align nat.card_prod Nat.card_prod
 
-/- warning: nat.card_ulift -> Nat.card_ulift is a dubious translation:
-lean 3 declaration is
-  forall (α : Type.{u1}), Eq.{1} Nat (Nat.card.{max u1 u2} (ULift.{u2, u1} α)) (Nat.card.{u1} α)
-but is expected to have type
-  forall (α : Type.{u2}), Eq.{1} Nat (Nat.card.{max u2 u1} (ULift.{u1, u2} α)) (Nat.card.{u2} α)
-Case conversion may be inaccurate. Consider using '#align nat.card_ulift Nat.card_uliftₓ'. -/
 @[simp]
 theorem card_ulift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
   card_congr Equiv.ulift
@@ -174,12 +150,6 @@ theorem card_pi {β : α → Type _} [Fintype α] : Nat.card (∀ a, β a) = ∏
 #align nat.card_pi Nat.card_pi
 -/
 
-/- warning: nat.card_fun -> Nat.card_fun is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : Finite.{succ u1} α], Eq.{1} Nat (Nat.card.{max u1 u2} (α -> β)) (HPow.hPow.{0, 0, 0} Nat Nat Nat (instHPow.{0, 0} Nat Nat (Monoid.Pow.{0} Nat Nat.monoid)) (Nat.card.{u2} β) (Nat.card.{u1} α))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : Finite.{succ u2} α], Eq.{1} Nat (Nat.card.{max u2 u1} (α -> β)) (HPow.hPow.{0, 0, 0} Nat Nat Nat (instHPow.{0, 0} Nat Nat instPowNat) (Nat.card.{u1} β) (Nat.card.{u2} α))
-Case conversion may be inaccurate. Consider using '#align nat.card_fun Nat.card_funₓ'. -/
 theorem card_fun [Finite α] : Nat.card (α → β) = Nat.card β ^ Nat.card α :=
   by
   haveI := Fintype.ofFinite α
@@ -208,12 +178,6 @@ def card (α : Type _) : PartENat :=
 #align part_enat.card PartENat.card
 -/
 
-/- warning: part_enat.card_eq_coe_fintype_card -> PartENat.card_eq_coe_fintype_card is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : Fintype.{u1} α], Eq.{1} PartENat (PartENat.card.{u1} α) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat PartENat (HasLiftT.mk.{1, 1} Nat PartENat (CoeTCₓ.coe.{1, 1} Nat PartENat (Nat.castCoe.{0} PartENat (AddMonoidWithOne.toNatCast.{0} PartENat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} PartENat PartENat.addCommMonoidWithOne))))) (Fintype.card.{u1} α _inst_1))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : Fintype.{u1} α], Eq.{1} PartENat (PartENat.card.{u1} α) (Nat.cast.{0} PartENat (AddMonoidWithOne.toNatCast.{0} PartENat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} PartENat PartENat.instAddCommMonoidWithOnePartENat)) (Fintype.card.{u1} α _inst_1))
-Case conversion may be inaccurate. Consider using '#align part_enat.card_eq_coe_fintype_card PartENat.card_eq_coe_fintype_cardₓ'. -/
 @[simp]
 theorem card_eq_coe_fintype_card [Fintype α] : card α = Fintype.card α :=
   mk_toPartENat_eq_coe_card
Diff
@@ -150,22 +150,22 @@ theorem card_prod (α β : Type _) : Nat.card (α × β) = Nat.card α * Nat.car
   simp only [Nat.card, mk_prod, to_nat_mul, to_nat_lift]
 #align nat.card_prod Nat.card_prod
 
-/- warning: nat.card_ulift -> Nat.card_uLift is a dubious translation:
+/- warning: nat.card_ulift -> Nat.card_ulift is a dubious translation:
 lean 3 declaration is
   forall (α : Type.{u1}), Eq.{1} Nat (Nat.card.{max u1 u2} (ULift.{u2, u1} α)) (Nat.card.{u1} α)
 but is expected to have type
   forall (α : Type.{u2}), Eq.{1} Nat (Nat.card.{max u2 u1} (ULift.{u1, u2} α)) (Nat.card.{u2} α)
-Case conversion may be inaccurate. Consider using '#align nat.card_ulift Nat.card_uLiftₓ'. -/
+Case conversion may be inaccurate. Consider using '#align nat.card_ulift Nat.card_uliftₓ'. -/
 @[simp]
-theorem card_uLift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
+theorem card_ulift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
   card_congr Equiv.ulift
-#align nat.card_ulift Nat.card_uLift
+#align nat.card_ulift Nat.card_ulift
 
-#print Nat.card_pLift /-
+#print Nat.card_plift /-
 @[simp]
-theorem card_pLift (α : Type _) : Nat.card (PLift α) = Nat.card α :=
+theorem card_plift (α : Type _) : Nat.card (PLift α) = Nat.card α :=
   card_congr Equiv.plift
-#align nat.card_plift Nat.card_pLift
+#align nat.card_plift Nat.card_plift
 -/
 
 #print Nat.card_pi /-
@@ -186,14 +186,14 @@ theorem card_fun [Finite α] : Nat.card (α → β) = Nat.card β ^ Nat.card α
   rw [Nat.card_pi, Finset.prod_const, Finset.card_univ, ← Nat.card_eq_fintype_card]
 #align nat.card_fun Nat.card_fun
 
-#print Nat.card_zMod /-
+#print Nat.card_zmod /-
 @[simp]
-theorem card_zMod (n : ℕ) : Nat.card (ZMod n) = n :=
+theorem card_zmod (n : ℕ) : Nat.card (ZMod n) = n :=
   by
   cases n
   · exact Nat.card_eq_zero_of_infinite
   · rw [Nat.card_eq_fintype_card, ZMod.card]
-#align nat.card_zmod Nat.card_zMod
+#align nat.card_zmod Nat.card_zmod
 -/
 
 end Nat

Changes in mathlib4

mathlib3
mathlib4
chore: add lemmas for nat literals corresponding to lemmas for nat casts (#8006)

I loogled for every occurrence of "cast", Nat and "natCast" and where the casted nat was n, and made sure there were corresponding @[simp] lemmas for 0, 1, and OfNat.ofNat n. This is necessary in general for simp confluence. Example:

import Mathlib

variable {α : Type*} [LinearOrderedRing α] (m n : ℕ) [m.AtLeastTwo] [n.AtLeastTwo]

example : ((OfNat.ofNat m : ℕ) : α) ≤ ((OfNat.ofNat n : ℕ) : α) ↔ (OfNat.ofNat m : ℕ) ≤ (OfNat.ofNat n : ℕ) := by
  simp only [Nat.cast_le] -- this `@[simp]` lemma can apply

example : ((OfNat.ofNat m : ℕ) : α) ≤ ((OfNat.ofNat n : ℕ) : α) ↔ (OfNat.ofNat m : α) ≤ (OfNat.ofNat n : α) := by
  simp only [Nat.cast_ofNat] -- and so can this one

example : (OfNat.ofNat m : α) ≤ (OfNat.ofNat n : α) ↔ (OfNat.ofNat m : ℕ) ≤ (OfNat.ofNat n : ℕ) := by
  simp -- fails! `simp` doesn't have a lemma to bridge their results. confluence issue.

As far as I know, the only file this PR leaves with ofNat gaps is PartENat.lean. #8002 is addressing that file in parallel.

Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -257,6 +257,7 @@ theorem card_image_of_injective {α : Type u} {β : Type v} (f : α → β) (s :
 #align part_enat.card_image_of_injective PartENat.card_image_of_injective
 
 -- Should I keeep the 6 following lemmas ?
+-- TODO: Add ofNat, zero, and one versions for simp confluence
 @[simp]
 theorem _root_.Cardinal.natCast_le_toPartENat_iff {n : ℕ} {c : Cardinal} :
     ↑n ≤ toPartENat c ↔ ↑n ≤ c := by
chore: classify simp can do this porting notes (#10619)

Classify by adding issue number (#10618) to porting notes claiming anything semantically equivalent to simp can prove this or simp can simplify this.

Diff
@@ -147,7 +147,7 @@ theorem card_of_subsingleton (a : α) [Subsingleton α] : Nat.card α = 1 := by
   rw [card_eq_fintype_card, Fintype.card_ofSubsingleton a]
 #align nat.card_of_subsingleton Nat.card_of_subsingleton
 
--- @[simp] -- Porting note: simp can prove this
+-- @[simp] -- Porting note (#10618): simp can prove this
 theorem card_unique [Unique α] : Nat.card α = 1 :=
   card_of_subsingleton default
 #align nat.card_unique Nat.card_unique
perf: speed up galActionHom_bijective_of_prime_degree (#10608)

This takes the proof from approximately 3 seconds to half a second on my laptop.

convert spent a fair amount of time dealing with the equality of Fintype.card calls with the same type but different Fintype instances. This sidesteps the issue by translating to Nat.card, which doesn't have the instance argument.

Diff
@@ -42,6 +42,11 @@ theorem card_eq_fintype_card [Fintype α] : Nat.card α = Fintype.card α :=
   mk_toNat_eq_card
 #align nat.card_eq_fintype_card Nat.card_eq_fintype_card
 
+/-- Because this theorem takes `Fintype α` as a non-instance argument, it can be used in particular
+when `Fintype.card` ends up with different instance than the one found by inference  -/
+theorem _root_.Fintype.card_eq_nat_card {_ : Fintype α} : Fintype.card α = Nat.card α :=
+  mk_toNat_eq_card.symm
+
 lemma card_eq_finsetCard (s : Finset α) : Nat.card s = s.card := by
   simp only [Nat.card_eq_fintype_card, Fintype.card_coe]
 
refactor(Cardinal): redefine toNat and toPartENat (#10472)

Redefine these operations in terms of toENat.

Diff
@@ -79,13 +79,12 @@ theorem card_congr (f : α ≃ β) : Nat.card α = Nat.card β :=
 
 lemma card_le_card_of_injective {α : Type u} {β : Type v} [Finite β] (f : α → β)
     (hf : Injective f) : Nat.card α ≤ Nat.card β := by
-  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) <|
-    mk_le_of_injective (α := ULift.{max u v} α) (β := ULift.{max u v} β) <| ULift.map_injective.2 hf
+  simpa using toNat_le_toNat (lift_mk_le_lift_mk_of_injective hf) (by simp [lt_aleph0_of_finite])
 
 lemma card_le_card_of_surjective {α : Type u} {β : Type v} [Finite α] (f : α → β)
     (hf : Surjective f) : Nat.card β ≤ Nat.card α := by
-  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) <| mk_le_of_surjective
-    (α := ULift.{max u v} α) (β := ULift.{max u v} β) <| ULift.map_surjective.2 hf
+  have : lift.{u} #β ≤ lift.{v} #α := mk_le_of_surjective (ULift.map_surjective.2 hf)
+  simpa using toNat_le_toNat this (by simp [lt_aleph0_of_finite])
 
 theorem card_eq_of_bijective (f : α → β) (hf : Function.Bijective f) : Nat.card α = Nat.card β :=
   card_congr (Equiv.ofBijective f hf)
@@ -100,7 +99,7 @@ open Set
 variable {s t : Set α}
 
 lemma card_mono (ht : t.Finite) (h : s ⊆ t) : Nat.card s ≤ Nat.card t :=
-  toNat_le_of_le_of_lt_aleph0 ht.lt_aleph0 <| mk_le_mk_of_subset h
+  toNat_le_toNat (mk_le_mk_of_subset h) ht.lt_aleph0
 
 lemma card_image_le (hs : s.Finite) : Nat.card (f '' s) ≤ Nat.card s :=
   have := hs.to_subtype; card_le_card_of_surjective (imageFactorization f s) surjective_onto_image
@@ -182,7 +181,7 @@ theorem card_plift (α : Type*) : Nat.card (PLift α) = Nat.card α :=
 #align nat.card_plift Nat.card_plift
 
 theorem card_pi {β : α → Type*} [Fintype α] : Nat.card (∀ a, β a) = ∏ a, Nat.card (β a) := by
-  simp_rw [Nat.card, mk_pi, prod_eq_of_fintype, toNat_lift, toNat_finset_prod]
+  simp_rw [Nat.card, mk_pi, prod_eq_of_fintype, toNat_lift, map_prod]
 #align nat.card_pi Nat.card_pi
 
 theorem card_fun [Finite α] : Nat.card (α → β) = Nat.card β ^ Nat.card α := by
@@ -256,13 +255,13 @@ theorem card_image_of_injective {α : Type u} {β : Type v} (f : α → β) (s :
 @[simp]
 theorem _root_.Cardinal.natCast_le_toPartENat_iff {n : ℕ} {c : Cardinal} :
     ↑n ≤ toPartENat c ↔ ↑n ≤ c := by
-  rw [← toPartENat_cast n, toPartENat_le_iff_of_le_aleph0 (le_of_lt (nat_lt_aleph0 n))]
+  rw [← toPartENat_natCast n, toPartENat_le_iff_of_le_aleph0 (le_of_lt (nat_lt_aleph0 n))]
 #align cardinal.coe_nat_le_to_part_enat_iff Cardinal.natCast_le_toPartENat_iff
 
 @[simp]
 theorem _root_.Cardinal.toPartENat_le_natCast_iff {c : Cardinal} {n : ℕ} :
     toPartENat c ≤ n ↔ c ≤ n := by
-  rw [← toPartENat_cast n, toPartENat_le_iff_of_lt_aleph0 (nat_lt_aleph0 n)]
+  rw [← toPartENat_natCast n, toPartENat_le_iff_of_lt_aleph0 (nat_lt_aleph0 n)]
 #align cardinal.to_part_enat_le_coe_nat_iff Cardinal.toPartENat_le_natCast_iff
 
 @[simp]
chore(Cardinal/Basic): split (#10466)

Move toNat and toPartENat to new files.

No changes in the code moved to the new files. One lemma remains in Basic but used toNat in the proof, so I changed the proof.

I'm going to redefine them in terms of toENat, so I need to move them out of Basic first.

Diff
@@ -5,7 +5,7 @@ Authors: Aaron Anderson
 -/
 import Mathlib.Data.ULift
 import Mathlib.Data.ZMod.Defs
-import Mathlib.SetTheory.Cardinal.Basic
+import Mathlib.SetTheory.Cardinal.PartENat
 
 #align_import set_theory.cardinal.finite from "leanprover-community/mathlib"@"3ff3f2d6a3118b8711063de7111a0d77a53219a8"
 
chore(*): replace $ with <| (#9319)

See Zulip thread for the discussion.

Diff
@@ -79,13 +79,13 @@ theorem card_congr (f : α ≃ β) : Nat.card α = Nat.card β :=
 
 lemma card_le_card_of_injective {α : Type u} {β : Type v} [Finite β] (f : α → β)
     (hf : Injective f) : Nat.card α ≤ Nat.card β := by
-  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) $
-    mk_le_of_injective (α := ULift.{max u v} α) (β := ULift.{max u v} β) $ ULift.map_injective.2 hf
+  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) <|
+    mk_le_of_injective (α := ULift.{max u v} α) (β := ULift.{max u v} β) <| ULift.map_injective.2 hf
 
 lemma card_le_card_of_surjective {α : Type u} {β : Type v} [Finite α] (f : α → β)
     (hf : Surjective f) : Nat.card β ≤ Nat.card α := by
-  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) $ mk_le_of_surjective
-    (α := ULift.{max u v} α) (β := ULift.{max u v} β) $ ULift.map_surjective.2 hf
+  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) <| mk_le_of_surjective
+    (α := ULift.{max u v} α) (β := ULift.{max u v} β) <| ULift.map_surjective.2 hf
 
 theorem card_eq_of_bijective (f : α → β) (hf : Function.Bijective f) : Nat.card α = Nat.card β :=
   card_congr (Equiv.ofBijective f hf)
@@ -116,7 +116,7 @@ lemma card_image_of_injOn (hf : s.InjOn f) : Nat.card (f '' s) = Nat.card s := b
     simp [Nat.card_eq_zero_of_infinite]
 
 lemma card_image_of_injective (hf : Injective f) (s : Set α) :
-    Nat.card (f '' s) = Nat.card s := card_image_of_injOn $ hf.injOn _
+    Nat.card (f '' s) = Nat.card s := card_image_of_injOn <| hf.injOn _
 
 lemma card_image_equiv (e : α ≃ β) : Nat.card (e '' s) = Nat.card s :=
     Nat.card_congr (e.image s).symm
feat: Preimage of pointwise multiplication (#8956)

From PFR

Co-authored-by: Patrick Massot <patrickmassot@free.fr>

Diff
@@ -42,6 +42,18 @@ theorem card_eq_fintype_card [Fintype α] : Nat.card α = Fintype.card α :=
   mk_toNat_eq_card
 #align nat.card_eq_fintype_card Nat.card_eq_fintype_card
 
+lemma card_eq_finsetCard (s : Finset α) : Nat.card s = s.card := by
+  simp only [Nat.card_eq_fintype_card, Fintype.card_coe]
+
+lemma card_eq_card_toFinset (s : Set α) [Fintype s] : Nat.card s = s.toFinset.card := by
+  simp only [← Nat.card_eq_finsetCard, s.mem_toFinset]
+
+lemma card_eq_card_finite_toFinset {s : Set α} (hs : s.Finite) : Nat.card s = hs.toFinset.card := by
+  simp only [← Nat.card_eq_finsetCard, hs.mem_toFinset]
+
+@[simp] theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp [Nat.card]
+#align nat.card_of_is_empty Nat.card_of_isEmpty
+
 @[simp] lemma card_eq_zero_of_infinite [Infinite α] : Nat.card α = 0 := mk_toNat_of_infinite
 #align nat.card_eq_zero_of_infinite Nat.card_eq_zero_of_infinite
 
@@ -83,9 +95,41 @@ theorem card_eq_of_equiv_fin {α : Type*} {n : ℕ} (f : α ≃ Fin n) : Nat.car
   simpa only [card_eq_fintype_card, Fintype.card_fin] using card_congr f
 #align nat.card_eq_of_equiv_fin Nat.card_eq_of_equiv_fin
 
-lemma card_mono {s t : Set α} (ht : t.Finite) (h : s ⊆ t) : Nat.card s ≤ Nat.card t :=
+section Set
+open Set
+variable {s t : Set α}
+
+lemma card_mono (ht : t.Finite) (h : s ⊆ t) : Nat.card s ≤ Nat.card t :=
   toNat_le_of_le_of_lt_aleph0 ht.lt_aleph0 <| mk_le_mk_of_subset h
 
+lemma card_image_le (hs : s.Finite) : Nat.card (f '' s) ≤ Nat.card s :=
+  have := hs.to_subtype; card_le_card_of_surjective (imageFactorization f s) surjective_onto_image
+
+lemma card_image_of_injOn (hf : s.InjOn f) : Nat.card (f '' s) = Nat.card s := by
+  classical
+  obtain hs | hs := s.finite_or_infinite
+  · have := hs.fintype
+    have := fintypeImage s f
+    simp_rw [Nat.card_eq_fintype_card, Set.card_image_of_inj_on hf]
+  · have := hs.to_subtype
+    have := (hs.image hf).to_subtype
+    simp [Nat.card_eq_zero_of_infinite]
+
+lemma card_image_of_injective (hf : Injective f) (s : Set α) :
+    Nat.card (f '' s) = Nat.card s := card_image_of_injOn $ hf.injOn _
+
+lemma card_image_equiv (e : α ≃ β) : Nat.card (e '' s) = Nat.card s :=
+    Nat.card_congr (e.image s).symm
+
+lemma card_preimage_of_injOn {s : Set β} (hf : (f ⁻¹' s).InjOn f) (hsf : s ⊆ range f) :
+    Nat.card (f ⁻¹' s) = Nat.card s := by
+  rw [← Nat.card_image_of_injOn hf, image_preimage_eq_iff.2 hsf]
+
+lemma card_preimage_of_injective {s : Set β} (hf : Injective f) (hsf : s ⊆ range f) :
+    Nat.card (f ⁻¹' s) = Nat.card s := card_preimage_of_injOn (hf.injOn _) hsf
+
+end Set
+
 /-- If the cardinality is positive, that means it is a finite type, so there is
 an equivalence between `α` and `Fin (Nat.card α)`. See also `Finite.equivFin`. -/
 def equivFinOfCardPos {α : Type*} (h : Nat.card α ≠ 0) : α ≃ Fin (Nat.card α) := by
@@ -116,9 +160,6 @@ theorem card_eq_two_iff' (x : α) : Nat.card α = 2 ↔ ∃! y, y ≠ x :=
   toNat_eq_ofNat.trans (mk_eq_two_iff' x)
 #align nat.card_eq_two_iff' Nat.card_eq_two_iff'
 
-@[simp] theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp [Nat.card]
-#align nat.card_of_is_empty Nat.card_of_isEmpty
-
 @[simp]
 theorem card_sum [Finite α] [Finite β] : Nat.card (α ⊕ β) = Nat.card α + Nat.card β := by
   have := Fintype.ofFinite α
@@ -158,6 +199,16 @@ theorem card_zmod (n : ℕ) : Nat.card (ZMod n) = n := by
 
 end Nat
 
+namespace Set
+
+lemma card_singleton_prod (a : α) (t : Set β) : Nat.card ({a} ×ˢ t) = Nat.card t := by
+  rw [singleton_prod, Nat.card_image_of_injective (Prod.mk.inj_left a)]
+
+lemma card_prod_singleton (s : Set α) (b : β) : Nat.card (s ×ˢ {b}) = Nat.card s := by
+  rw [prod_singleton, Nat.card_image_of_injective (Prod.mk.inj_right b)]
+
+end Set
+
 namespace PartENat
 
 /-- `PartENat.card α` is the cardinality of `α` as an extended natural number.
feat: demote the instance Fintype.ofIsEmpty to a def (#8816)

Rationale: this instance creates (empty) data out of nothing, which may conflict with other data. If you have in the context [Fintype i] and case on whether i is empty or not, then this gave two non-defeq instances of [Fintype i] around.

Diff
@@ -42,7 +42,6 @@ theorem card_eq_fintype_card [Fintype α] : Nat.card α = Fintype.card α :=
   mk_toNat_eq_card
 #align nat.card_eq_fintype_card Nat.card_eq_fintype_card
 
-lemma card_eq_zero_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp [Nat.card]
 @[simp] lemma card_eq_zero_of_infinite [Infinite α] : Nat.card α = 0 := mk_toNat_of_infinite
 #align nat.card_eq_zero_of_infinite Nat.card_eq_zero_of_infinite
 
@@ -117,7 +116,7 @@ theorem card_eq_two_iff' (x : α) : Nat.card α = 2 ↔ ∃! y, y ≠ x :=
   toNat_eq_ofNat.trans (mk_eq_two_iff' x)
 #align nat.card_eq_two_iff' Nat.card_eq_two_iff'
 
-theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp
+@[simp] theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp [Nat.card]
 #align nat.card_of_is_empty Nat.card_of_isEmpty
 
 @[simp]
chore: bump to v4.3.0-rc2 (#8366)

PR contents

This is the supremum of

along with some minor fixes from failures on nightly-testing as Mathlib master is merged into it.

Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.

I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0 branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.

Lean PRs involved in this bump

In particular this includes adjustments for the Lean PRs

leanprover/lean4#2778

We can get rid of all the

local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)

macros across Mathlib (and in any projects that want to write natural number powers of reals).

leanprover/lean4#2722

Changes the default behaviour of simp to (config := {decide := false}). This makes simp (and consequentially norm_num) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp or norm_num to decide or rfl, or adding (config := {decide := true}).

leanprover/lean4#2783

This changed the behaviour of simp so that simp [f] will only unfold "fully applied" occurrences of f. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true }). We may in future add a syntax for this, e.g. simp [!f]; please provide feedback! In the meantime, we have made the following changes:

  • switching to using explicit lemmas that have the intended level of application
  • (config := { unfoldPartialApp := true }) in some places, to recover the old behaviour
  • Using @[eqns] to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp and Function.flip.

This change in Lean may require further changes down the line (e.g. adding the !f syntax, and/or upstreaming the special treatment for Function.comp and Function.flip, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!

Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>

Diff
@@ -92,7 +92,7 @@ an equivalence between `α` and `Fin (Nat.card α)`. See also `Finite.equivFin`.
 def equivFinOfCardPos {α : Type*} (h : Nat.card α ≠ 0) : α ≃ Fin (Nat.card α) := by
   cases fintypeOrInfinite α
   · simpa only [card_eq_fintype_card] using Fintype.equivFin α
-  · simp only [card_eq_zero_of_infinite, ne_eq] at h
+  · simp only [card_eq_zero_of_infinite, ne_eq, not_true_eq_false] at h
 #align nat.equiv_fin_of_card_pos Nat.equivFinOfCardPos
 
 theorem card_of_subsingleton (a : α) [Subsingleton α] : Nat.card α = 1 := by
chore: Fix name of Nat.card_mono (#8340)

This was accidentally put in the PartENat namespace in #8202. Also add Set.Infinite.card_eq_zero and fix capitalisation errors.

Diff
@@ -46,6 +46,9 @@ lemma card_eq_zero_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp [Nat.car
 @[simp] lemma card_eq_zero_of_infinite [Infinite α] : Nat.card α = 0 := mk_toNat_of_infinite
 #align nat.card_eq_zero_of_infinite Nat.card_eq_zero_of_infinite
 
+lemma _root_.Set.Infinite.card_eq_zero {s : Set α} (hs : s.Infinite) : Nat.card s = 0 :=
+  @card_eq_zero_of_infinite _ hs.to_subtype
+
 lemma card_eq_zero : Nat.card α = 0 ↔ IsEmpty α ∨ Infinite α := by
   simp [Nat.card, mk_eq_zero_iff, aleph0_le_mk_iff]
 
@@ -81,6 +84,9 @@ theorem card_eq_of_equiv_fin {α : Type*} {n : ℕ} (f : α ≃ Fin n) : Nat.car
   simpa only [card_eq_fintype_card, Fintype.card_fin] using card_congr f
 #align nat.card_eq_of_equiv_fin Nat.card_eq_of_equiv_fin
 
+lemma card_mono {s t : Set α} (ht : t.Finite) (h : s ⊆ t) : Nat.card s ≤ Nat.card t :=
+  toNat_le_of_le_of_lt_aleph0 ht.lt_aleph0 <| mk_le_mk_of_subset h
+
 /-- If the cardinality is positive, that means it is a finite type, so there is
 an equivalence between `α` and `Fin (Nat.card α)`. See also `Finite.equivFin`. -/
 def equivFinOfCardPos {α : Type*} (h : Nat.card α ≠ 0) : α ≃ Fin (Nat.card α) := by
@@ -180,17 +186,11 @@ theorem card_congr {α : Type*} {β : Type*} (f : α ≃ β) : PartENat.card α
   Cardinal.toPartENat_congr f
 #align part_enat.card_congr PartENat.card_congr
 
-theorem card_uLift (α : Type*) : card (ULift α) = card α :=
-  card_congr Equiv.ulift
-#align part_enat.card_ulift PartENat.card_uLift
-
-@[simp]
-theorem card_pLift (α : Type*) : card (PLift α) = card α :=
-  card_congr Equiv.plift
-#align part_enat.card_plift PartENat.card_pLift
+@[simp] lemma card_ulift (α : Type*) : card (ULift α) = card α := card_congr Equiv.ulift
+#align part_enat.card_ulift PartENat.card_ulift
 
-lemma card_mono {s t : Set α} (ht : t.Finite) (h : s ⊆ t) : Nat.card s ≤ Nat.card t :=
-  toNat_le_of_le_of_lt_aleph0 ht.lt_aleph0 <| mk_le_mk_of_subset h
+@[simp] lemma card_plift (α : Type*) : card (PLift α) = card α := card_congr Equiv.plift
+#align part_enat.card_plift PartENat.card_plift
 
 theorem card_image_of_injOn {α : Type u} {β : Type v} {f : α → β} {s : Set α} (h : Set.InjOn f s) :
     card (f '' s) = card s :=
feat: When Nat.card is zero (#8202)

and lemmas about injectivity/surjectivity of PLift.map/ULift.map.

Diff
@@ -3,6 +3,7 @@ Copyright (c) 2021 Aaron Anderson. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
 -/
+import Mathlib.Data.ULift
 import Mathlib.Data.ZMod.Defs
 import Mathlib.SetTheory.Cardinal.Basic
 
@@ -21,13 +22,11 @@ import Mathlib.SetTheory.Cardinal.Basic
 
 set_option autoImplicit true
 
-
-open Cardinal
+open Cardinal Function
+open scoped BigOperators
 
 noncomputable section
 
-open BigOperators
-
 variable {α β : Type*}
 
 namespace Nat
@@ -43,19 +42,37 @@ theorem card_eq_fintype_card [Fintype α] : Nat.card α = Fintype.card α :=
   mk_toNat_eq_card
 #align nat.card_eq_fintype_card Nat.card_eq_fintype_card
 
-@[simp]
-theorem card_eq_zero_of_infinite [Infinite α] : Nat.card α = 0 :=
-  mk_toNat_of_infinite
+lemma card_eq_zero_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp [Nat.card]
+@[simp] lemma card_eq_zero_of_infinite [Infinite α] : Nat.card α = 0 := mk_toNat_of_infinite
 #align nat.card_eq_zero_of_infinite Nat.card_eq_zero_of_infinite
 
-theorem finite_of_card_ne_zero (h : Nat.card α ≠ 0) : Finite α :=
-  not_infinite_iff_finite.mp <| h ∘ @Nat.card_eq_zero_of_infinite α
+lemma card_eq_zero : Nat.card α = 0 ↔ IsEmpty α ∨ Infinite α := by
+  simp [Nat.card, mk_eq_zero_iff, aleph0_le_mk_iff]
+
+lemma card_ne_zero : Nat.card α ≠ 0 ↔ Nonempty α ∧ Finite α := by simp [card_eq_zero, not_or]
+
+lemma card_pos_iff : 0 < Nat.card α ↔ Nonempty α ∧ Finite α := by
+  simp [Nat.card, mk_eq_zero_iff, mk_lt_aleph0_iff]
+
+@[simp] lemma card_pos [Nonempty α] [Finite α] : 0 < Nat.card α := card_pos_iff.2 ⟨‹_›, ‹_›⟩
+
+theorem finite_of_card_ne_zero (h : Nat.card α ≠ 0) : Finite α := (card_ne_zero.1 h).2
 #align nat.finite_of_card_ne_zero Nat.finite_of_card_ne_zero
 
 theorem card_congr (f : α ≃ β) : Nat.card α = Nat.card β :=
   Cardinal.toNat_congr f
 #align nat.card_congr Nat.card_congr
 
+lemma card_le_card_of_injective {α : Type u} {β : Type v} [Finite β] (f : α → β)
+    (hf : Injective f) : Nat.card α ≤ Nat.card β := by
+  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) $
+    mk_le_of_injective (α := ULift.{max u v} α) (β := ULift.{max u v} β) $ ULift.map_injective.2 hf
+
+lemma card_le_card_of_surjective {α : Type u} {β : Type v} [Finite α] (f : α → β)
+    (hf : Surjective f) : Nat.card β ≤ Nat.card α := by
+  simpa using toNat_le_of_le_of_lt_aleph0 (by simp [lt_aleph0_of_finite]) $ mk_le_of_surjective
+    (α := ULift.{max u v} α) (β := ULift.{max u v} β) $ ULift.map_surjective.2 hf
+
 theorem card_eq_of_bijective (f : α → β) (hf : Function.Bijective f) : Nat.card α = Nat.card β :=
   card_congr (Equiv.ofBijective f hf)
 #align nat.card_eq_of_bijective Nat.card_eq_of_bijective
@@ -172,6 +189,9 @@ theorem card_pLift (α : Type*) : card (PLift α) = card α :=
   card_congr Equiv.plift
 #align part_enat.card_plift PartENat.card_pLift
 
+lemma card_mono {s t : Set α} (ht : t.Finite) (h : s ⊆ t) : Nat.card s ≤ Nat.card t :=
+  toNat_le_of_le_of_lt_aleph0 ht.lt_aleph0 <| mk_le_mk_of_subset h
+
 theorem card_image_of_injOn {α : Type u} {β : Type v} {f : α → β} {s : Set α} (h : Set.InjOn f s) :
     card (f '' s) = card s :=
   card_congr (Equiv.Set.imageOfInjOn f s h).symm
chore: only four spaces for subsequent lines (#7286)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -185,38 +185,38 @@ theorem card_image_of_injective {α : Type u} {β : Type v} (f : α → β) (s :
 -- Should I keeep the 6 following lemmas ?
 @[simp]
 theorem _root_.Cardinal.natCast_le_toPartENat_iff {n : ℕ} {c : Cardinal} :
-  ↑n ≤ toPartENat c ↔ ↑n ≤ c := by
+    ↑n ≤ toPartENat c ↔ ↑n ≤ c := by
   rw [← toPartENat_cast n, toPartENat_le_iff_of_le_aleph0 (le_of_lt (nat_lt_aleph0 n))]
 #align cardinal.coe_nat_le_to_part_enat_iff Cardinal.natCast_le_toPartENat_iff
 
 @[simp]
 theorem _root_.Cardinal.toPartENat_le_natCast_iff {c : Cardinal} {n : ℕ} :
-  toPartENat c ≤ n ↔ c ≤ n := by
+    toPartENat c ≤ n ↔ c ≤ n := by
   rw [← toPartENat_cast n, toPartENat_le_iff_of_lt_aleph0 (nat_lt_aleph0 n)]
 #align cardinal.to_part_enat_le_coe_nat_iff Cardinal.toPartENat_le_natCast_iff
 
 @[simp]
 theorem _root_.Cardinal.natCast_eq_toPartENat_iff {n : ℕ} {c : Cardinal} :
-  ↑n = toPartENat c ↔ ↑n = c := by
+    ↑n = toPartENat c ↔ ↑n = c := by
   rw [le_antisymm_iff, le_antisymm_iff, Cardinal.toPartENat_le_natCast_iff,
     Cardinal.natCast_le_toPartENat_iff]
 #align cardinal.coe_nat_eq_to_part_enat_iff Cardinal.natCast_eq_toPartENat_iff
 
 @[simp]
 theorem _root_.Cardinal.toPartENat_eq_natCast_iff {c : Cardinal} {n : ℕ} :
-  Cardinal.toPartENat c = n ↔ c = n := by
+    Cardinal.toPartENat c = n ↔ c = n := by
 rw [eq_comm, Cardinal.natCast_eq_toPartENat_iff, eq_comm]
 #align cardinal.to_part_nat_eq_coe_nat_iff_eq Cardinal.toPartENat_eq_natCast_iff
 
 @[simp]
 theorem _root_.Cardinal.natCast_lt_toPartENat_iff {n : ℕ} {c : Cardinal} :
-  ↑n < toPartENat c ↔ ↑n < c := by
+    ↑n < toPartENat c ↔ ↑n < c := by
   simp only [← not_le, Cardinal.toPartENat_le_natCast_iff]
 #align part_enat.coe_nat_lt_coe_iff_lt Cardinal.natCast_lt_toPartENat_iff
 
 @[simp]
 theorem _root_.Cardinal.toPartENat_lt_natCast_iff {n : ℕ} {c : Cardinal} :
-   toPartENat c < ↑n ↔ c < ↑n :=
+    toPartENat c < ↑n ↔ c < ↑n :=
 by simp only [← not_le, Cardinal.natCast_le_toPartENat_iff]
 #align lt_coe_nat_iff_lt Cardinal.toPartENat_lt_natCast_iff
 
fix: disable autoImplicit globally (#6528)

Autoimplicits are highly controversial and also defeat the performance-improving work in #6474.

The intent of this PR is to make autoImplicit opt-in on a per-file basis, by disabling it in the lakefile and enabling it again with set_option autoImplicit true in the few files that rely on it.

That also keeps this PR small, as opposed to attempting to "fix" files to not need it any more.

I claim that many of the uses of autoImplicit in these files are accidental; situations such as:

  • Assuming variables are in scope, but pasting the lemma in the wrong section
  • Pasting in a lemma from a scratch file without checking to see if the variable names are consistent with the rest of the file
  • Making a copy-paste error between lemmas and forgetting to add an explicit arguments.

Having set_option autoImplicit false as the default prevents these types of mistake being made in the 90% of files where autoImplicits are not used at all, and causes them to be caught by CI during review.

I think there were various points during the port where we encouraged porters to delete the universes u v lines; I think having autoparams for universe variables only would cover a lot of the cases we actually use them, while avoiding any real shortcomings.

A Zulip poll (after combining overlapping votes accordingly) was in favor of this change with 5:5:18 as the no:dontcare:yes vote ratio.

While this PR was being reviewed, a handful of files gained some more likely-accidental autoImplicits. In these places, set_option autoImplicit true has been placed locally within a section, rather than at the top of the file.

Diff
@@ -19,6 +19,8 @@ import Mathlib.SetTheory.Cardinal.Basic
   (using `Part ℕ`). If `α` is infinite, `PartENat.card α = ⊤`.
 -/
 
+set_option autoImplicit true
+
 
 open Cardinal
 
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -26,13 +26,13 @@ noncomputable section
 
 open BigOperators
 
-variable {α β : Type _}
+variable {α β : Type*}
 
 namespace Nat
 
 /-- `Nat.card α` is the cardinality of `α` as a natural number.
   If `α` is infinite, `Nat.card α = 0`. -/
-protected def card (α : Type _) : ℕ :=
+protected def card (α : Type*) : ℕ :=
   toNat (mk α)
 #align nat.card Nat.card
 
@@ -58,13 +58,13 @@ theorem card_eq_of_bijective (f : α → β) (hf : Function.Bijective f) : Nat.c
   card_congr (Equiv.ofBijective f hf)
 #align nat.card_eq_of_bijective Nat.card_eq_of_bijective
 
-theorem card_eq_of_equiv_fin {α : Type _} {n : ℕ} (f : α ≃ Fin n) : Nat.card α = n := by
+theorem card_eq_of_equiv_fin {α : Type*} {n : ℕ} (f : α ≃ Fin n) : Nat.card α = n := by
   simpa only [card_eq_fintype_card, Fintype.card_fin] using card_congr f
 #align nat.card_eq_of_equiv_fin Nat.card_eq_of_equiv_fin
 
 /-- If the cardinality is positive, that means it is a finite type, so there is
 an equivalence between `α` and `Fin (Nat.card α)`. See also `Finite.equivFin`. -/
-def equivFinOfCardPos {α : Type _} (h : Nat.card α ≠ 0) : α ≃ Fin (Nat.card α) := by
+def equivFinOfCardPos {α : Type*} (h : Nat.card α ≠ 0) : α ≃ Fin (Nat.card α) := by
   cases fintypeOrInfinite α
   · simpa only [card_eq_fintype_card] using Fintype.equivFin α
   · simp only [card_eq_zero_of_infinite, ne_eq] at h
@@ -102,21 +102,21 @@ theorem card_sum [Finite α] [Finite β] : Nat.card (α ⊕ β) = Nat.card α +
   simp_rw [Nat.card_eq_fintype_card, Fintype.card_sum]
 
 @[simp]
-theorem card_prod (α β : Type _) : Nat.card (α × β) = Nat.card α * Nat.card β := by
+theorem card_prod (α β : Type*) : Nat.card (α × β) = Nat.card α * Nat.card β := by
   simp only [Nat.card, mk_prod, toNat_mul, toNat_lift]
 #align nat.card_prod Nat.card_prod
 
 @[simp]
-theorem card_ulift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
+theorem card_ulift (α : Type*) : Nat.card (ULift α) = Nat.card α :=
   card_congr Equiv.ulift
 #align nat.card_ulift Nat.card_ulift
 
 @[simp]
-theorem card_plift (α : Type _) : Nat.card (PLift α) = Nat.card α :=
+theorem card_plift (α : Type*) : Nat.card (PLift α) = Nat.card α :=
   card_congr Equiv.plift
 #align nat.card_plift Nat.card_plift
 
-theorem card_pi {β : α → Type _} [Fintype α] : Nat.card (∀ a, β a) = ∏ a, Nat.card (β a) := by
+theorem card_pi {β : α → Type*} [Fintype α] : Nat.card (∀ a, β a) = ∏ a, Nat.card (β a) := by
   simp_rw [Nat.card, mk_pi, prod_eq_of_fintype, toNat_lift, toNat_finset_prod]
 #align nat.card_pi Nat.card_pi
 
@@ -138,7 +138,7 @@ namespace PartENat
 
 /-- `PartENat.card α` is the cardinality of `α` as an extended natural number.
   If `α` is infinite, `PartENat.card α = ⊤`. -/
-def card (α : Type _) : PartENat :=
+def card (α : Type*) : PartENat :=
   toPartENat (mk α)
 #align part_enat.card PartENat.card
 
@@ -153,20 +153,20 @@ theorem card_eq_top_of_infinite [Infinite α] : card α = ⊤ :=
 #align part_enat.card_eq_top_of_infinite PartENat.card_eq_top_of_infinite
 
 @[simp]
-theorem card_sum (α β : Type _) :
+theorem card_sum (α β : Type*) :
     PartENat.card (α ⊕ β) = PartENat.card α + PartENat.card β := by
   simp only [PartENat.card, Cardinal.mk_sum, map_add, Cardinal.toPartENat_lift]
 
-theorem card_congr {α : Type _} {β : Type _} (f : α ≃ β) : PartENat.card α = PartENat.card β :=
+theorem card_congr {α : Type*} {β : Type*} (f : α ≃ β) : PartENat.card α = PartENat.card β :=
   Cardinal.toPartENat_congr f
 #align part_enat.card_congr PartENat.card_congr
 
-theorem card_uLift (α : Type _) : card (ULift α) = card α :=
+theorem card_uLift (α : Type*) : card (ULift α) = card α :=
   card_congr Equiv.ulift
 #align part_enat.card_ulift PartENat.card_uLift
 
 @[simp]
-theorem card_pLift (α : Type _) : card (PLift α) = card α :=
+theorem card_pLift (α : Type*) : card (PLift α) = card α :=
   card_congr Equiv.plift
 #align part_enat.card_plift PartENat.card_pLift
 
@@ -218,21 +218,21 @@ theorem _root_.Cardinal.toPartENat_lt_natCast_iff {n : ℕ} {c : Cardinal} :
 by simp only [← not_le, Cardinal.natCast_le_toPartENat_iff]
 #align lt_coe_nat_iff_lt Cardinal.toPartENat_lt_natCast_iff
 
-theorem card_eq_zero_iff_empty (α : Type _) : card α = 0 ↔ IsEmpty α := by
+theorem card_eq_zero_iff_empty (α : Type*) : card α = 0 ↔ IsEmpty α := by
   rw [← Cardinal.mk_eq_zero_iff]
   conv_rhs => rw [← Nat.cast_zero]
   simp only [← Cardinal.toPartENat_eq_natCast_iff]
   simp only [PartENat.card, Nat.cast_zero]
 #align part_enat.card_eq_zero_iff_empty PartENat.card_eq_zero_iff_empty
 
-theorem card_le_one_iff_subsingleton (α : Type _) : card α ≤ 1 ↔ Subsingleton α := by
+theorem card_le_one_iff_subsingleton (α : Type*) : card α ≤ 1 ↔ Subsingleton α := by
   rw [← le_one_iff_subsingleton]
   conv_rhs => rw [← Nat.cast_one]
   rw [← Cardinal.toPartENat_le_natCast_iff]
   simp only [PartENat.card, Nat.cast_one]
 #align part_enat.card_le_one_iff_subsingleton PartENat.card_le_one_iff_subsingleton
 
-theorem one_lt_card_iff_nontrivial (α : Type _) : 1 < card α ↔ Nontrivial α := by
+theorem one_lt_card_iff_nontrivial (α : Type*) : 1 < card α ↔ Nontrivial α := by
   rw [← Cardinal.one_lt_iff_nontrivial]
   conv_rhs => rw [← Nat.cast_one]
   rw [← natCast_lt_toPartENat_iff]
feat(SetTheory/Cardinal): add ofNat lemmas (#6362)
Diff
@@ -85,11 +85,11 @@ theorem card_eq_one_iff_unique : Nat.card α = 1 ↔ Subsingleton α ∧ Nonempt
 #align nat.card_eq_one_iff_unique Nat.card_eq_one_iff_unique
 
 theorem card_eq_two_iff : Nat.card α = 2 ↔ ∃ x y : α, x ≠ y ∧ {x, y} = @Set.univ α :=
-  (toNat_eq_iff two_ne_zero).trans <| Iff.trans (by rw [Nat.cast_two]) mk_eq_two_iff
+  toNat_eq_ofNat.trans mk_eq_two_iff
 #align nat.card_eq_two_iff Nat.card_eq_two_iff
 
 theorem card_eq_two_iff' (x : α) : Nat.card α = 2 ↔ ∃! y, y ≠ x :=
-  (toNat_eq_iff two_ne_zero).trans <| Iff.trans (by rw [Nat.cast_two]) (mk_eq_two_iff' x)
+  toNat_eq_ofNat.trans (mk_eq_two_iff' x)
 #align nat.card_eq_two_iff' Nat.card_eq_two_iff'
 
 theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp
feat(Data.Set.Ncard): enat set cardinality (#5908)

This PR is a second attempt at defining the cardinality of a set as extended natural number, with a function encard. The implementation involves a refactor, where the existingncard function is redefined in terms of encard. This shortens a lot of proofs, reduces reliance on the Finset API, and allows for a potential future refactor where ncard is removed if it is decided to be redundant.

Co-authored-by: Jireh Loreaux <loreaujy@gmail.com>

Diff
@@ -152,6 +152,11 @@ theorem card_eq_top_of_infinite [Infinite α] : card α = ⊤ :=
   mk_toPartENat_of_infinite
 #align part_enat.card_eq_top_of_infinite PartENat.card_eq_top_of_infinite
 
+@[simp]
+theorem card_sum (α β : Type _) :
+    PartENat.card (α ⊕ β) = PartENat.card α + PartENat.card β := by
+  simp only [PartENat.card, Cardinal.mk_sum, map_add, Cardinal.toPartENat_lift]
+
 theorem card_congr {α : Type _} {β : Type _} (f : α ≃ β) : PartENat.card α = PartENat.card β :=
   Cardinal.toPartENat_congr f
 #align part_enat.card_congr PartENat.card_congr
feat: Add Nat.card_sum (#6081)

This PR adds Nat.card_sum. The finiteness assumptions cannot be dropped, unfortunately.

Co-authored-by: Thomas Browning <tb65536@users.noreply.github.com>

Diff
@@ -95,6 +95,12 @@ theorem card_eq_two_iff' (x : α) : Nat.card α = 2 ↔ ∃! y, y ≠ x :=
 theorem card_of_isEmpty [IsEmpty α] : Nat.card α = 0 := by simp
 #align nat.card_of_is_empty Nat.card_of_isEmpty
 
+@[simp]
+theorem card_sum [Finite α] [Finite β] : Nat.card (α ⊕ β) = Nat.card α + Nat.card β := by
+  have := Fintype.ofFinite α
+  have := Fintype.ofFinite β
+  simp_rw [Nat.card_eq_fintype_card, Fintype.card_sum]
+
 @[simp]
 theorem card_prod (α β : Type _) : Nat.card (α × β) = Nat.card α * Nat.card β := by
   simp only [Nat.card, mk_prod, toNat_mul, toNat_lift]
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2021 Aaron Anderson. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
-
-! This file was ported from Lean 3 source module set_theory.cardinal.finite
-! leanprover-community/mathlib commit 3ff3f2d6a3118b8711063de7111a0d77a53219a8
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Data.ZMod.Defs
 import Mathlib.SetTheory.Cardinal.Basic
 
+#align_import set_theory.cardinal.finite from "leanprover-community/mathlib"@"3ff3f2d6a3118b8711063de7111a0d77a53219a8"
+
 /-!
 # Finite Cardinality Functions
 
feat:add correct SHA to earlier PR (#5799)

Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr>

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Aaron Anderson
 
 ! This file was ported from Lean 3 source module set_theory.cardinal.finite
-! leanprover-community/mathlib commit dde670c9a3f503647fd5bfdf1037bad526d3397a
+! leanprover-community/mathlib commit 3ff3f2d6a3118b8711063de7111a0d77a53219a8
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
feat(SetTheory/Cardinal/Finite): prove lemmas about PartENat.card (#5307)

Prove lemmas to handle PartENat.card Inspired from the similar lemmas for Nat.card This is a mathlib4 companion to the PR #19198 of mathlib3

Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@math.univ-paris-diderot.fr>

Diff
@@ -149,4 +149,86 @@ theorem card_eq_top_of_infinite [Infinite α] : card α = ⊤ :=
   mk_toPartENat_of_infinite
 #align part_enat.card_eq_top_of_infinite PartENat.card_eq_top_of_infinite
 
+theorem card_congr {α : Type _} {β : Type _} (f : α ≃ β) : PartENat.card α = PartENat.card β :=
+  Cardinal.toPartENat_congr f
+#align part_enat.card_congr PartENat.card_congr
+
+theorem card_uLift (α : Type _) : card (ULift α) = card α :=
+  card_congr Equiv.ulift
+#align part_enat.card_ulift PartENat.card_uLift
+
+@[simp]
+theorem card_pLift (α : Type _) : card (PLift α) = card α :=
+  card_congr Equiv.plift
+#align part_enat.card_plift PartENat.card_pLift
+
+theorem card_image_of_injOn {α : Type u} {β : Type v} {f : α → β} {s : Set α} (h : Set.InjOn f s) :
+    card (f '' s) = card s :=
+  card_congr (Equiv.Set.imageOfInjOn f s h).symm
+#align part_enat.card_image_of_inj_on PartENat.card_image_of_injOn
+
+theorem card_image_of_injective {α : Type u} {β : Type v} (f : α → β) (s : Set α)
+    (h : Function.Injective f) : card (f '' s) = card s :=
+  card_image_of_injOn (Set.injOn_of_injective h s)
+#align part_enat.card_image_of_injective PartENat.card_image_of_injective
+
+-- Should I keeep the 6 following lemmas ?
+@[simp]
+theorem _root_.Cardinal.natCast_le_toPartENat_iff {n : ℕ} {c : Cardinal} :
+  ↑n ≤ toPartENat c ↔ ↑n ≤ c := by
+  rw [← toPartENat_cast n, toPartENat_le_iff_of_le_aleph0 (le_of_lt (nat_lt_aleph0 n))]
+#align cardinal.coe_nat_le_to_part_enat_iff Cardinal.natCast_le_toPartENat_iff
+
+@[simp]
+theorem _root_.Cardinal.toPartENat_le_natCast_iff {c : Cardinal} {n : ℕ} :
+  toPartENat c ≤ n ↔ c ≤ n := by
+  rw [← toPartENat_cast n, toPartENat_le_iff_of_lt_aleph0 (nat_lt_aleph0 n)]
+#align cardinal.to_part_enat_le_coe_nat_iff Cardinal.toPartENat_le_natCast_iff
+
+@[simp]
+theorem _root_.Cardinal.natCast_eq_toPartENat_iff {n : ℕ} {c : Cardinal} :
+  ↑n = toPartENat c ↔ ↑n = c := by
+  rw [le_antisymm_iff, le_antisymm_iff, Cardinal.toPartENat_le_natCast_iff,
+    Cardinal.natCast_le_toPartENat_iff]
+#align cardinal.coe_nat_eq_to_part_enat_iff Cardinal.natCast_eq_toPartENat_iff
+
+@[simp]
+theorem _root_.Cardinal.toPartENat_eq_natCast_iff {c : Cardinal} {n : ℕ} :
+  Cardinal.toPartENat c = n ↔ c = n := by
+rw [eq_comm, Cardinal.natCast_eq_toPartENat_iff, eq_comm]
+#align cardinal.to_part_nat_eq_coe_nat_iff_eq Cardinal.toPartENat_eq_natCast_iff
+
+@[simp]
+theorem _root_.Cardinal.natCast_lt_toPartENat_iff {n : ℕ} {c : Cardinal} :
+  ↑n < toPartENat c ↔ ↑n < c := by
+  simp only [← not_le, Cardinal.toPartENat_le_natCast_iff]
+#align part_enat.coe_nat_lt_coe_iff_lt Cardinal.natCast_lt_toPartENat_iff
+
+@[simp]
+theorem _root_.Cardinal.toPartENat_lt_natCast_iff {n : ℕ} {c : Cardinal} :
+   toPartENat c < ↑n ↔ c < ↑n :=
+by simp only [← not_le, Cardinal.natCast_le_toPartENat_iff]
+#align lt_coe_nat_iff_lt Cardinal.toPartENat_lt_natCast_iff
+
+theorem card_eq_zero_iff_empty (α : Type _) : card α = 0 ↔ IsEmpty α := by
+  rw [← Cardinal.mk_eq_zero_iff]
+  conv_rhs => rw [← Nat.cast_zero]
+  simp only [← Cardinal.toPartENat_eq_natCast_iff]
+  simp only [PartENat.card, Nat.cast_zero]
+#align part_enat.card_eq_zero_iff_empty PartENat.card_eq_zero_iff_empty
+
+theorem card_le_one_iff_subsingleton (α : Type _) : card α ≤ 1 ↔ Subsingleton α := by
+  rw [← le_one_iff_subsingleton]
+  conv_rhs => rw [← Nat.cast_one]
+  rw [← Cardinal.toPartENat_le_natCast_iff]
+  simp only [PartENat.card, Nat.cast_one]
+#align part_enat.card_le_one_iff_subsingleton PartENat.card_le_one_iff_subsingleton
+
+theorem one_lt_card_iff_nontrivial (α : Type _) : 1 < card α ↔ Nontrivial α := by
+  rw [← Cardinal.one_lt_iff_nontrivial]
+  conv_rhs => rw [← Nat.cast_one]
+  rw [← natCast_lt_toPartENat_iff]
+  simp only [PartENat.card, Nat.cast_one]
+#align part_enat.one_lt_card_iff_nontrivial PartENat.one_lt_card_iff_nontrivial
+
 end PartENat
chore: tidy various files (#3483)
Diff
@@ -19,7 +19,7 @@ import Mathlib.SetTheory.Cardinal.Basic
 * `Nat.card α` is the cardinality of `α` as a natural number.
   If `α` is infinite, `Nat.card α = 0`.
 * `PartENat.card α` is the cardinality of `α` as an extended natural number
-  (Part ℕ` implementation). If `α` is infinite, `PartENat.card α = ⊤`.
+  (using `Part ℕ`). If `α` is infinite, `PartENat.card α = ⊤`.
 -/
 
 
@@ -104,14 +104,14 @@ theorem card_prod (α β : Type _) : Nat.card (α × β) = Nat.card α * Nat.car
 #align nat.card_prod Nat.card_prod
 
 @[simp]
-theorem card_uLift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
+theorem card_ulift (α : Type _) : Nat.card (ULift α) = Nat.card α :=
   card_congr Equiv.ulift
-#align nat.card_ulift Nat.card_uLift
+#align nat.card_ulift Nat.card_ulift
 
 @[simp]
-theorem card_pLift (α : Type _) : Nat.card (PLift α) = Nat.card α :=
+theorem card_plift (α : Type _) : Nat.card (PLift α) = Nat.card α :=
   card_congr Equiv.plift
-#align nat.card_plift Nat.card_pLift
+#align nat.card_plift Nat.card_plift
 
 theorem card_pi {β : α → Type _} [Fintype α] : Nat.card (∀ a, β a) = ∏ a, Nat.card (β a) := by
   simp_rw [Nat.card, mk_pi, prod_eq_of_fintype, toNat_lift, toNat_finset_prod]
@@ -123,11 +123,11 @@ theorem card_fun [Finite α] : Nat.card (α → β) = Nat.card β ^ Nat.card α
 #align nat.card_fun Nat.card_fun
 
 @[simp]
-theorem card_zMod (n : ℕ) : Nat.card (ZMod n) = n := by
+theorem card_zmod (n : ℕ) : Nat.card (ZMod n) = n := by
   cases n
   · exact @Nat.card_eq_zero_of_infinite _ Int.infinite
   · rw [Nat.card_eq_fintype_card, ZMod.card]
-#align nat.card_zmod Nat.card_zMod
+#align nat.card_zmod Nat.card_zmod
 
 end Nat
 
feat: Port SetTheory.Cardinal.Finite (#2182)

Co-authored-by: Johan Commelin <johan@commelin.net>

Dependencies 7 + 305

306 files ported (97.8%)
124736 lines ported (97.6%)
Show graph

The unported dependencies are