Theorem: Batteries.UnionFind.root_link
File: .lake/packages/batteries/Batteries/Data/UnionFind/Lemmas.lean

tactic: refine ⟨x, .inl rfl, fun i => ?_⟩
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ↑x = ↑y
⊢ ∃ r,
    (r = x ∨ r = y) ∧
      ∀ (i : Nat), (self.link x y yroot).rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
state_after: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ↑x = ↑y
i : Nat
⊢ (self.link x y yroot).rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: rw [rootD_ext (m2 := self) (fun _ => by rw [parent_link, if_pos h])]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ↑x = ↑y
i : Nat
⊢ (self.link x y yroot).rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ↑x = ↑y
i : Nat
⊢ self.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: split <;> [obtain _ | _ := ‹_› <;> simp [*]; rfl]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ↑x = ↑y
i : Nat
⊢ self.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: no goals

tactic: rw [parent_link, if_pos h]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ↑x = ↑y
i x✝ : Nat
⊢ (self.link x y yroot).parent x✝ = self.parent x✝
state_after: no goals

tactic: if hr : self.rank y < self.rank x then
  exact this xroot yroot fun i => by simp [parent_link, h, hr]
else
  simpa (config := {singlePass := true}) [or_comm] using
    this yroot xroot fun i => by simp [parent_link, h, hr]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ¬↑x = ↑y
this :
  ∀ {x y : Fin self.size},
    self.parent ↑x = ↑x →
      self.parent ↑y = ↑y →
        ∀ {m : UnionFind},
          (∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i) →
            ∃ r,
              (r = x ∨ r = y) ∧
                ∀ (i : Nat), m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
⊢ ∃ r,
    (r = x ∨ r = y) ∧
      ∀ (i : Nat), (self.link x y yroot).rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
state_after: no goals

tactic: exact ⟨x, .inl rfl, go⟩
state_before: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
⊢ ∃ r, (r = x ∨ r = y) ∧ ∀ (i : Nat), m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
state_after: no goals

tactic: rw [rootD_eq_self.2 h]
state_before: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : m.parent i = i
⊢ m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : m.parent i = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: rw [hm i] at h
state_before: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : m.parent i = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : (if ↑y = i then ↑x else self.parent i) = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: split at h
state_before: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : (if ↑y = i then ↑x else self.parent i) = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: case isTrue
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ↑y = i
h : ↑x = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

case isFalse
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ¬↑y = i
h : self.parent i = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: rw [if_pos, h]
state_before: case isTrue
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ↑y = i
h : ↑x = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: case isTrue.hc
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ↑y = i
h : ↑x = i
⊢ self.rootD i = ↑x ∨ self.rootD i = ↑y

tactic: simp [← h, rootD_eq_self, xroot]
state_before: case isTrue.hc
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ↑y = i
h : ↑x = i
⊢ self.rootD i = ↑x ∨ self.rootD i = ↑y
state_after: no goals

tactic: rw [rootD_eq_self.2 ‹_›]
state_before: case isFalse
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ¬↑y = i
h : self.parent i = i
⊢ i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: case isFalse
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ¬↑y = i
h : self.parent i = i
⊢ i = if i = ↑x ∨ i = ↑y then ↑x else i

tactic: split <;> [skip; rfl]
state_before: case isFalse
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ¬↑y = i
h : self.parent i = i
⊢ i = if i = ↑x ∨ i = ↑y then ↑x else i
state_after: case isFalse.isTrue
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝² : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝¹ : ¬↑y = i
h : self.parent i = i
h✝ : i = ↑x ∨ i = ↑y
⊢ i = ↑x

tactic: next h' => exact h'.resolve_right (Ne.symm ‹_›)
state_before: case isFalse.isTrue
self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝² : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝¹ : ¬↑y = i
h : self.parent i = i
h✝ : i = ↑x ∨ i = ↑y
⊢ i = ↑x
state_after: no goals

tactic: exact h'.resolve_right (Ne.symm ‹_›)
state_before: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝¹ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h✝ : ¬↑y = i
h : self.parent i = i
h' : i = ↑x ∨ i = ↑y
⊢ i = ↑x
state_after: no goals

tactic: have _ := Nat.sub_lt_sub_left (m.lt_rankMax i) (m.rank_lt h)
state_before: self : UnionFind
x✝ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝ = ↑x✝
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
⊢ m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
x✝ : m.rankMax - m.rank (m.parent i) < m.rankMax - m.rank i
⊢ m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: rw [← rootD_parent, go (m.parent i)]
state_before: self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
x✝ : m.rankMax - m.rank (m.parent i) < m.rankMax - m.rank i
⊢ m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
x✝ : m.rankMax - m.rank (m.parent i) < m.rankMax - m.rank i
⊢ (if self.rootD (m.parent i) = ↑x ∨ self.rootD (m.parent i) = ↑y then ↑x else self.rootD (m.parent i)) =
    if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: rw [hm i]
state_before: self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
x✝ : m.rankMax - m.rank (m.parent i) < m.rankMax - m.rank i
⊢ (if self.rootD (m.parent i) = ↑x ∨ self.rootD (m.parent i) = ↑y then ↑x else self.rootD (m.parent i)) =
    if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
x✝ : m.rankMax - m.rank (m.parent i) < m.rankMax - m.rank i
⊢ (if
        self.rootD (if ↑y = i then ↑x else self.parent i) = ↑x ∨
          self.rootD (if ↑y = i then ↑x else self.parent i) = ↑y then
      ↑x
    else self.rootD (if ↑y = i then ↑x else self.parent i)) =
    if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i

tactic: split <;> [subst i; rw [rootD_parent]]
state_before: self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
i : Nat
h : ¬m.parent i = i
x✝ : m.rankMax - m.rank (m.parent i) < m.rankMax - m.rank i
⊢ (if
        self.rootD (if ↑y = i then ↑x else self.parent i) = ↑x ∨
          self.rootD (if ↑y = i then ↑x else self.parent i) = ↑y then
      ↑x
    else self.rootD (if ↑y = i then ↑x else self.parent i)) =
    if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑x else self.rootD i
state_after: case isTrue
self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
h : ¬m.parent ↑y = ↑y
x✝ : m.rankMax - m.rank (m.parent ↑y) < m.rankMax - m.rank ↑y
⊢ (if self.rootD ↑x = ↑x ∨ self.rootD ↑x = ↑y then ↑x else self.rootD ↑x) =
    if self.rootD ↑y = ↑x ∨ self.rootD ↑y = ↑y then ↑x else self.rootD ↑y

tactic: simp [rootD_eq_self.2 xroot, rootD_eq_self.2 yroot]
state_before: case isTrue
self : UnionFind
x✝¹ y✝ : Fin self.size
xroot✝ : self.parent ↑x✝¹ = ↑x✝¹
yroot✝ : self.parent ↑y✝ = ↑y✝
h✝ : ¬↑x✝¹ = ↑y✝
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
m : UnionFind
hm : ∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i
h : ¬m.parent ↑y = ↑y
x✝ : m.rankMax - m.rank (m.parent ↑y) < m.rankMax - m.rank ↑y
⊢ (if self.rootD ↑x = ↑x ∨ self.rootD ↑x = ↑y then ↑x else self.rootD ↑x) =
    if self.rootD ↑y = ↑x ∨ self.rootD ↑y = ↑y then ↑x else self.rootD ↑y
state_after: no goals

tactic: exact this xroot yroot fun i => by simp [parent_link, h, hr]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ¬↑x = ↑y
this :
  ∀ {x y : Fin self.size},
    self.parent ↑x = ↑x →
      self.parent ↑y = ↑y →
        ∀ {m : UnionFind},
          (∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i) →
            ∃ r,
              (r = x ∨ r = y) ∧
                ∀ (i : Nat), m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
hr : self.rank ↑y < self.rank ↑x
⊢ ∃ r,
    (r = x ∨ r = y) ∧
      ∀ (i : Nat), (self.link x y yroot).rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
state_after: no goals

tactic: simp [parent_link, h, hr]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ¬↑x = ↑y
this :
  ∀ {x y : Fin self.size},
    self.parent ↑x = ↑x →
      self.parent ↑y = ↑y →
        ∀ {m : UnionFind},
          (∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i) →
            ∃ r,
              (r = x ∨ r = y) ∧
                ∀ (i : Nat), m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
hr : self.rank ↑y < self.rank ↑x
i : Nat
⊢ (self.link x y yroot).parent i = if ↑y = i then ↑x else self.parent i
state_after: no goals

tactic: simpa (config := {singlePass := true}) [or_comm] using
  this yroot xroot fun i => by simp [parent_link, h, hr]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ¬↑x = ↑y
this :
  ∀ {x y : Fin self.size},
    self.parent ↑x = ↑x →
      self.parent ↑y = ↑y →
        ∀ {m : UnionFind},
          (∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i) →
            ∃ r,
              (r = x ∨ r = y) ∧
                ∀ (i : Nat), m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
hr : ¬self.rank ↑y < self.rank ↑x
⊢ ∃ r,
    (r = x ∨ r = y) ∧
      ∀ (i : Nat), (self.link x y yroot).rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
state_after: no goals

tactic: simp [parent_link, h, hr]
state_before: self : UnionFind
x y : Fin self.size
xroot : self.parent ↑x = ↑x
yroot : self.parent ↑y = ↑y
h : ¬↑x = ↑y
this :
  ∀ {x y : Fin self.size},
    self.parent ↑x = ↑x →
      self.parent ↑y = ↑y →
        ∀ {m : UnionFind},
          (∀ (i : Nat), m.parent i = if ↑y = i then ↑x else self.parent i) →
            ∃ r,
              (r = x ∨ r = y) ∧
                ∀ (i : Nat), m.rootD i = if self.rootD i = ↑x ∨ self.rootD i = ↑y then ↑r else self.rootD i
hr : ¬self.rank ↑y < self.rank ↑x
i : Nat
⊢ (self.link x y yroot).parent i = if ↑x = i then ↑y else self.parent i
state_after: no goals