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
  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); 

Proof state:
α : 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✝
x' : Fin n := { val := ↑x, isLt := (_ : ↑x < n) }
root : Fin n := { val := ↑root✝, isLt := (_ : ↑root✝ < n) }
hy : ↑(UFModel.parent m x') = y
this✝¹ : y ≠ ↑x' → UFModel.rank m ↑x' < UFModel.rank m y
this✝ : UFModel.rank m ↑x' < UFModel.rank m ↑root✝
this : ↑x ≠ ↑root
⊢ ↑(UFModel.parent (UFModel.setParent m' x' root (_ : UFModel.rank m' ↑x' < UFModel.rank m' ↑root))
        {
          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 := (_ : ↑root < n) }) =
    ↑{ 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:
dsimp only at this