Theorem: Finpartition.IsEquipartition.exists_partPreservingEquiv
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, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
tactic: obtain ⟨f, hf⟩ := P.exists_enumeration
state_before: case intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
tactic: obtain ⟨g, hg⟩ := hP.exists_partsEquiv
state_before: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
tactic: let z := fun a ↦ P.parts.card * (f a).2 + g (f a).1
state_before: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
tactic: have gl := fun a ↦ (g (f a).1).2
state_before: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
tactic: let z' : s → Fin s.card := fun a ↦ ⟨z a, less a⟩
state_before: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
bij : Function.Bijective z'
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
tactic: have bij : z'.Bijective := by
    refine (bijective_iff_injective_and_card z').mpr ⟨fun a b e ↦ ?_, by simp⟩
    simp_rw [z', z, Fin.mk.injEq, mul_comm P.parts.card] at e
    haveI : NeZero P.parts.card := ⟨((Nat.zero_le _).trans_lt (gl a)).ne'⟩
    change P.parts.card.divModEquiv.symm (_, _) = P.parts.card.divModEquiv.symm (_, _) at e
    simp only [Equiv.apply_eq_iff_eq, Prod.mk.injEq] at e
    apply_fun f
    exact Sigma.ext e.2 <| (Fin.heq_ext_iff (by rw [e.2])).mpr e.1
state_before: case intro.intro
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
bij : Function.Bijective z'
⊢ ∃ f, ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ ↑(f a) % P.parts.card = ↑(f b) % P.parts.card
state_after: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
bij : Function.Bijective z'
⊢ ∀ (a b : { x // x ∈ s }),
    P.part ↑a = P.part ↑b ↔
      ↑((Equiv.ofBijective z' bij) a) % P.parts.card = ↑((Equiv.ofBijective z' bij) b) % P.parts.card
tactic: use Equiv.ofBijective _ bij
state_before: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
bij : Function.Bijective z'
⊢ ∀ (a b : { x // x ∈ s }),
    P.part ↑a = P.part ↑b ↔
      ↑((Equiv.ofBijective z' bij) a) % P.parts.card = ↑((Equiv.ofBijective z' bij) b) % P.parts.card
state_after: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
bij : Function.Bijective z'
a b : { x // x ∈ s }
⊢ P.part ↑a = P.part ↑b ↔
    ↑((Equiv.ofBijective z' bij) a) % P.parts.card = ↑((Equiv.ofBijective z' bij) b) % P.parts.card
tactic: intro a b
state_before: case h
α : Type u_1
inst✝ : DecidableEq α
s t : Finset α
P : Finpartition s
hP : P.IsEquipartition
f : { x // x ∈ s } ≃ (t : { x // x ∈ P.parts }) × Fin (↑t).card
hf : ∀ (a b : { x // x ∈ s }), P.part ↑a = P.part ↑b ↔ (f a).fst = (f b).fst
g : { x // x ∈ P.parts } ≃ Fin P.parts.card
hg : ∀ (t : { x // x ∈ P.parts }), (↑t).card = s.card / P.parts.card + 1 ↔ ↑(g t) < s.card % P.parts.card
z : { x // x ∈ s } → ℕ := fun a => P.parts.card * ↑(f a).snd + ↑(g (f a).fst)
gl : ∀ (a : { x // x ∈ s }), ↑(g (f a).fst) < P.parts.card
less : ∀ (a : { x // x ∈ s }), z a < s.card
z' : { x // x ∈ s } → Fin s.card := fun a => ⟨z a, ⋯⟩
bij : Function.Bijective z'
a b : { x // x ∈ s }
⊢ P.part ↑a = P.part ↑b ↔
    ↑((Equiv.ofBijective z' bij) a) % P.parts.card = ↑((Equiv.ofBijective z' bij) b) % P.parts.card
state_after: no goals
tactic: simp_rw [Equiv.ofBijective_apply, z, hf a b, Nat.mul_add_mod,
    Nat.mod_eq_of_lt (gl a), Nat.mod_eq_of_lt (gl b), Fin.val_eq_val, g.apply_eq_iff_eq]