Documentation

ToMathlib.Data.IndexedBinaryTree.Basic

Inductive Indexed Binary Trees #

A Note about Process/API when working with this #

I am trying to follow a process of making simp theorems and procedures that decompose the trees as much as possible.

  1. Use casework to take a tree of a known structure and specify the parts of that structure
  2. Push maps or other functions on this down to the bottom of the (tree / syntax tree)
  3. I then have e.g. FullData.internal value1 left1 right1 = FullData.internal value2 left2 right2
  4. and then I can congruence the values and subtrees

Notes & TODOs #

Inductive data type for a binary tree skeleton. A skeleton is a binary tree without values, used to represent the structure of the tree.

Instances For

    Type of indices of leaves of a skeleton

    Instances For

      Type of indices of internal nodes of a skeleton

      Instances For

        Type of indices of any node of a skeleton

        Instances For

          This section contains predicates about indices determined by their neighborhood in the tree.

          Check whether a leaf index is the root of its tree.

          Instances For

            Check whether an internal-node index is the root of its tree.

            Instances For

              Check whether a node index is the root of its tree.

              Instances For

                Check whether a node index points to a leaf of the tree.

                Instances For
                  inductive BinaryTree.LeafData (α : Type u_1) :
                  SkeletonType u_1

                  A binary tree with values stored at leaves.

                  Instances For
                    def BinaryTree.instReprLeafData.repr {α✝ : Type u_1} {a✝ : Skeleton} [Repr α✝] :
                    LeafData α✝ a✝Std.Format
                    Instances For
                      @[implicit_reducible]
                      instance BinaryTree.instReprLeafData {α✝ : Type u_1} {a✝ : Skeleton} [Repr α✝] :
                      Repr (LeafData α✝ a✝)
                      inductive BinaryTree.InternalData (α : Type u_1) :
                      SkeletonType u_1

                      A binary tree with values stored in internal nodes.

                      Instances For
                        def BinaryTree.instReprInternalData.repr {α✝ : Type u_1} {a✝ : Skeleton} [Repr α✝] :
                        InternalData α✝ a✝Std.Format
                        Instances For
                          @[implicit_reducible]
                          instance BinaryTree.instReprInternalData {α✝ : Type u_1} {a✝ : Skeleton} [Repr α✝] :
                          Repr (InternalData α✝ a✝)
                          inductive BinaryTree.FullData (α : Type u_1) :
                          SkeletonType u_1

                          A binary tree with values stored at both leaves and internal nodes.

                          Instances For
                            @[implicit_reducible]
                            instance BinaryTree.instReprFullData {α✝ : Type u_1} {a✝ : Skeleton} [Repr α✝] :
                            Repr (FullData α✝ a✝)
                            def BinaryTree.instReprFullData.repr {α✝ : Type u_1} {a✝ : Skeleton} [Repr α✝] :
                            FullData α✝ a✝Std.Format
                            Instances For
                              def BinaryTree.LeafData.leftSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : LeafData α (s_left.internal s_right)) :
                              LeafData α s_left

                              Get the left subtree of a LeafData.

                              Instances For
                                def BinaryTree.LeafData.rightSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : LeafData α (s_left.internal s_right)) :
                                LeafData α s_right

                                Get the right subtree of a LeafData.

                                Instances For
                                  def BinaryTree.InternalData.leftSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : InternalData α (s_left.internal s_right)) :
                                  InternalData α s_left

                                  Get the left subtree of a InternalData.

                                  Instances For
                                    def BinaryTree.InternalData.rightSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : InternalData α (s_left.internal s_right)) :
                                    InternalData α s_right

                                    Get the right subtree of a InternalData.

                                    Instances For
                                      def BinaryTree.FullData.leftSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : FullData α (s_left.internal s_right)) :
                                      FullData α s_left

                                      Get the left subtree of a FullData.

                                      Instances For
                                        def BinaryTree.FullData.rightSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : FullData α (s_left.internal s_right)) :
                                        FullData α s_right

                                        Get the right subtree of a FullData.

                                        Instances For
                                          @[simp]
                                          theorem BinaryTree.LeafData.leftSubtree_internal {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) :
                                          (left.internal right).leftSubtree = left
                                          @[simp]
                                          theorem BinaryTree.LeafData.rightSubtree_internal {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) :
                                          (left.internal right).rightSubtree = right
                                          @[simp]
                                          theorem BinaryTree.InternalData.leftSubtree_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : InternalData α s_left) (right : InternalData α s_right) :
                                          (internal value left right).leftSubtree = left
                                          @[simp]
                                          theorem BinaryTree.InternalData.rightSubtree_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : InternalData α s_left) (right : InternalData α s_right) :
                                          (internal value left right).rightSubtree = right
                                          @[simp]
                                          theorem BinaryTree.FullData.leftSubtree_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : FullData α s_left) (right : FullData α s_right) :
                                          (internal value left right).leftSubtree = left
                                          @[simp]
                                          theorem BinaryTree.FullData.rightSubtree_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : FullData α s_left) (right : FullData α s_right) :
                                          (internal value left right).rightSubtree = right
                                          def BinaryTree.LeafData.get {s : Skeleton} {α : Type u_1} (tree : LeafData α s) (idx : SkeletonLeafIndex s) :
                                          α

                                          Get a value of a LeafData at an index.

                                          Instances For
                                            def BinaryTree.InternalData.get {s : Skeleton} {α : Type u_1} (tree : InternalData α s) (idx : SkeletonInternalIndex s) :
                                            α

                                            Get a value of a InternalData at an index.

                                            Instances For
                                              def BinaryTree.FullData.get {s : Skeleton} {α : Type u_1} (tree : FullData α s) (idx : SkeletonNodeIndex s) :
                                              α

                                              Get a value of a FullData at an index.

                                              Instances For
                                                @[simp]
                                                @[simp]
                                                theorem BinaryTree.LeafData.get_ofLeft {s_left s_right : Skeleton} {α : Type u_1} (tree : LeafData α (s_left.internal s_right)) (idxLeft : SkeletonLeafIndex s_left) :
                                                tree.get idxLeft.ofLeft = tree.leftSubtree.get idxLeft
                                                @[simp]
                                                theorem BinaryTree.LeafData.get_ofRight {s_left s_right : Skeleton} {α : Type u_1} (tree : LeafData α (s_left.internal s_right)) (idxRight : SkeletonLeafIndex s_right) :
                                                tree.get idxRight.ofRight = tree.rightSubtree.get idxRight
                                                @[simp]
                                                theorem BinaryTree.LeafData.get_internal_ofLeft {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) (idxLeft : SkeletonLeafIndex s_left) :
                                                (left.internal right).get idxLeft.ofLeft = left.get idxLeft
                                                @[simp]
                                                theorem BinaryTree.LeafData.get_internal_ofRight {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) (idxRight : SkeletonLeafIndex s_right) :
                                                (left.internal right).get idxRight.ofRight = right.get idxRight
                                                @[simp]
                                                @[simp]
                                                theorem BinaryTree.InternalData.get_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : InternalData α s_left) (right : InternalData α s_right) :
                                                @[simp]
                                                theorem BinaryTree.InternalData.get_ofLeft {s_left s_right : Skeleton} {α : Type u_1} (tree : InternalData α (s_left.internal s_right)) (idxLeft : SkeletonInternalIndex s_left) :
                                                tree.get idxLeft.ofLeft = tree.leftSubtree.get idxLeft
                                                @[simp]
                                                theorem BinaryTree.InternalData.get_ofRight {s_left s_right : Skeleton} {α : Type u_1} (tree : InternalData α (s_left.internal s_right)) (idxRight : SkeletonInternalIndex s_right) :
                                                tree.get idxRight.ofRight = tree.rightSubtree.get idxRight
                                                @[simp]
                                                theorem BinaryTree.InternalData.get_internal_ofLeft {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : InternalData α s_left) (right : InternalData α s_right) (idxLeft : SkeletonInternalIndex s_left) :
                                                (internal value left right).get idxLeft.ofLeft = left.get idxLeft
                                                @[simp]
                                                theorem BinaryTree.InternalData.get_internal_ofRight {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : InternalData α s_left) (right : InternalData α s_right) (idxRight : SkeletonInternalIndex s_right) :
                                                (internal value left right).get idxRight.ofRight = right.get idxRight
                                                @[simp]
                                                theorem BinaryTree.FullData.get_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : FullData α s_left) (right : FullData α s_right) :
                                                (internal value left right).get SkeletonNodeIndex.ofInternal = value
                                                @[simp]
                                                theorem BinaryTree.FullData.get_ofLeft {s_left s_right : Skeleton} {α : Type u_1} (tree : FullData α (s_left.internal s_right)) (idxLeft : SkeletonNodeIndex s_left) :
                                                tree.get idxLeft.ofLeft = tree.leftSubtree.get idxLeft
                                                @[simp]
                                                theorem BinaryTree.FullData.get_ofRight {s_left s_right : Skeleton} {α : Type u_1} (tree : FullData α (s_left.internal s_right)) (idxRight : SkeletonNodeIndex s_right) :
                                                tree.get idxRight.ofRight = tree.rightSubtree.get idxRight
                                                @[simp]
                                                theorem BinaryTree.FullData.get_internal_ofLeft {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : FullData α s_left) (right : FullData α s_right) (idxLeft : SkeletonNodeIndex s_left) :
                                                (internal value left right).get idxLeft.ofLeft = left.get idxLeft
                                                @[simp]
                                                theorem BinaryTree.FullData.get_internal_ofRight {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : FullData α s_left) (right : FullData α s_right) (idxRight : SkeletonNodeIndex s_right) :
                                                (internal value left right).get idxRight.ofRight = right.get idxRight
                                                def BinaryTree.FullData.toLeafData {α : Type u_1} {s : Skeleton} (tree : FullData α s) :

                                                Convert a FullData to a LeafData by dropping the internal node values.

                                                Instances For
                                                  def BinaryTree.FullData.toInternalData {α : Type u_1} {s : Skeleton} (tree : FullData α s) :

                                                  Convert a FullData to a InternalData by dropping the leaf node values.

                                                  Instances For
                                                    @[simp]
                                                    theorem BinaryTree.FullData.toLeafData_leftSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : FullData α (s_left.internal s_right)) :
                                                    @[simp]
                                                    theorem BinaryTree.FullData.toLeafData_rightSubtree {α : Type u_1} {s_left s_right : Skeleton} (tree : FullData α (s_left.internal s_right)) :
                                                    theorem BinaryTree.FullData.toLeafData_eq_leaf {α : Type u_1} (a : α) (tree : FullData α Skeleton.leaf) (h : LeafData.leaf a = tree.toLeafData) :
                                                    tree = leaf a
                                                    @[simp]
                                                    theorem BinaryTree.FullData.toLeafData_internal {α : Type u_1} {s_left s_right : Skeleton} (value : α) (left : FullData α s_left) (right : FullData α s_right) :
                                                    (internal value left right).toLeafData = left.toLeafData.internal right.toLeafData

                                                    Get the root index of a skeleton.

                                                    Instances For
                                                      def BinaryTree.FullData.getRootValue {s : Skeleton} {α : Type u_1} (tree : FullData α s) :
                                                      α

                                                      Get the root value of a FullData.

                                                      Instances For
                                                        @[simp]
                                                        theorem BinaryTree.FullData.getRootValue_leaf {α : Type u_1} (a : α) :
                                                        @[simp]
                                                        theorem BinaryTree.FullData.internal_getRootValue {s_left s_right : Skeleton} {α : Type u_1} (value : α) (left : FullData α s_left) (right : FullData α s_right) :
                                                        (internal value left right).getRootValue = value

                                                        Depth of a SkeletonLeafIndex

                                                        Instances For

                                                          Depth of a SkeletonInternalIndex

                                                          Instances For

                                                            Depth of a SkeletonNodeIndex

                                                            Instances For

                                                              Get the parent of a SkeletonNodeIndex, or none if the index is the root.

                                                              Instances For

                                                                Return the sibling node index of a given SkeletonNodeIndex. Or none if the node is the root.

                                                                Instances For

                                                                  Return the left child of a SkeletonNodeIndex, or none if the index is a leaf.

                                                                  Instances For

                                                                    Return the right child of a SkeletonNodeIndex, or none if the index is a leaf.

                                                                    Instances For

                                                                      Given a Skeleton, and a node index of the skeleton, return a list of node indices which are the ancestors of the node, starting with the root node, and going down to but not including the node itself.

                                                                      Instances For
                                                                        def BinaryTree.FullData.copath {α : Type u_1} {s : Skeleton} (cache_tree : FullData α s) :

                                                                        Find the siblings of a node and its ancestors, starting with the child of the root

                                                                        Instances For
                                                                          def BinaryTree.LeafData.map {α : Type u_1} {β : Type u_2} (f : αβ) {s : Skeleton} (tree : LeafData α s) :

                                                                          Apply a function to every value stored in a LeafData.

                                                                          Instances For
                                                                            def BinaryTree.InternalData.map {α : Type u_1} {β : Type u_2} (f : αβ) {s : Skeleton} (tree : InternalData α s) :

                                                                            Apply a function to every value stored in an InternalData.

                                                                            Instances For
                                                                              def BinaryTree.FullData.map {α : Type u_1} {β : Type u_2} (f : αβ) {s : Skeleton} (tree : FullData α s) :

                                                                              Apply a function to every value stored in a FullData.

                                                                              Instances For
                                                                                @[simp]
                                                                                theorem BinaryTree.FullData.map_leaf {α : Type u_1} {β : Type u_2} (f : αβ) (a : α) :
                                                                                map f (leaf a) = leaf (f a)
                                                                                @[simp]
                                                                                theorem BinaryTree.FullData.map_internal {α : Type u_1} {β : Type u_2} {s_left s_right : Skeleton} (f : αβ) (value : α) (left : FullData α s_left) (right : FullData α s_right) :
                                                                                map f (internal value left right) = internal (f value) (map f left) (map f right)
                                                                                @[simp]
                                                                                theorem BinaryTree.LeafData.map_leaf {α : Type u_1} {β : Type u_2} (f : αβ) (a : α) :
                                                                                map f (leaf a) = leaf (f a)
                                                                                @[simp]
                                                                                theorem BinaryTree.LeafData.map_internal {α : Type u_1} {β : Type u_2} {s_left s_right : Skeleton} (f : αβ) (left : LeafData α s_left) (right : LeafData α s_right) :
                                                                                map f (left.internal right) = (map f left).internal (map f right)
                                                                                theorem BinaryTree.FullData.map_getRootValue {α : Type u_1} {β : Type u_2} {s : Skeleton} (f : αβ) (tree : FullData α s) :
                                                                                (map f tree).getRootValue = f tree.getRootValue

                                                                                Build #

                                                                                This section contains theorems about building full trees from leaf trees.

                                                                                def BinaryTree.LeafData.composeBuild {α : Type u_1} {s : Skeleton} (leaf_data_tree : LeafData α s) (compose : ααα) :

                                                                                Build a FullData tree by hashing together the roots of child subtrees.

                                                                                Instances For
                                                                                  @[simp]
                                                                                  theorem BinaryTree.LeafData.composeBuild_leaf {α : Type u_1} (a : α) (compose : ααα) :
                                                                                  @[simp]
                                                                                  theorem BinaryTree.LeafData.composeBuild_internal {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) (compose : ααα) :
                                                                                  (left.internal right).composeBuild compose = FullData.internal (compose (left.composeBuild compose).getRootValue (right.composeBuild compose).getRootValue) (left.composeBuild compose) (right.composeBuild compose)
                                                                                  @[simp]
                                                                                  theorem BinaryTree.LeafData.composeBuild_getRootValue {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) (compose : ααα) :
                                                                                  ((left.internal right).composeBuild compose).getRootValue = compose (left.composeBuild compose).getRootValue (right.composeBuild compose).getRootValue
                                                                                  def BinaryTree.Option.doubleBind {α β γ : Type u_1} (f : αβOption γ) (x : Option α) (y : Option β) :

                                                                                  Lift a binary function through two Option arguments.

                                                                                  Instances For
                                                                                    def BinaryTree.LeafData.optionComposeBuild {α : Type u_1} {s : Skeleton} (leaf_data_tree : LeafData α s) (compose : ααOption α) :

                                                                                    Build a tree while allowing failures in the composition function.

                                                                                    Instances For
                                                                                      @[simp]
                                                                                      theorem BinaryTree.LeafData.optionComposeBuild_leaf {α : Type u_1} (a : α) (compose : ααOption α) :
                                                                                      @[simp]
                                                                                      theorem BinaryTree.LeafData.optionComposeBuild_internal {α : Type u_1} {s_left s_right : Skeleton} (left : LeafData α s_left) (right : LeafData α s_right) (compose : ααOption α) :