File: Mathlib/Combinatorics/SimpleGraph/Regularity/Equitabilise.lean

full_name: Finpartition.equitabilise_aux
code: /-- Given a partition `P` of `s`, as well as a proof that `a * m + b * (m + 1) = s.card`, we can
find a new partition `Q` of `s` where each part has size `m` or `m + 1`, every part of `P` is the
union of parts of `Q` plus at most `m` extra elements, there are `b` parts of size `m + 1` and
(provided `m > 0`, because a partition does not have parts of size `0`) there are `a` parts of size
`m` and hence `a + b` parts in total. -/
theorem equitabilise_aux (hs : a * m + b * (m + 1) = s.card) :
    ∃ Q : Finpartition s,
      (∀ x : Finset α, x ∈ Q.parts → x.card = m ∨ x.card = m + 1) ∧
        (∀ x, x ∈ P.parts → (x \ (Q.parts.filter fun y => y ⊆ x).biUnion id).card ≤ m) ∧
          (Q.parts.filter fun i => card i = m + 1).card = b 
goal: ∃ Q,
  (∀ x ∈ Q.parts, x.card = m ∨ x.card = m + 1) ∧
    (∀ x ∈ P.parts, (x \ (Finset.filter (fun y => y ⊆ x) Q.parts).biUnion id).card ≤ m) ∧
      (Finset.filter (fun i => i.card = m + 1) Q.parts).card = b

full_name: Finpartition.equitabilise
code: /-- Given a partition `P` of `s`, as well as a proof that `a * m + b * (m + 1) = s.card`, build a
new partition `Q` of `s` where each part has size `m` or `m + 1`, every part of `P` is the union of
parts of `Q` plus at most `m` extra elements, there are `b` parts of size `m + 1` and (provided
`m > 0`, because a partition does not have parts of size `0`) there are `a` parts of size `m` and
hence `a + b` parts in total. -/
noncomputable def equitabilise : Finpartition s 
goal: Finpartition s

full_name: Finpartition.card_eq_of_mem_parts_equitabilise
code: theorem card_eq_of_mem_parts_equitabilise :
    t ∈ (P.equitabilise h).parts → t.card = m ∨ t.card = m + 1 
goal: t ∈ (Finpartition.equitabilise h).parts → t.card = m ∨ t.card = m + 1

full_name: Finpartition.equitabilise_isEquipartition
code: theorem equitabilise_isEquipartition : (P.equitabilise h).IsEquipartition 
goal: (Finpartition.equitabilise h).IsEquipartition

full_name: Finpartition.card_filter_equitabilise_big
code: theorem card_filter_equitabilise_big :
    ((P.equitabilise h).parts.filter fun u : Finset α => u.card = m + 1).card = b 
goal: (Finset.filter (fun u => u.card = m + 1) (Finpartition.equitabilise h).parts).card = b

full_name: Finpartition.card_filter_equitabilise_small
code: theorem card_filter_equitabilise_small (hm : m ≠ 0) :
    ((P.equitabilise h).parts.filter fun u : Finset α => u.card = m).card = a 
goal: (Finset.filter (fun u => u.card = m) (Finpartition.equitabilise h).parts).card = a

full_name: Finpartition.card_parts_equitabilise
code: theorem card_parts_equitabilise (hm : m ≠ 0) : (P.equitabilise h).parts.card = a + b 
goal: (Finpartition.equitabilise h).parts.card = a + b

full_name: Finpartition.card_parts_equitabilise_subset_le
code: theorem card_parts_equitabilise_subset_le :
    t ∈ P.parts → (t \ ((P.equitabilise h).parts.filter fun u => u ⊆ t).biUnion id).card ≤ m 
goal: t ∈ P.parts → (t \ (Finset.filter (fun u => u ⊆ t) (Finpartition.equitabilise h).parts).biUnion id).card ≤ m

full_name: Finpartition.exists_equipartition_card_eq
code: /-- We can find equipartitions of arbitrary size. -/
theorem exists_equipartition_card_eq (hn : n ≠ 0) (hs : n ≤ s.card) :
    ∃ P : Finpartition s, P.IsEquipartition ∧ P.parts.card = n 
goal: ∃ P, P.IsEquipartition ∧ P.parts.card = n