Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit d8fc588

Browse files
committed
refactor(data/finite/card): split from basic (#14885)
1 parent c2719ad commit d8fc588

File tree

2 files changed

+108
-84
lines changed

2 files changed

+108
-84
lines changed

src/data/finite/basic.lean

Lines changed: 2 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Copyright (c) 2022 Kyle Miller. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Kyle Miller
55
-/
6-
import set_theory.cardinal.finite
6+
import data.fintype.basic
77

88
/-!
99
# Finite types
@@ -28,14 +28,6 @@ vice versa. Every `fintype` instance should be computable since they are meant
2828
for computation. If it's not possible to write a computable `fintype` instance,
2929
one should prefer writing a `finite` instance instead.
3030
31-
The cardinality of a finite type `α` is given by `nat.card α`. This function has
32-
the "junk value" of `0` for infinite types, but to ensure the function has valid
33-
output, one just needs to know that it's possible to produce a `finite` instance
34-
for the type. (Note: we could have defined a `finite.card` that required you to
35-
supply a `finite` instance, but (a) the function would be `noncomputable` anyway
36-
so there is no need to supply the instance and (b) the function would have a more
37-
complicated dependent type that easily leads to "motive not type correct" errors.)
38-
3931
## Main definitions
4032
4133
* `finite α` denotes that `α` is a finite type.
@@ -59,10 +51,6 @@ that cannot be inferred using `finite.of_fintype'`. (However, when using
5951
on `decidable` instances will give `finite` instances.) In the future we might
6052
consider writing automation to create these "lowered" instances.
6153
62-
Theorems about `nat.card` are sometimes incidentally true for both finite and infinite
63-
types. If removing a finiteness constraint results in no loss in legibility, we remove
64-
it. We generally put such theorems into the `set_theory.cardinal.finite` module.
65-
6654
## Tags
6755
6856
finiteness, finite types
@@ -99,21 +87,10 @@ priority than ones coming from `fintype` instances. -/
9987
@[priority 900]
10088
instance finite.of_fintype' (α : Type*) [fintype α] : finite α := finite.of_fintype ‹_›
10189

102-
/-- There is (noncomputably) an equivalence between a finite type `α` and `fin (nat.card α)`. -/
103-
def finite.equiv_fin (α : Type*) [finite α] : α ≃ fin (nat.card α) :=
104-
begin
105-
have := (finite.exists_equiv_fin α).some_spec.some,
106-
rwa nat.card_eq_of_equiv_fin this,
107-
end
108-
109-
/-- Similar to `finite.equiv_fin` but with control over the term used for the cardinality. -/
110-
def finite.equiv_fin_of_card_eq [finite α] {n : ℕ} (h : nat.card α = n) : α ≃ fin n :=
111-
by { subst h, apply finite.equiv_fin }
112-
11390
/-- Noncomputably get a `fintype` instance from a `finite` instance. This is not an
11491
instance because we want `fintype` instances to be useful for computations. -/
11592
def fintype.of_finite (α : Type*) [finite α] : fintype α :=
116-
fintype.of_equiv _ (finite.equiv_fin α).symm
93+
nonempty.some $ let ⟨n, ⟨e⟩⟩ := finite.exists_equiv_fin α in ⟨fintype.of_equiv _ e.symm
11794

11895
lemma finite_iff_nonempty_fintype (α : Type*) :
11996
finite α ↔ nonempty (fintype α) :=
@@ -142,23 +119,6 @@ lemma not_infinite_iff_finite {α : Type*} : ¬ infinite α ↔ finite α :=
142119
lemma not_finite_iff_infinite {α : Type*} : ¬ finite α ↔ infinite α :=
143120
not_infinite_iff_finite.not_right.symm
144121

145-
lemma nat.card_eq (α : Type*) :
146-
nat.card α = if h : finite α then by exactI @fintype.card α (fintype.of_finite α) else 0 :=
147-
begin
148-
casesI finite_or_infinite α,
149-
{ letI := fintype.of_finite α,
150-
simp only [*, nat.card_eq_fintype_card, dif_pos] },
151-
{ simp [*, not_finite_iff_infinite.mpr h] },
152-
end
153-
154-
lemma finite.card_pos_iff [finite α] :
155-
0 < nat.card α ↔ nonempty α :=
156-
begin
157-
haveI := fintype.of_finite α,
158-
simp only [nat.card_eq_fintype_card],
159-
exact fintype.card_pos_iff,
160-
end
161-
162122
lemma of_subsingleton {α : Sort*} [subsingleton α] : finite α := finite.of_equiv _ equiv.plift
163123

164124
@[nolint instance_priority]
@@ -190,24 +150,9 @@ end
190150
lemma of_surjective {α β : Sort*} [finite α] (f : α → β) (H : function.surjective f) : finite β :=
191151
of_injective _ $ function.injective_surj_inv H
192152

193-
lemma card_eq [finite α] [finite β] : nat.card α = nat.card β ↔ nonempty (α ≃ β) :=
194-
by { haveI := fintype.of_finite α, haveI := fintype.of_finite β, simp [fintype.card_eq] }
195-
196153
@[priority 100] -- see Note [lower instance priority]
197154
instance of_is_empty {α : Sort*} [is_empty α] : finite α := finite.of_equiv _ equiv.plift
198155

199-
lemma card_le_one_iff_subsingleton [finite α] : nat.card α ≤ 1 ↔ subsingleton α :=
200-
by { haveI := fintype.of_finite α, simp [fintype.card_le_one_iff_subsingleton] }
201-
202-
lemma one_lt_card_iff_nontrivial [finite α] : 1 < nat.card α ↔ nontrivial α :=
203-
by { haveI := fintype.of_finite α, simp [fintype.one_lt_card_iff_nontrivial] }
204-
205-
lemma one_lt_card [finite α] [h : nontrivial α] : 1 < nat.card α :=
206-
one_lt_card_iff_nontrivial.mpr h
207-
208-
@[simp] lemma card_option [finite α] : nat.card (option α) = nat.card α + 1 :=
209-
by { haveI := fintype.of_finite α, simp }
210-
211156
lemma prod_left (β) [finite (α × β)] [nonempty β] : finite α :=
212157
of_surjective (prod.fst : α × β → α) prod.fst_surjective
213158

@@ -226,39 +171,12 @@ of_injective (sum.inl : α → α ⊕ β) sum.inl_injective
226171
lemma sum_right (α) [finite (α ⊕ β)] : finite β :=
227172
of_injective (sum.inr : β → α ⊕ β) sum.inr_injective
228173

229-
lemma card_sum [finite α] [finite β] : nat.card (α ⊕ β) = nat.card α + nat.card β :=
230-
by { haveI := fintype.of_finite α, haveI := fintype.of_finite β, simp }
231-
232-
lemma card_le_of_injective [finite β] (f : α → β) (hf : function.injective f) :
233-
nat.card α ≤ nat.card β :=
234-
by { haveI := fintype.of_finite β, haveI := fintype.of_injective f hf,
235-
simpa using fintype.card_le_of_injective f hf }
236-
237-
lemma card_le_of_embedding [finite β] (f : α ↪ β) : nat.card α ≤ nat.card β :=
238-
card_le_of_injective _ f.injective
239-
240-
lemma card_le_of_surjective [finite α] (f : α → β) (hf : function.surjective f) :
241-
nat.card β ≤ nat.card α :=
242-
by { haveI := fintype.of_finite α, haveI := fintype.of_surjective f hf,
243-
simpa using fintype.card_le_of_surjective f hf }
244-
245-
lemma card_eq_zero_iff [finite α] : nat.card α = 0 ↔ is_empty α :=
246-
by { haveI := fintype.of_finite α, simp [fintype.card_eq_zero_iff] }
247-
248174
end finite
249175

250176
/-- This instance also provides `[finite s]` for `s : set α`. -/
251177
instance subtype.finite {α : Sort*} [finite α] {p : α → Prop} : finite {x // p x} :=
252178
finite.of_injective coe subtype.coe_injective
253179

254-
theorem finite.card_subtype_le [finite α] (p : α → Prop) :
255-
nat.card {x // p x} ≤ nat.card α :=
256-
by { haveI := fintype.of_finite α, simpa using fintype.card_subtype_le p }
257-
258-
theorem finite.card_subtype_lt [finite α] {p : α → Prop} {x : α} (hx : ¬ p x) :
259-
nat.card {x // p x} < nat.card α :=
260-
by { haveI := fintype.of_finite α, simpa using fintype.card_subtype_lt hx }
261-
262180
instance pi.finite {α : Sort*} {β : α → Sort*} [finite α] [∀ a, finite (β a)] : finite (Π a, β a) :=
263181
begin
264182
haveI := fintype.of_finite (plift α),

src/data/finite/card.lean

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/-
2+
Copyright (c) 2022 Kyle Miller. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Kyle Miller
5+
-/
6+
import data.finite.basic
7+
import set_theory.cardinal.finite
8+
9+
/-!
10+
11+
# Cardinality of finite types
12+
13+
The cardinality of a finite type `α` is given by `nat.card α`. This function has
14+
the "junk value" of `0` for infinite types, but to ensure the function has valid
15+
output, one just needs to know that it's possible to produce a `finite` instance
16+
for the type. (Note: we could have defined a `finite.card` that required you to
17+
supply a `finite` instance, but (a) the function would be `noncomputable` anyway
18+
so there is no need to supply the instance and (b) the function would have a more
19+
complicated dependent type that easily leads to "motive not type correct" errors.)
20+
21+
## Implementation notes
22+
23+
Theorems about `nat.card` are sometimes incidentally true for both finite and infinite
24+
types. If removing a finiteness constraint results in no loss in legibility, we remove
25+
it. We generally put such theorems into the `set_theory.cardinal.finite` module.
26+
27+
-/
28+
29+
noncomputable theory
30+
open_locale classical
31+
32+
variables {α β γ : Type*}
33+
34+
/-- There is (noncomputably) an equivalence between a finite type `α` and `fin (nat.card α)`. -/
35+
def finite.equiv_fin (α : Type*) [finite α] : α ≃ fin (nat.card α) :=
36+
begin
37+
have := (finite.exists_equiv_fin α).some_spec.some,
38+
rwa nat.card_eq_of_equiv_fin this,
39+
end
40+
41+
/-- Similar to `finite.equiv_fin` but with control over the term used for the cardinality. -/
42+
def finite.equiv_fin_of_card_eq [finite α] {n : ℕ} (h : nat.card α = n) : α ≃ fin n :=
43+
by { subst h, apply finite.equiv_fin }
44+
45+
lemma nat.card_eq (α : Type*) :
46+
nat.card α = if h : finite α then by exactI @fintype.card α (fintype.of_finite α) else 0 :=
47+
begin
48+
casesI finite_or_infinite α,
49+
{ letI := fintype.of_finite α,
50+
simp only [*, nat.card_eq_fintype_card, dif_pos] },
51+
{ simp [*, not_finite_iff_infinite.mpr h] },
52+
end
53+
54+
lemma finite.card_pos_iff [finite α] :
55+
0 < nat.card α ↔ nonempty α :=
56+
begin
57+
haveI := fintype.of_finite α,
58+
simp only [nat.card_eq_fintype_card],
59+
exact fintype.card_pos_iff,
60+
end
61+
62+
namespace finite
63+
64+
lemma card_eq [finite α] [finite β] : nat.card α = nat.card β ↔ nonempty (α ≃ β) :=
65+
by { haveI := fintype.of_finite α, haveI := fintype.of_finite β, simp [fintype.card_eq] }
66+
67+
lemma card_le_one_iff_subsingleton [finite α] : nat.card α ≤ 1 ↔ subsingleton α :=
68+
by { haveI := fintype.of_finite α, simp [fintype.card_le_one_iff_subsingleton] }
69+
70+
lemma one_lt_card_iff_nontrivial [finite α] : 1 < nat.card α ↔ nontrivial α :=
71+
by { haveI := fintype.of_finite α, simp [fintype.one_lt_card_iff_nontrivial] }
72+
73+
lemma one_lt_card [finite α] [h : nontrivial α] : 1 < nat.card α :=
74+
one_lt_card_iff_nontrivial.mpr h
75+
76+
@[simp] lemma card_option [finite α] : nat.card (option α) = nat.card α + 1 :=
77+
by { haveI := fintype.of_finite α, simp }
78+
79+
lemma card_le_of_injective [finite β] (f : α → β) (hf : function.injective f) :
80+
nat.card α ≤ nat.card β :=
81+
by { haveI := fintype.of_finite β, haveI := fintype.of_injective f hf,
82+
simpa using fintype.card_le_of_injective f hf }
83+
84+
lemma card_le_of_embedding [finite β] (f : α ↪ β) : nat.card α ≤ nat.card β :=
85+
card_le_of_injective _ f.injective
86+
87+
lemma card_le_of_surjective [finite α] (f : α → β) (hf : function.surjective f) :
88+
nat.card β ≤ nat.card α :=
89+
by { haveI := fintype.of_finite α, haveI := fintype.of_surjective f hf,
90+
simpa using fintype.card_le_of_surjective f hf }
91+
92+
lemma card_eq_zero_iff [finite α] : nat.card α = 0 ↔ is_empty α :=
93+
by { haveI := fintype.of_finite α, simp [fintype.card_eq_zero_iff] }
94+
95+
lemma card_sum [finite α] [finite β] : nat.card (α ⊕ β) = nat.card α + nat.card β :=
96+
by { haveI := fintype.of_finite α, haveI := fintype.of_finite β, simp }
97+
98+
end finite
99+
100+
theorem finite.card_subtype_le [finite α] (p : α → Prop) :
101+
nat.card {x // p x} ≤ nat.card α :=
102+
by { haveI := fintype.of_finite α, simpa using fintype.card_subtype_le p }
103+
104+
theorem finite.card_subtype_lt [finite α] {p : α → Prop} {x : α} (hx : ¬ p x) :
105+
nat.card {x // p x} < nat.card α :=
106+
by { haveI := fintype.of_finite α, simpa using fintype.card_subtype_lt hx }

0 commit comments

Comments
 (0)