Documentation

Batteries.Data.UnionFind.Basic

Union-find node type

  • parent : Nat

    Parent of node

  • rank : Nat

    Rank of node

Instances For

    Parent of a union-find node, defaults to self when the node is a root

    Equations
    Instances For

      Rank of a union-find node, defaults to 0 when the node is a root

      Equations
      Instances For
        theorem Batteries.UnionFind.parentD_eq {arr : Array UFNode} {i : Nat} (h : i < arr.size) :
        parentD arr i = arr[i].parent
        theorem Batteries.UnionFind.rankD_eq {arr : Array UFNode} {i : Nat} (h : i < arr.size) :
        rankD arr i = arr[i].rank
        theorem Batteries.UnionFind.parentD_of_not_lt {i : Nat} {arr : Array UFNode} :
        ¬i < arr.sizeparentD arr i = i
        theorem Batteries.UnionFind.lt_of_parentD {arr : Array UFNode} {i : Nat} :
        parentD arr i ii < arr.size
        theorem Batteries.UnionFind.parentD_set {arr : Array UFNode} {x : Nat} {v : UFNode} {i : Nat} {h : x < arr.size} :
        parentD (arr.set x v h) i = if x = i then v.parent else parentD arr i
        theorem Batteries.UnionFind.rankD_set {arr : Array UFNode} {x : Nat} {v : UFNode} {i : Nat} {h : x < arr.size} :
        rankD (arr.set x v h) i = if x = i then v.rank else rankD arr i

        Union-find data structure #

        The UnionFind structure is an implementation of disjoint-set data structure that uses path compression to make the primary operations run in amortized nearly linear time. The nodes of a UnionFind structure s are natural numbers smaller than s.size. The structure associates with a canonical representative from its equivalence class. The structure can be extended using the push operation and equivalence classes can be updated using the union operation.

        The main operations for UnionFind are:

        • empty/mkEmpty are used to create a new empty structure.
        • size returns the size of the data structure.
        • push adds a new node to a structure, unlinked to any other node.
        • union links two nodes of the data structure, joining their equivalence classes, and performs path compression.
        • find returns the canonical representative of a node and updates the data structure using path compression.
        • root returns the canonical representative of a node without altering the data structure.
        • checkEquiv checks whether two nodes have the same canonical representative and updates the structure using path compression.

        Most use cases should prefer find over root to benefit from the speedup from path-compression.

        The main operations use Fin s.size to represent nodes of the union-find structure. Some alternatives are provided:

        The noncomputable relation UnionFind.Equiv is provided to use the equivalence relation from a UnionFind structure in the context of proofs.

        Instances For
          @[reducible, inline]

          Size of union-find structure.

          Equations
          Instances For

            Create an empty union-find structure with specific capacity

            Equations
            Instances For
              @[reducible, inline]

              Parent of union-find node

              Equations
              Instances For
                theorem Batteries.UnionFind.parent'_lt (self : UnionFind) (i : Nat) (h : i < self.arr.size) :
                self.arr[i].parent < self.size
                theorem Batteries.UnionFind.parent_lt (self : UnionFind) (i : Nat) :
                self.parent i < self.size i < self.size
                @[reducible, inline]
                abbrev Batteries.UnionFind.rank (self : UnionFind) (i : Nat) :

                Rank of union-find node

                Equations
                Instances For
                  theorem Batteries.UnionFind.rank_lt {self : UnionFind} {i : Nat} :
                  self.parent i iself.rank i < self.rank (self.parent i)
                  theorem Batteries.UnionFind.rank'_lt (self : UnionFind) (i : Nat) (h : i < self.arr.size) :
                  self.arr[i].parent iself.rank i < self.rank self.arr[i].parent
                  noncomputable def Batteries.UnionFind.rankMax (self : UnionFind) :

                  Maximum rank of nodes in a union-find structure

                  Equations
                  Instances For
                    theorem Batteries.UnionFind.rank'_lt_rankMax (self : UnionFind) (i : Nat) (h : i < self.arr.size) :
                    self.arr[i].rank < self.rankMax
                    theorem Batteries.UnionFind.lt_rankMax (self : UnionFind) (i : Nat) :
                    self.rank i < self.rankMax
                    theorem Batteries.UnionFind.push_rankD {i : Nat} (arr : Array UFNode) :
                    rankD (arr.push { parent := arr.size, rank := 0 }) i = rankD arr i
                    theorem Batteries.UnionFind.push_parentD {i : Nat} (arr : Array UFNode) :
                    parentD (arr.push { parent := arr.size, rank := 0 }) i = parentD arr i

                    Add a new node to a union-find structure, unlinked with any other nodes

                    Equations
                    Instances For
                      @[irreducible]
                      def Batteries.UnionFind.root (self : UnionFind) (x : Fin self.size) :
                      Fin self.size

                      Root of a union-find node.

                      Equations
                      Instances For
                        def Batteries.UnionFind.rootN {n : Nat} (self : UnionFind) (x : Fin n) (h : n = self.size) :
                        Fin n

                        Root of a union-find node.

                        Equations
                        Instances For

                          Root of a union-find node. Panics if index is out of bounds.

                          Equations
                          Instances For

                            Root of a union-find node. Returns input if index is out of bounds.

                            Equations
                            Instances For
                              @[irreducible]
                              theorem Batteries.UnionFind.parent_root (self : UnionFind) (x : Fin self.size) :
                              self.arr[(self.root x)].parent = (self.root x)
                              theorem Batteries.UnionFind.parent_rootD (self : UnionFind) (x : Nat) :
                              self.parent (self.rootD x) = self.rootD x
                              theorem Batteries.UnionFind.rootD_parent (self : UnionFind) (x : Nat) :
                              self.rootD (self.parent x) = self.rootD x
                              theorem Batteries.UnionFind.rootD_lt {self : UnionFind} {x : Nat} :
                              self.rootD x < self.size x < self.size
                              theorem Batteries.UnionFind.rootD_eq_self {self : UnionFind} {x : Nat} :
                              self.rootD x = x self.parent x = x
                              theorem Batteries.UnionFind.rootD_rootD {self : UnionFind} {x : Nat} :
                              self.rootD (self.rootD x) = self.rootD x
                              @[irreducible]
                              theorem Batteries.UnionFind.rootD_ext {m1 m2 : UnionFind} (H : ∀ (x : Nat), m1.parent x = m2.parent x) {x : Nat} :
                              m1.rootD x = m2.rootD x
                              @[irreducible]
                              theorem Batteries.UnionFind.le_rank_root {self : UnionFind} {x : Nat} :
                              self.rank x self.rank (self.rootD x)
                              theorem Batteries.UnionFind.lt_rank_root {self : UnionFind} {x : Nat} :
                              self.rank x < self.rank (self.rootD x) self.parent x x

                              Auxiliary data structure for find operation

                              • Array of nodes

                              • root : Fin n

                                Index of root node

                              • size_eq : self.s.size = n

                                Size requirement

                              Instances For
                                @[irreducible]

                                Auxiliary function for find operation

                                Equations
                                • One or more equations did not get rendered due to their size.
                                Instances For
                                  @[irreducible]
                                  theorem Batteries.UnionFind.findAux_root {self : UnionFind} {x : Fin self.size} :
                                  (self.findAux x).root = self.root x
                                  theorem Batteries.UnionFind.findAux_s {self : UnionFind} {x : Fin self.size} :
                                  (self.findAux x).s = if self.arr[x].parent = x then self.arr else (self.findAux self.arr[x].parent, ).s.modify x fun (s : UFNode) => { parent := self.rootD x, rank := s.rank }
                                  @[irreducible]
                                  theorem Batteries.UnionFind.rankD_findAux {i : Nat} {self : UnionFind} {x : Fin self.size} :
                                  rankD (self.findAux x).s i = self.rank i
                                  theorem Batteries.UnionFind.parentD_findAux {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[x].parent, ).s i
                                  @[irreducible]
                                  theorem Batteries.UnionFind.parentD_findAux_rootD {self : UnionFind} {x : Fin self.size} :
                                  parentD (self.findAux x).s (self.rootD x) = self.rootD x
                                  @[irreducible]
                                  theorem Batteries.UnionFind.parentD_findAux_lt {i : Nat} {self : UnionFind} {x : Fin self.size} (h : i < self.size) :
                                  parentD (self.findAux x).s i < self.size
                                  @[irreducible]
                                  theorem Batteries.UnionFind.parentD_findAux_or (self : UnionFind) (x : Fin self.size) (i : Nat) :
                                  parentD (self.findAux x).s i = self.rootD i self.rootD i = self.rootD x parentD (self.findAux x).s i = self.parent i
                                  @[irreducible]
                                  theorem Batteries.UnionFind.lt_rankD_findAux {i : Nat} {self : UnionFind} {x : Fin self.size} :
                                  parentD (self.findAux x).s i iself.rank i < self.rank (parentD (self.findAux x).s i)
                                  def Batteries.UnionFind.find (self : UnionFind) (x : Fin self.size) :
                                  (s : UnionFind) × { _root : Fin s.size // s.size = self.size }

                                  Find root of a union-find node, updating the structure using path compression.

                                  Equations
                                  Instances For
                                    def Batteries.UnionFind.findN {n : Nat} (self : UnionFind) (x : Fin n) (h : n = self.size) :

                                    Find root of a union-find node, updating the structure using path compression.

                                    Equations
                                    Instances For

                                      Find root of a union-find node, updating the structure using path compression. Panics if index is out of bounds.

                                      Equations
                                      Instances For

                                        Find root of a union-find node, updating the structure using path compression. Returns inputs unchanged when index is out of bounds.

                                        Equations
                                        Instances For
                                          @[simp]
                                          theorem Batteries.UnionFind.find_size (self : UnionFind) (x : Fin self.size) :
                                          (self.find x).fst.size = self.size
                                          @[simp]
                                          theorem Batteries.UnionFind.find_root_2 (self : UnionFind) (x : Fin self.size) :
                                          (self.find x).snd.val = self.rootD x
                                          @[simp]
                                          theorem Batteries.UnionFind.find_parent_1 (self : UnionFind) (x : Fin self.size) :
                                          (self.find x).fst.parent x = self.rootD x
                                          theorem Batteries.UnionFind.find_parent_or (self : UnionFind) (x : Fin self.size) (i : Nat) :
                                          (self.find x).fst.parent i = self.rootD i self.rootD i = self.rootD x (self.find x).fst.parent i = self.parent i
                                          @[simp, irreducible]
                                          theorem Batteries.UnionFind.find_root_1 (self : UnionFind) (x : Fin self.size) (i : Nat) :
                                          (self.find x).fst.rootD i = self.rootD i

                                          Link two union-find nodes

                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For
                                            theorem Batteries.UnionFind.setParentBump_rankD_lt {arr' arr : Array UFNode} {x y : Fin arr.size} (hroot : arr[x].rank < arr[y].rank arr[y].parent = y) (H : arr[x].rank arr[y].rank) {i : Nat} (rankD_lt : parentD arr i irankD arr i < rankD arr (parentD arr i)) (hP : parentD arr' i = if x = i then y else parentD arr i) (hR : ∀ {i : Nat}, rankD arr' i = if y = i arr[x].rank = arr[y].rank then arr[y].rank + 1 else rankD arr i) :
                                            ¬parentD arr' i = irankD arr' i < rankD arr' (parentD arr' i)
                                            theorem Batteries.UnionFind.setParent_rankD_lt {arr : Array UFNode} {x y : Fin arr.size} (h : arr[x].rank < arr[y].rank) {i : Nat} (rankD_lt : parentD arr i irankD arr i < rankD arr (parentD arr i)) :
                                            let arr' := arr.set x { parent := y, rank := arr[x].rank } ; parentD arr' i irankD arr' i < rankD arr' (parentD arr' i)
                                            @[simp]
                                            theorem Batteries.UnionFind.linkAux_size {self : Array UFNode} {x y : Fin self.size} :
                                            (linkAux self x y).size = self.size
                                            def Batteries.UnionFind.linkN {n : Nat} (self : UnionFind) (x y : Fin n) (yroot : self.parent y = y) (h : n = self.size) :

                                            Link a union-find node to a root node.

                                            Equations
                                            • self.linkN x_2 y_2 yroot_2 = self.link x_2 y_2 yroot_2
                                            Instances For
                                              def Batteries.UnionFind.link! (self : UnionFind) (x y : Nat) (yroot : self.parent y = y) :

                                              Link a union-find node to a root node. Panics if either index is out of bounds.

                                              Equations
                                              Instances For

                                                Link two union-find nodes, uniting their respective classes.

                                                Equations
                                                Instances For
                                                  def Batteries.UnionFind.unionN {n : Nat} (self : UnionFind) (x y : Fin n) (h : n = self.size) :

                                                  Link two union-find nodes, uniting their respective classes.

                                                  Equations
                                                  Instances For

                                                    Link two union-find nodes, uniting their respective classes. Panics if either index is out of bounds.

                                                    Equations
                                                    Instances For

                                                      Check whether two union-find nodes are equivalent, updating structure using path compression.

                                                      Equations
                                                      Instances For
                                                        def Batteries.UnionFind.checkEquivN {n : Nat} (self : UnionFind) (x y : Fin n) (h : n = self.size) :

                                                        Check whether two union-find nodes are equivalent, updating structure using path compression.

                                                        Equations
                                                        Instances For

                                                          Check whether two union-find nodes are equivalent, updating structure using path compression. Panics if either index is out of bounds.

                                                          Equations
                                                          Instances For

                                                            Check whether two union-find nodes are equivalent with path compression, returns x == y if either index is out of bounds

                                                            Equations
                                                            Instances For

                                                              Equivalence relation from a UnionFind structure

                                                              Equations
                                                              Instances For