set_theory.cardinal.finite
⟷
Mathlib.SetTheory.Cardinal.Finite
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.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
@@ -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)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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"
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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 /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -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"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/8b981918a93bc45a8600de608cde7944a80d92b9
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -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]
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -30,7 +30,7 @@ open Cardinal
noncomputable section
-open BigOperators
+open scoped BigOperators
variable {α β : Type _}
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/17ad94b4953419f3e3ce3e77da3239c62d1d09f0
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
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>
@@ -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
@@ -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
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.
@@ -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]
toNat
and toPartENat
(#10472)
Redefine these operations in terms of toENat
.
@@ -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]
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.
@@ -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"
$
with <|
(#9319)
See Zulip thread for the discussion.
@@ -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
@@ -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.
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.
@@ -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]
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.
In particular this includes adjustments for the Lean PRs
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).
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})
.
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:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[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>
@@ -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
@@ -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 :=
Nat.card
is zero (#8202)
and lemmas about injectivity/surjectivity of PLift.map
/ULift.map
.
@@ -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
@@ -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
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:
variables
are in scope, but pasting the lemma in the wrong sectionHaving set_option autoImplicit false
as the default prevents these types of mistake being made in the 90% of files where autoImplicit
s 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.
@@ -19,6 +19,8 @@ import Mathlib.SetTheory.Cardinal.Basic
(using `Part ℕ`). If `α` is infinite, `PartENat.card α = ⊤`.
-/
+set_option autoImplicit true
+
open Cardinal
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -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]
@@ -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
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>
@@ -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
@@ -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]
@@ -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
@@ -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.
-/
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>
@@ -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
@@ -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
The unported dependencies are