def findAux (self : UnionFind α) (x : Fin self.size) :
    (s : Array (UFNode α)) ×' (root : Fin s.size) ×'
    ∃ n, ∃ (m : UFModel n) (m' : UFModel n),
      m.Models self.arr ∧ m'.Models s ∧ m'.rank = m.rank ∧
      (∃ hr, (m'.parent ⟨root, hr⟩).1 = root) ∧
      m.rank x ≤ m.rank root := by
  let y := self.arr[x].parent
  refine if h : y = x then ⟨self.arr, x, ?a'⟩ else
    have := Nat.sub_lt_sub_left (self.lt_rankMax x) (self.rank_lt _ h)
    let ⟨arr₁, root, H⟩ := self.findAux ⟨y, self.parent_lt _ x.2⟩
    have hx := ?hx
    let arr₂ := arr₁.set ⟨x, hx⟩ {arr₁.get ⟨x, hx⟩ with parent := root}
    ⟨arr₂, ⟨root, by simp [root.2]⟩, ?b'⟩
  -- start proof
  case a' => -- FIXME: hygiene bug causes `case a` to fail
    let ⟨m, hm⟩ := self.model'
    exact ⟨_, m, m, hm, hm, rfl, ⟨x.2, by rwa [← hm.parent_eq]⟩, le_refl _⟩
  all_goals let ⟨n, m, m', hm, hm', e, ⟨_, hr⟩, le⟩ := H
  case hx => exact hm'.size_eq ▸ hm.size_eq.symm ▸ x.2
  

Proof state:
case b'
α : Type ?u.57384
self : UnionFind α
x : Fin (size self)
y : ℕ := self.arr[x].parent
h : ¬y = ↑x
this : rankMax self - rank self self.arr[↑x].parent < rankMax self - rank self ↑x
arr₁ : Array (UFNode α)
root : Fin (Array.size arr₁)
H :
  ∃ n m m',
    UFModel.Models self.arr m ∧
      UFModel.Models arr₁ m' ∧
        m'.rank = m.rank ∧
          (∃ hr, ↑(UFModel.parent m' { val := ↑root, isLt := hr }) = ↑root) ∧
            UFModel.rank m ↑{ val := y, isLt := (_ : self.arr[↑x].parent < size self) } ≤ UFModel.rank m ↑root
hx : ↑x < Array.size arr₁
arr₂ : Array (UFNode α) :=
  Array.set arr₁ { val := ↑x, isLt := hx }
    (let src := Array.get arr₁ { val := ↑x, isLt := hx };
    { parent := ↑root, value := src.value, rank := src.rank })
n : ℕ
m m' : UFModel n
hm : UFModel.Models self.arr m
hm' : UFModel.Models arr₁ m'
e : m'.rank = m.rank
w✝ : ↑root < n
hr : ↑(UFModel.parent m' { val := ↑root, isLt := w✝ }) = ↑root
le : UFModel.rank m ↑{ val := y, isLt := (_ : self.arr[↑x].parent < size self) } ≤ UFModel.rank m ↑root
⊢ ∃ n m m',
    UFModel.Models self.arr m ∧
      UFModel.Models arr₂ m' ∧
        m'.rank = m.rank ∧
          (∃ hr,
              ↑(UFModel.parent m'
                    {
                      val :=
                        ↑{ val := ↑root,
                            isLt :=
                              (_ :
                                ↑root <
                                  Array.size
                                    (Array.set arr₁ { val := ↑x, isLt := hx }
                                      { parent := ↑root, value := arr₁[↑x].value, rank := arr₁[↑x].rank })) },
                      isLt := hr }) =
                ↑{ val := ↑root,
                    isLt :=
                      (_ :
                        ↑root <
                          Array.size
                            (Array.set arr₁ { val := ↑x, isLt := hx }
                              { parent := ↑root, value := arr₁[↑x].value, rank := arr₁[↑x].rank })) }) ∧
            UFModel.rank m ↑x ≤
              UFModel.rank m
                ↑{ val := ↑root,
                    isLt :=
                      (_ :
                        ↑root <
                          Array.size
                            (Array.set arr₁ { val := ↑x, isLt := hx }
                              { parent := ↑root, value := arr₁[↑x].value, rank := arr₁[↑x].rank })) }

Next tactic:
case b' =>
    let x' : Fin n := ⟨x, hm.size_eq ▸ x.2⟩
    let root : Fin n := ⟨root, hm'.size_eq.symm ▸ root.2⟩
    have hy : (UFModel.parent m x').1 = y := by rw [← hm.parent_eq x x.2 x'.2]; rfl
    have := m.rank_lt x'; rw [hy] at this
    have := lt_of_lt_of_le (this h) le
    refine ⟨n, m, _, hm,
      hm'.setParent x' root (by rw [e]; exact this) hx _ rfl rfl, e,
      ⟨root.2, ?_⟩, le_of_lt this⟩
    have : x.1 ≠ root := mt (congrArg _) (ne_of_lt this); dsimp only at this
    simp [UFModel.setParent, this, hr]