Theorem: Finpartition.IsEquipartition.exists_partsEquiv
File: Mathlib/Order/Partition/Equipartition.lean

Proof steps:
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card + 1) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).equivFin
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: let el := (P.parts.filter fun p ↦ p.card = s.card / P.parts.card + 1).equivFin
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card + 1) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).equivFin
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card + 1) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).equivFin
es : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card) P.parts).equivFin
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: let es := (P.parts.filter fun p ↦ p.card = s.card / P.parts.card).equivFin
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card + 1) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card + 1) P.parts).equivFin
es : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card) P.parts).equivFin
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
es : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card) P.parts).equivFin
el : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: simp_rw [mem_filter, hP.card_large_parts_eq_mod] at el
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
es : { x // x ∈ filter (fun p => p.card = s.card / P.parts.card) P.parts } ≃
  Fin (filter (fun p => p.card = s.card / P.parts.card) P.parts).card :=
  (filter (fun p => p.card = s.card / P.parts.card) P.parts).equivFin
el : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } ≃ Fin (P.parts.card - s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: simp_rw [mem_filter, hP.card_small_parts_eq_mod] at es
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } ≃ Fin (P.parts.card - s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } ≃ Fin (P.parts.card - s.card % P.parts.card)
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: let sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
      { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } := by
    apply (Equiv.refl _).subtypeEquiv
    simp only [Equiv.refl_apply, and_congr_right_iff]
    exact fun _ ha ↦ by rw [hP.card_part_eq_average_iff ha, ne_eq]
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
el : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } ≃ Fin (P.parts.card - s.card % P.parts.card)
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
es : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } ≃ Fin (P.parts.card - s.card % P.parts.card)
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: replace el : { x : P.parts // x.1.card = s.card / P.parts.card + 1 } ≃
      Fin (s.card % P.parts.card) := (Equiv.Set.sep ..).symm.trans el
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
es : { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } ≃ Fin (P.parts.card - s.card % P.parts.card)
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: replace es : { x : P.parts // ¬x.1.card = s.card / P.parts.card + 1 } ≃
      Fin (P.parts.card - s.card % P.parts.card) := (Equiv.Set.sep ..).symm.trans (sneg.trans es)
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
tactic: let f := (Equiv.sumCompl _).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
state_before: α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
⊢ ∃ f, ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(f t) < s.card % P.parts.card
state_after: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
⊢ ∀ (t : { x // x ∈ P.parts }),
    (↑t).card = s.card / P.parts.card + 1 ↔ ↑((f.trans (finCongr ⋯)) t) < s.card % P.parts.card
tactic: use f.trans (finCongr (Nat.add_sub_of_le P.card_mod_card_parts_le))
state_before: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
⊢ ∀ (t : { x // x ∈ P.parts }),
    (↑t).card = s.card / P.parts.card + 1 ↔ ↑((f.trans (finCongr ⋯)) t) < s.card % P.parts.card
state_after: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
p : Finset α
property✝ : p ∈ P.parts
⊢ (↑⟨p, property✝⟩).card = s.card / P.parts.card + 1 ↔ ↑((f.trans (finCongr ⋯)) ⟨p, property✝⟩) < s.card % P.parts.card
tactic: intro ⟨p, _⟩
state_before: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
p : Finset α
property✝ : p ∈ P.parts
⊢ (↑⟨p, property✝⟩).card = s.card / P.parts.card + 1 ↔ ↑((f.trans (finCongr ⋯)) ⟨p, property✝⟩) < s.card % P.parts.card
state_after: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
p : Finset α
property✝ : p ∈ P.parts
⊢ p.card = s.card / P.parts.card + 1 ↔
    ↑(finSumFinEquiv
          (Sum.map (⇑el) (⇑es) ((Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm ⟨p, property✝⟩))) <
      s.card % P.parts.card
tactic: simp_rw [f, Equiv.trans_apply, Equiv.sumCongr_apply, finCongr_apply, Fin.coe_cast]
state_before: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
sneg : { x // x ∈ P.parts ∧ ¬x.card = s.card / P.parts.card + 1 } ≃
  { x // x ∈ P.parts ∧ x.card = s.card / P.parts.card } :=
  (Equiv.refl (Finset α)).subtypeEquiv ⋯
el : { x // (↑x).card = s.card / P.parts.card + 1 } ≃ Fin (s.card % P.parts.card)
es : { x // ¬(↑x).card = s.card / P.parts.card + 1 } ≃ Fin (P.parts.card - s.card % P.parts.card)
f : { x // x ∈ P.parts } ≃ Fin (s.card % P.parts.card + (P.parts.card - s.card % P.parts.card)) :=
  (Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm.trans ((el.sumCongr es).trans finSumFinEquiv)
p : Finset α
property✝ : p ∈ P.parts
⊢ p.card = s.card / P.parts.card + 1 ↔
    ↑(finSumFinEquiv
          (Sum.map (⇑el) (⇑es) ((Equiv.sumCompl fun a => (↑a).card = s.card / P.parts.card + 1).symm ⟨p, property✝⟩))) <
      s.card % P.parts.card
state_after: no goals
tactic: by_cases hc : p.card = s.card / P.parts.card + 1 <;> simp [hc]