Zulip Chat Archive
Stream: new members
Topic: Counting cardinalities in presence of partitions
Antoine Chambert-Loir (Mar 08 2022 at 13:08):
The following MWE is arguably ugly, but I couldn't do better, in the presence of a docs#setoid.is_partition of a set which is known to be finite , to say that the cardinality of the ambient set is the sum of the cardinalities of its parts.
I struggled against coercions between finset (finset α)
and set (set α)
.
Any advice or golfing is welcome !
In particular :
-
Is there a better way to switch between close types, especially in the presence of
finset.sum
. -
On line 29, the
suffices…
is made to have Lean automatically insert the correct type; can one do better?
import data.setoid.partition
/- {α : Type u_1} (c : set (set α)) :
setoid.is_partition c =
(∅ ∉ c ∧ ∀ (a : α), ∃! (b : set α) (H : b ∈ c), a ∈ b)
-/
import algebra.big_operators.order
variables {α : Type*}
open_locale big_operators classical
/-- The cardinal of ambient fintype equal the sum of cardinals of the parts of a partition (finset style)-/
lemma card_of_partition' [fintype α] {c : finset (finset α)} (hc : setoid.is_partition ({ s : set α | ∃ (t : finset α), s.to_finset = t ∧ t ∈ c } : set (set α))) :
∑ (s : finset α) in c, s.card = fintype.card α :=
begin
rw ← mul_one (fintype.card α),
rw ← finset.sum_card,
intro a,
rw finset.card_eq_one,
obtain ⟨s, hs, hs'⟩ := hc.right a,
simp only [exists_unique_iff_exists, exists_prop, and_imp, exists_eq_left', set.mem_set_of_eq] at hs hs',
have hs'2 : ∀ (z : finset α), z ∈ c → a ∈ z → z = s.to_finset,
{ intros z hz ha,
rw ← finset.coe_inj, simp,
refine hs' z _ (finset.mem_coe.mpr ha),
-- To get the correct type automatically and perform the rewrite
suffices : ∀ {u v : finset α}, v ∈ c → u = v → u ∈ c,
{ refine this hz _,
rw [← finset.coe_inj, set.coe_to_finset], },
{ intros u v hu huv, rw huv, exact hu, },
},
use s.to_finset,
ext t,
simp only [finset.mem_filter, finset.mem_singleton],
split,
{ rintro ⟨ht,ha⟩,
exact hs'2 t ht ha, },
{ intro ht,
rw ← ht at hs, apply and.intro hs.left,
rw ht, simp only [set.mem_to_finset], exact hs.right,}
end
/-- The cardinal of ambient fintype equal the sum of cardinals of the parts of a partition (set style)-/
lemma card_of_partition [fintype α] {c : set (set α)} (hc : setoid.is_partition c) :
∑ (s : set α) in c.to_finset, s.to_finset.card = fintype.card α :=
begin
let c' : finset (finset α) := { s : finset (α) | (s : set α) ∈ c }.to_finset,
have hcc' : c = { s : set α | ∃ (t : finset α), s.to_finset = t ∧ t ∈ c' },
{ simp only [set.mem_to_finset, set.mem_set_of_eq, exists_eq_left', set.coe_to_finset, set.set_of_mem_eq] },
rw hcc' at hc,
rw ← card_of_partition' hc,
have hi : ∀ (a : set α) (ha : a ∈ c.to_finset), a.to_finset ∈ c',
{ intros a ha,
simp only [set.mem_to_finset, set.mem_set_of_eq, set.coe_to_finset],
simpa only [set.mem_to_finset] using ha, },
have hj : ∀ (a : finset α) (ha : a ∈ c'), (a : set α) ∈ c.to_finset,
{ intros a ha,
simpa only [set.mem_to_finset] using ha, },
rw finset.sum_bij' _ hi _ _ hj,
{ intros a ha, simp only [set.coe_to_finset], },
{ intros a ha,
rw [← finset.coe_inj, set.coe_to_finset], },
{ intros a ha, refl, },
end
Anatole Dedecker (Mar 08 2022 at 14:18):
I’m not a big user of the finite cardinals API in Lean, but when working on the Burnside formula (docs#mul_action.sum_card_fixed_by_eq_card_orbits_mul_card_group) I found it really convenient to construct an equiv in calc mode and then just deduce the corresponding cardinal result
Anatole Dedecker (Mar 08 2022 at 14:25):
In particular I would definitely try using docs#finset.card_sigma in this case.
Anatole Dedecker (Mar 08 2022 at 14:26):
About the suffices
I’m not sure if I understand your problem correctly, but do you know about docs#tactic.interactive.change ?
Eric Wieser (Mar 08 2022 at 14:38):
If you're working with finset.card
, it should be much easier to use finpartition
:
import algebra.big_operators.basic
import order.partition.finpartition
open_locale big_operators
/-- The cardinal of ambient fintype equal the sum of cardinals of the parts of a partition (set style)-/
example {α : Type*} [decidable_eq α] {x : finset α} (p : finpartition x) :
∑ s in p.parts, s.card = x.card :=
begin
conv_rhs {rw ←p.sup_parts},
rw [finset.sup_eq_bUnion, finset.card_bUnion p.sup_indep.pairwise_disjoint],
refl
end
Antoine Chambert-Loir (Mar 08 2022 at 14:41):
… and using the ongoing PR to convert is_partition
to finpartition
? ;-)
Eric Wieser (Mar 08 2022 at 14:41):
Or maximally golfed:
example {α : Type*} [decidable_eq α] {x : finset α} (p : finpartition x) :
∑ s in p.parts, s.card = x.card :=
(finset.card_bUnion p.sup_indep.pairwise_disjoint).symm.trans $ congr_arg _ $
(finset.sup_eq_bUnion _ _).symm.trans p.sup_parts
Antoine Chambert-Loir (Mar 08 2022 at 15:44):
Shouldn't such a function belong to mathlib?
Johan Commelin (Mar 08 2022 at 16:11):
I think it should
Antoine Chambert-Loir (Mar 08 2022 at 16:29):
Actually, it exists… docs#finpartition.sum_card_parts
Antoine Chambert-Loir (Mar 08 2022 at 16:30):
(I even had forgotten that PR #12459 was the very reason to be able to use it.)
Antoine Chambert-Loir (Mar 08 2022 at 16:32):
That leaves one of my initial questions still open. Maybe, PR #12459 should not only produce a finpartition
of set α
but also produce one of finset α
when possible.
Eric Wieser (Mar 08 2022 at 19:19):
Can you post the statement you're thinking of here?
Antoine Chambert-Loir (Mar 15 2022 at 02:14):
Sure. And finally, I could prove it myself., but I did not succeed using finpartition
.
import data.setoid.partition
import algebra.big_operators.order
open_locale big_operators classical
section partition
variables {α : Type*}
-- TODO : remove the finiteness assumption on α and put it on s
/-- Given a partition of the ambient finite type,
the cardinal of a set is the sum of the cardinalities of its trace on the parts of the partition -/
lemma setoid.is_partition.card_set_eq_sum_parts {α : Type*} [fintype α] {s : set α} {P : set (set α)}
(hP : setoid.is_partition P) :
s.to_finset.card =
finset.sum P.to_finset (λ (t : set α), (s ∩ t).to_finset.card) :=
begin
rw ← finset.card_bUnion,
apply congr_arg,
{ rw ← finset.coe_inj, simp only [set.coe_to_finset, finset.coe_bUnion],
rw [set.bUnion_eq_Union, ← set.inter_Union, ← set.sUnion_eq_Union],
rw setoid.is_partition.sUnion_eq_univ hP,
exact (set.inter_univ s).symm },
{ intros t ht u hu htu,
simp only [set.mem_to_finset] at ht hu,
simp only [set.to_finset_disjoint_iff],
exact set.disjoint_of_subset (set.inter_subset_right s t) (set.inter_subset_right s u)
(setoid.is_partition.pairwise_disjoint hP ht hu htu) }
end
/-- The cardinality of a finite type is
the sum of the cardinalities of the parts of any partition -/
lemma setoid.is_partition.card_eq_sum_parts {α : Type*} [fintype α] {P : set (set α)}
(hP : setoid.is_partition P) :
fintype.card α =
finset.sum P.to_finset (λ (t : set α), t.to_finset.card) :=
begin
change finset.univ.card = _,
have : (finset.univ : finset α) = (set.univ : set α).to_finset :=
by rw [← finset.coe_inj, set.to_finset_univ],
rw this,
have h : ∀ (t : set α) (ht : t ∈ P.to_finset), t.to_finset.card = (set.univ ∩ t).to_finset.card,
{ intros t ht, apply congr_arg,
rw set.to_finset_inj, exact (set.univ_inter t).symm, },
simp_rw finset.sum_congr rfl h,
let z := @setoid.is_partition.card_set_eq_sum_parts _ _ (set.univ) P hP,
simpa only [set.to_finset_univ, set.to_finset_card, fintype.card_of_finset]
using z,
end
end partition
Antoine Chambert-Loir (Mar 15 2022 at 08:37):
(By the way, should I PR these two lemmas to somewhere after the definition of docs#setoid.is_partition ?)
Last updated: Dec 20 2023 at 11:08 UTC