Finite partitions #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
In this file, we define finite partitions. A finpartition of a : α is a finite set of pairwise
disjoint parts parts : finset α which does not contain ⊥ and whose supremum is a.
Finpartitions of a finset are at the heart of Szemerédi's regularity lemma. They are also studied purely order theoretically in Sperner theory.
Constructions #
We provide many ways to build finpartitions:
finpartition.of_erase: Builds a finpartition by erasing⊥for you.finpartition.of_subset: Builds a finpartition from a subset of the parts of a previous finpartition.finpartition.empty: The empty finpartition of⊥.finpartition.indiscrete: The indiscrete, aka trivial, aka pure, finpartition made of a single part.finpartition.discrete: The discrete finpartition ofs : finset αmade of singletons.finpartition.bind: Puts together the finpartitions of the parts of a finpartition into a new finpartition.finpartition.atomise: Makes a finpartition ofs : finset αby breakingsalong all finsets inF : finset (finset α). Two elements ofsbelong to the same part iff they belong to the same elements ofF.
finpartition.indiscrete and finpartition.bind together form the monadic structure of
finpartition.
Implementation notes #
Forbidding ⊥ as a part follows mathematical tradition and is a pragmatic choice concerning
operations on finpartition. Not caring about ⊥ being a part or not breaks extensionality (it's
not because the parts of P and the parts of Q have the same elements that P = Q). Enforcing
⊥ to be a part makes finpartition.bind uglier and doesn't rid us of the need of
finpartition.of_erase.
TODO #
Link finpartition and setoid.is_partition.
The order is the wrong way around to make finpartition a a graded order. Is it bad to depart from
the literature and turn the order around?
A finpartition constructor which does not insist on ⊥ not being a part.
Equations
- finpartition.of_erase parts sup_indep sup_parts = {parts := parts.erase ⊥, sup_indep := _, sup_parts := _, not_bot_mem := _}
A finpartition constructor from a bigger existing finpartition.
Changes the type of a finpartition to an equal one.
The empty finpartition.
Equations
- finpartition.empty α = {parts := ∅, sup_indep := _, sup_parts := _, not_bot_mem := _}
Equations
- finpartition.inhabited α = {default := finpartition.empty α _inst_2}
The finpartition in one part, aka indiscrete finpartition.
Equations
- finpartition.indiscrete ha = {parts := {a}, sup_indep := _, sup_parts := _, not_bot_mem := _}
Equations
- finpartition.unique = {to_inhabited := {default := inhabited.default (finpartition.inhabited α)}, uniq := _}
There's a unique partition of an atom.
Equations
- ha.unique_finpartition = {to_inhabited := {default := finpartition.indiscrete _}, uniq := _}
Refinement order #
We say that P ≤ Q if P refines Q: each part of P is less than some part of Q.
Equations
- finpartition.partial_order = {le := has_le.le finpartition.has_le, lt := preorder.lt._default has_le.le, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _}
Equations
- finpartition.has_inf = {inf := λ (P Q : finpartition a), finpartition.of_erase (finset.image (λ (bc : α × α), bc.fst ⊓ bc.snd) (P.parts ×ˢ Q.parts)) _ _}
Equations
- finpartition.semilattice_inf = {inf := has_inf.inf finpartition.has_inf, le := partial_order.le finpartition.partial_order, lt := partial_order.lt finpartition.partial_order, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, inf_le_left := _, inf_le_right := _, le_inf := _}
Given a finpartition P of a and finpartitions of each part of P, this yields the
finpartition of a obtained by juxtaposing all the subpartitions.
Adds b to a finpartition of a to make a finpartition of a ⊔ b.
Equations
- P.extend hb hab hc = {parts := has_insert.insert b P.parts, sup_indep := _, sup_parts := _, not_bot_mem := _}
Restricts a finpartition to avoid a given element.
Equations
- P.avoid b = finpartition.of_erase (finset.image (λ (_x : α), _x \ b) P.parts) _ _
Finite partitions of finsets #
⊥ is the partition in singletons, aka discrete partition.
Equations
- finpartition.has_bot s = {bot := {parts := finset.map {to_fun := has_singleton.singleton finset.has_singleton, inj' := _} s, sup_indep := _, sup_parts := _, not_bot_mem := _}}
Cuts s along the finsets in F: Two elements of s will be in the same part if they are
in the same finsets of F.
Equations
- finpartition.atomise s F = finpartition.of_erase (finset.image (λ (Q : finset (finset α)), finset.filter (λ (i : α), ∀ (t : finset α), t ∈ F → (t ∈ Q ↔ i ∈ t)) s) F.powerset) _ _