Theorem: Batteries.UnionFind.parentD_findAux
File: .lake/packages/batteries/Batteries/Data/UnionFind/Basic.lean

tactic: rw [findAux_s]
state_before: i : Nat
self : UnionFind
x : Fin self.size
⊢ parentD (self.findAux x).s i =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: i : Nat
self : UnionFind
x : Fin self.size
⊢ parentD
      (if (self.arr.get x).parent = ↑x then self.arr
      else (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank })
      i =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: split <;> [split; skip]
state_before: i : Nat
self : UnionFind
x : Fin self.size
⊢ parentD
      (if (self.arr.get x).parent = ↑x then self.arr
      else (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank })
      i =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isTrue.isTrue
i : Nat
self : UnionFind
x : Fin self.size
h✝¹ : (self.arr.get x).parent = ↑x
h✝ : i = ↑x
⊢ parentD self.arr i = self.rootD ↑x

case isTrue.isFalse
i : Nat
self : UnionFind
x : Fin self.size
h✝¹ : (self.arr.get x).parent = ↑x
h✝ : ¬i = ↑x
⊢ parentD self.arr i = parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

case isFalse
i : Nat
self : UnionFind
x : Fin self.size
h✝ : ¬(self.arr.get x).parent = ↑x
⊢ parentD ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank })
      i =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: subst i
state_before: case isTrue.isTrue
i : Nat
self : UnionFind
x : Fin self.size
h✝¹ : (self.arr.get x).parent = ↑x
h✝ : i = ↑x
⊢ parentD self.arr i = self.rootD ↑x
state_after: case isTrue.isTrue
self : UnionFind
x : Fin self.size
h✝ : (self.arr.get x).parent = ↑x
⊢ parentD self.arr ↑x = self.rootD ↑x

tactic: rw [rootD_eq_self.2 _] <;> simp [parentD_eq, *, -Array.get_eq_getElem]
state_before: case isTrue.isTrue
self : UnionFind
x : Fin self.size
h✝ : (self.arr.get x).parent = ↑x
⊢ parentD self.arr ↑x = self.rootD ↑x
state_after: no goals

tactic: rw [findAux_s]
state_before: case isTrue.isFalse
i : Nat
self : UnionFind
x : Fin self.size
h✝¹ : (self.arr.get x).parent = ↑x
h✝ : ¬i = ↑x
⊢ parentD self.arr i = parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isTrue.isFalse
i : Nat
self : UnionFind
x : Fin self.size
h✝¹ : (self.arr.get x).parent = ↑x
h✝ : ¬i = ↑x
⊢ parentD self.arr i =
    parentD
      (if (self.arr.get ⟨(self.arr.get x).parent, ⋯⟩).parent = ↑⟨(self.arr.get x).parent, ⋯⟩ then self.arr
      else
        (self.findAux ⟨(self.arr.get ⟨(self.arr.get x).parent, ⋯⟩).parent, ⋯⟩).s.modify ↑⟨(self.arr.get x).parent, ⋯⟩
          fun s => { parent := self.rootD ↑⟨(self.arr.get x).parent, ⋯⟩, rank := s.rank })
      i

tactic: simp [*, -Array.get_eq_getElem]
state_before: case isTrue.isFalse
i : Nat
self : UnionFind
x : Fin self.size
h✝¹ : (self.arr.get x).parent = ↑x
h✝ : ¬i = ↑x
⊢ parentD self.arr i =
    parentD
      (if (self.arr.get ⟨(self.arr.get x).parent, ⋯⟩).parent = ↑⟨(self.arr.get x).parent, ⋯⟩ then self.arr
      else
        (self.findAux ⟨(self.arr.get ⟨(self.arr.get x).parent, ⋯⟩).parent, ⋯⟩).s.modify ↑⟨(self.arr.get x).parent, ⋯⟩
          fun s => { parent := self.rootD ↑⟨(self.arr.get x).parent, ⋯⟩, rank := s.rank })
      i
state_after: no goals

tactic: rw [parentD]
state_before: i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
⊢ parentD ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank })
      i =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
⊢ (if h :
        i <
          ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
              { parent := self.rootD ↑x, rank := s.rank }).size then
      (((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
              { parent := self.rootD ↑x, rank := s.rank }).get
          ⟨i, h⟩).parent
    else i) =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: split <;> rename_i h'
state_before: i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
⊢ (if h :
        i <
          ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
              { parent := self.rootD ↑x, rank := s.rank }).size then
      (((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
              { parent := self.rootD ↑x, rank := s.rank }).get
          ⟨i, h⟩).parent
    else i) =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isTrue
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ (((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).get
        ⟨i, h'⟩).parent =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

case isFalse
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ i = if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: rw [Array.get_modify (by simpa using h')]
state_before: case isTrue
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ (((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).get
        ⟨i, h'⟩).parent =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isTrue
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ (if ↑x = i then { parent := self.rootD ↑x, rank := ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).rank }
      else (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).parent =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: simp [@eq_comm _ i, -Array.get_eq_getElem]
state_before: case isTrue
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ (if ↑x = i then { parent := self.rootD ↑x, rank := ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).rank }
      else (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).parent =
    if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isTrue
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ (if ↑x = i then { parent := self.rootD ↑x, rank := ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).rank }
      else (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).parent =
    if ↑x = i then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: split <;> simp [← parentD_eq, -Array.get_eq_getElem]
state_before: case isTrue
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ (if ↑x = i then { parent := self.rootD ↑x, rank := ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).rank }
      else (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.get ⟨i, ⋯⟩).parent =
    if ↑x = i then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: no goals

tactic: simpa using h'
state_before: i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  i <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
⊢ i < (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.size
state_after: no goals

tactic: rw [if_neg (mt (by rintro rfl; simp [FindAux.size_eq]) h')]
state_before: case isFalse
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ i = if i = ↑x then self.rootD ↑x else parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isFalse
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ i = parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i

tactic: rw [parentD, dif_neg]
state_before: case isFalse
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ i = parentD (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s i
state_after: case isFalse.hnc
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ ¬i < (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.size

tactic: simpa using h'
state_before: case isFalse.hnc
i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ ¬i < (self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.size
state_after: no goals

tactic: rintro rfl
state_before: i : Nat
self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ i = ↑x →
    i <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
state_after: self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬↑x <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ ↑x <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size

tactic: simp [FindAux.size_eq]
state_before: self : UnionFind
x : Fin self.size
h : ¬(self.arr.get x).parent = ↑x
h' :
  ¬↑x <
      ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s =>
          { parent := self.rootD ↑x, rank := s.rank }).size
⊢ ↑x <
    ((self.findAux ⟨(self.arr.get x).parent, ⋯⟩).s.modify ↑x fun s => { parent := self.rootD ↑x, rank := s.rank }).size
state_after: no goals