File: Mathlib/Data/Ordmap/Ordnode.lean

full_name: Ordnode.node
code: /-- An `Ordnode α` is a finite set of values, represented as a tree.
  The operations on this type maintain that the tree is balanced
  and correctly stores subtree sizes at each level. -/
inductive Ordnode (α : Type u) : Type u
  | nil : Ordnode α
  | node (size : ℕ) (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α
goal: Ordnode α

full_name: Ordnode
code: /-- An `Ordnode α` is a finite set of values, represented as a tree.
  The operations on this type maintain that the tree is balanced
  and correctly stores subtree sizes at each level. -/
inductive Ordnode (α : Type u) : Type u
  | nil : Ordnode α
  | node (size : ℕ) (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α
goal: Type u

full_name: Ordnode.nil
code: /-- An `Ordnode α` is a finite set of values, represented as a tree.
  The operations on this type maintain that the tree is balanced
  and correctly stores subtree sizes at each level. -/
inductive Ordnode (α : Type u) : Type u
  | nil : Ordnode α
  | node (size : ℕ) (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α
goal: Ordnode α

full_name: Ordnode.instEmptyCollection
code: instance : EmptyCollection (Ordnode α) 
goal: EmptyCollection (Ordnode α)

full_name: Ordnode.instInhabited
code: instance : Inhabited (Ordnode α) 
goal: Inhabited (Ordnode α)

full_name: Ordnode.delta
code: /-- **Internal use only**

The maximal relative difference between the sizes of
two trees, it corresponds with the `w` in Adams' paper.

According to the Haskell comment, only `(delta, ratio)` settings
of `(3, 2)` and `(4, 2)` will work, and the proofs in
`Ordset.lean` assume `delta := 3` and `ratio := 2`. -/
@[inline]
def delta 
goal: ℕ

full_name: Ordnode.ratio
code: /-- **Internal use only**

The ratio between an outer and inner sibling of the
heavier subtree in an unbalanced setting. It determines
whether a double or single rotation should be performed
to restore balance. It is corresponds with the inverse
of `α` in Adam's article. -/
@[inline]
def ratio 
goal: ℕ

full_name: Ordnode.singleton
code: /-- O(1). Construct a singleton set containing value `a`.

     singleton 3 = {3} -/
@[inline]
protected def singleton (a : α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode._aux_Mathlib_Data_Ordmap_Ordnode___macroRules_Ordnode_termι__1
code: local prefix:arg "ι" => Ordnode.singleton
goal: Lean.Macro

full_name: Ordnode._aux_Mathlib_Data_Ordmap_Ordnode___unexpand_Ordnode_singleton_1
code: local prefix:arg "ι" => Ordnode.singleton
goal: Lean.PrettyPrinter.Unexpander

full_name: Ordnode.instSingleton
code: instance : Singleton α (Ordnode α) 
goal: Singleton α (Ordnode α)

full_name: Ordnode.size
code: /-- O(1). Get the size of the set.

     size {2, 1, 1, 4} = 3  -/
@[inline]
def size : Ordnode α → ℕ
  
goal: Ordnode α → ℕ

full_name: Ordnode.size_nil
code: @[simp] theorem size_nil : size (nil : Ordnode α) = 0 
goal: Ordnode.nil.size = 0

full_name: Ordnode.size_node
code: @[simp] theorem size_node (sz : ℕ) (l : Ordnode α) (x : α) (r : Ordnode α) :
    size (node sz l x r) = sz 
goal: (Ordnode.node sz l x r).size = sz

full_name: Ordnode.empty
code: /-- O(1). Is the set empty?

     empty ∅ = tt
     empty {1, 2, 3} = ff -/
@[inline]
def empty : Ordnode α → Bool
  
goal: Ordnode α → Bool

full_name: Ordnode.dual
code: /-- **Internal use only**, because it violates the BST property on the original order.

O(n). The dual of a tree is a tree with its left and right sides reversed throughout.
The dual of a valid BST is valid under the dual order. This is convenient for exploiting
symmetries in the algorithms. -/
@[simp]
def dual : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.node'
code: /-- **Internal use only**

O(1). Construct a node with the correct size information, without rebalancing. -/
@[inline, reducible]
def node' (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.repr
code: /-- Basic pretty printing for `Ordnode α` that shows the structure of the tree.

     repr {3, 1, 2, 4} = ((∅ 1 ∅) 2 ((∅ 3 ∅) 4 ∅)) -/
def repr {α} [Repr α] (o : Ordnode α) (n : ℕ) : Std.Format 
goal: Lean.Format

full_name: Ordnode.instRepr
code: instance {α} [Repr α] : Repr (Ordnode α) 
goal: Repr (Ordnode α)

full_name: Ordnode.balanceL
code: /-- **Internal use only**

O(1). Rebalance a tree which was previously balanced but has had its left
side grow by 1, or its right side shrink by 1. -/
def balanceL (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.balanceR
code: /-- **Internal use only**

O(1). Rebalance a tree which was previously balanced but has had its right
side grow by 1, or its left side shrink by 1. -/
def balanceR (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.balance
code: /-- **Internal use only**

O(1). Rebalance a tree which was previously balanced but has had one side change
by at most 1. -/
def balance (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.All
code: /-- O(n). Does every element of the map satisfy property `P`?

     All (fun x ↦ x < 5) {1, 2, 3} = True
     All (fun x ↦ x < 5) {1, 2, 3, 5} = False -/
def All (P : α → Prop) : Ordnode α → Prop
  
goal: Ordnode α → Prop

full_name: Ordnode.All.decidable
code: instance All.decidable {P : α → Prop} : (t : Ordnode α) → [DecidablePred P] → Decidable (All P t)
  
goal: Decidable (Ordnode.All P t)

full_name: Ordnode.Any
code: /-- O(n). Does any element of the map satisfy property `P`?

     Any (fun x ↦ x < 2) {1, 2, 3} = True
     Any (fun x ↦ x < 2) {2, 3, 5} = False -/
def Any (P : α → Prop) : Ordnode α → Prop
  
goal: Ordnode α → Prop

full_name: Ordnode.Any.decidable
code: instance Any.decidable {P : α → Prop} : (t : Ordnode α ) → [DecidablePred P] → Decidable (Any P t)
  
goal: Decidable (Ordnode.Any P t)

full_name: Ordnode.Emem
code: /-- O(n). Exact membership in the set. This is useful primarily for stating
correctness properties; use `∈` for a version that actually uses the BST property
of the tree.

    Emem 2 {1, 2, 3} = true
    Emem 4 {1, 2, 3} = false -/
def Emem (x : α) : Ordnode α → Prop 
goal: Ordnode α → Prop

full_name: Ordnode.Emem.decidable
code: instance Emem.decidable (x : α) [DecidableEq α] : ∀ t, Decidable (Emem x t) 
goal: Decidable (Ordnode.Emem x t)

full_name: Ordnode.Amem
code: /-- O(n). Approximate membership in the set, that is, whether some element in the
set is equivalent to this one in the preorder. This is useful primarily for stating
correctness properties; use `∈` for a version that actually uses the BST property
of the tree.

    Amem 2 {1, 2, 3} = true
    Amem 4 {1, 2, 3} = false

To see the difference with `Emem`, we need a preorder that is not a partial order.
For example, suppose we compare pairs of numbers using only their first coordinate. Then:
-- Porting note: Verify below example
    emem (0, 1) {(0, 0), (1, 2)} = false
    amem (0, 1) {(0, 0), (1, 2)} = true
    (0, 1) ∈ {(0, 0), (1, 2)} = true

The `∈` relation is equivalent to `Amem` as long as the `Ordnode` is well formed,
and should always be used instead of `Amem`. -/
def Amem [LE α] (x : α) : Ordnode α → Prop 
goal: Ordnode α → Prop

full_name: Ordnode.Amem.decidable
code: instance Amem.decidable [LE α] [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Decidable (Amem x t) 
goal: Decidable (Ordnode.Amem x t)

full_name: Ordnode.findMin'
code: /-- O(log n). Return the minimum element of the tree, or the provided default value.

     findMin' 37 {1, 2, 3} = 1
     findMin' 37 ∅ = 37 -/
def findMin' : Ordnode α → α → α
  
goal: Ordnode α → α → α

full_name: Ordnode.findMin
code: /-- O(log n). Return the minimum element of the tree, if it exists.

     findMin {1, 2, 3} = some 1
     findMin ∅ = none -/
def findMin : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.findMax'
code: /-- O(log n). Return the maximum element of the tree, or the provided default value.

     findMax' 37 {1, 2, 3} = 3
     findMax' 37 ∅ = 37 -/
def findMax' : α → Ordnode α → α
  
goal: α → Ordnode α → α

full_name: Ordnode.findMax
code: /-- O(log n). Return the maximum element of the tree, if it exists.

     findMax {1, 2, 3} = some 3
     findMax ∅ = none -/
def findMax : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.eraseMin
code: /-- O(log n). Remove the minimum element from the tree, or do nothing if it is already empty.

     eraseMin {1, 2, 3} = {2, 3}
     eraseMin ∅ = ∅ -/
def eraseMin : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.eraseMax
code: /-- O(log n). Remove the maximum element from the tree, or do nothing if it is already empty.

     eraseMax {1, 2, 3} = {1, 2}
     eraseMax ∅ = ∅ -/
def eraseMax : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.splitMin'
code: /-- **Internal use only**, because it requires a balancing constraint on the inputs.

O(log n). Extract and remove the minimum element from a nonempty tree. -/
def splitMin' : Ordnode α → α → Ordnode α → α × Ordnode α
  
goal: Ordnode α → α → Ordnode α → α × Ordnode α

full_name: Ordnode.splitMin
code: /-- O(log n). Extract and remove the minimum element from the tree, if it exists.

     split_min {1, 2, 3} = some (1, {2, 3})
     split_min ∅ = none -/
def splitMin : Ordnode α → Option (α × Ordnode α)
  
goal: Ordnode α → Option (α × Ordnode α)

full_name: Ordnode.splitMax'
code: /-- **Internal use only**, because it requires a balancing constraint on the inputs.

O(log n). Extract and remove the maximum element from a nonempty tree. -/
def splitMax' : Ordnode α → α → Ordnode α → Ordnode α × α
  
goal: Ordnode α → α → Ordnode α → Ordnode α × α

full_name: Ordnode.splitMax
code: /-- O(log n). Extract and remove the maximum element from the tree, if it exists.

     split_max {1, 2, 3} = some ({1, 2}, 3)
     split_max ∅ = none -/
def splitMax : Ordnode α → Option (Ordnode α × α)
  
goal: Ordnode α → Option (Ordnode α × α)

full_name: Ordnode.glue
code: /-- **Internal use only**

O(log(m + n)). Concatenate two trees that are balanced and ordered with respect to each other. -/
def glue : Ordnode α → Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α → Ordnode α

full_name: Ordnode.merge
code: /-- O(log(m + n)). Concatenate two trees that are ordered with respect to each other.

     merge {1, 2} {3, 4} = {1, 2, 3, 4}
     merge {3, 4} {1, 2} = precondition violation -/
def merge (l : Ordnode α) : Ordnode α → Ordnode α 
goal: Ordnode α → Ordnode α

full_name: Ordnode.insertMax
code: /-- O(log n). Insert an element above all the others, without any comparisons.
(Assumes that the element is in fact above all the others).

    insertMax {1, 2} 4 = {1, 2, 4}
    insertMax {1, 2} 0 = precondition violation -/
def insertMax : Ordnode α → α → Ordnode α
  
goal: Ordnode α → α → Ordnode α

full_name: Ordnode.insertMin
code: /-- O(log n). Insert an element below all the others, without any comparisons.
(Assumes that the element is in fact below all the others).

    insertMin {1, 2} 0 = {0, 1, 2}
    insertMin {1, 2} 4 = precondition violation -/
def insertMin (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.link
code: /-- O(log(m+n)). Build a tree from an element between two trees, without any
assumption on the relative sizes.

    link {1, 2} 4 {5, 6} = {1, 2, 4, 5, 6}
    link {1, 3} 2 {5} = precondition violation -/
def link (l : Ordnode α) (x : α) : Ordnode α → Ordnode α 
goal: Ordnode α → Ordnode α

full_name: Ordnode.filter
code: /-- O(n). Filter the elements of a tree satisfying a predicate.

     filter (fun x ↦ x < 3) {1, 2, 4} = {1, 2}
     filter (fun x ↦ x > 5) {1, 2, 4} = ∅ -/
def filter (p : α → Prop) [DecidablePred p] : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.partition
code: /-- O(n). Split the elements of a tree into those satisfying, and not satisfying, a predicate.

     partition (fun x ↦ x < 3) {1, 2, 4} = ({1, 2}, {3}) -/
def partition (p : α → Prop) [DecidablePred p] : Ordnode α → Ordnode α × Ordnode α
  
goal: Ordnode α → Ordnode α × Ordnode α

full_name: Ordnode.map
code: /-- O(n). Map a function across a tree, without changing the structure. Only valid when
the function is strictly monotone, i.e. `x < y → f x < f y`.

     partition (fun x ↦ x + 2) {1, 2, 4} = {2, 3, 6}
     partition (fun x : ℕ ↦ x - 2) {1, 2, 4} = precondition violation -/
def map {β} (f : α → β) : Ordnode α → Ordnode β
  
goal: Ordnode α → Ordnode β

full_name: Ordnode.fold
code: /-- O(n). Fold a function across the structure of a tree.

     fold z f {1, 2, 4} = f (f z 1 z) 2 (f z 4 z)

The exact structure of function applications depends on the tree and so
is unspecified. -/
def fold {β} (z : β) (f : β → α → β → β) : Ordnode α → β
  
goal: Ordnode α → β

full_name: Ordnode.foldl
code: /-- O(n). Fold a function from left to right (in increasing order) across the tree.

     foldl f z {1, 2, 4} = f (f (f z 1) 2) 4 -/
def foldl {β} (f : β → α → β) : β → Ordnode α → β
  
goal: β → Ordnode α → β

full_name: Ordnode.foldr
code: /-- O(n). Fold a function from right to left (in decreasing order) across the tree.

     foldr f {1, 2, 4} z = f 1 (f 2 (f 4 z)) -/
def foldr {β} (f : α → β → β) : Ordnode α → β → β
  
goal: Ordnode α → β → β

full_name: Ordnode.toList
code: /-- O(n). Build a list of elements in ascending order from the tree.

     toList {1, 2, 4} = [1, 2, 4]
     toList {2, 1, 1, 4} = [1, 2, 4] -/
def toList (t : Ordnode α) : List α 
goal: List α

full_name: Ordnode.toRevList
code: /-- O(n). Build a list of elements in descending order from the tree.

     toRevList {1, 2, 4} = [4, 2, 1]
     toRevList {2, 1, 1, 4} = [4, 2, 1] -/
def toRevList (t : Ordnode α) : List α 
goal: List α

full_name: Ordnode.instToString
code: instance [ToString α] : ToString (Ordnode α) 
goal: ToString (Ordnode α)

full_name: Ordnode.instToFormat
code: instance [Std.ToFormat α] : Std.ToFormat (Ordnode α) 
goal: Lean.ToFormat (Ordnode α)

full_name: Ordnode.Equiv
code: /-- O(n). True if the trees have the same elements, ignoring structural differences.

     Equiv {1, 2, 4} {2, 1, 1, 4} = true
     Equiv {1, 2, 4} {1, 2, 3} = false -/
def Equiv (t₁ t₂ : Ordnode α) : Prop 
goal: Prop

full_name: Ordnode.instDecidableRelEquivOfDecidableEq
code: instance [DecidableEq α] : DecidableRel (@Equiv α) 
goal: DecidableRel Ordnode.Equiv

full_name: Ordnode.powerset
code: /-- O(2^n). Constructs the powerset of a given set, that is, the set of all subsets.

     powerset {1, 2, 3} = {∅, {1}, {2}, {3}, {1,2}, {1,3}, {2,3}, {1,2,3}} -/
def powerset (t : Ordnode α) : Ordnode (Ordnode α) 
goal: Ordnode (Ordnode α)

full_name: Ordnode.prod
code: /-- O(m * n). The cartesian product of two sets: `(a, b) ∈ s.prod t` iff `a ∈ s` and `b ∈ t`.

     prod {1, 2} {2, 3} = {(1, 2), (1, 3), (2, 2), (2, 3)} -/
protected def prod {β} (t₁ : Ordnode α) (t₂ : Ordnode β) : Ordnode (α × β) 
goal: Ordnode (α × β)

full_name: Ordnode.copair
code: /-- O(m + n). Build a set on the disjoint union by combining sets on the factors.
`Or.inl a ∈ s.copair t` iff `a ∈ s`, and `Or.inr b ∈ s.copair t` iff `b ∈ t`.

    copair {1, 2} {2, 3} = {inl 1, inl 2, inr 2, inr 3} -/
protected def copair {β} (t₁ : Ordnode α) (t₂ : Ordnode β) : Ordnode (α ⊕ β) 
goal: Ordnode (α ⊕ β)

full_name: Ordnode.pmap
code: /-- O(n). Map a partial function across a set. The result depends on a proof
that the function is defined on all members of the set.

    pmap (fin.mk : ∀ n, n < 4 → fin 4) {1, 2} H = {(1 : fin 4), (2 : fin 4)} -/
def pmap {P : α → Prop} {β} (f : ∀ a, P a → β) : ∀ t : Ordnode α, All P t → Ordnode β
  
goal: Ordnode.All P t → Ordnode β

full_name: Ordnode.attach'
code: /-- O(n). "Attach" the information that every element of `t` satisfies property
P to these elements inside the set, producing a set in the subtype.

    attach' (fun x ↦ x < 4) {1, 2} H = ({1, 2} : Ordnode {x // x<4}) -/
def attach' {P : α → Prop} : ∀ t, All P t → Ordnode { a // P a } 
goal: Ordnode.All P t → Ordnode { a // P a }

full_name: Ordnode.nth
code: /-- O(log n). Get the `i`th element of the set, by its index from left to right.

     nth {a, b, c, d} 2 = some c
     nth {a, b, c, d} 5 = none -/
def nth : Ordnode α → ℕ → Option α
  
goal: Ordnode α → ℕ → Option α

full_name: Ordnode.removeNth
code: /-- O(log n). Remove the `i`th element of the set, by its index from left to right.

     remove_nth {a, b, c, d} 2 = {a, b, d}
     remove_nth {a, b, c, d} 5 = {a, b, c, d} -/
def removeNth : Ordnode α → ℕ → Ordnode α
  
goal: Ordnode α → ℕ → Ordnode α

full_name: Ordnode.takeAux
code: /-- Auxiliary definition for `take`. (Can also be used in lieu of `take` if you know the
index is within the range of the data structure.)

    takeAux {a, b, c, d} 2 = {a, b}
    takeAux {a, b, c, d} 5 = {a, b, c, d} -/
def takeAux : Ordnode α → ℕ → Ordnode α
  
goal: Ordnode α → ℕ → Ordnode α

full_name: Ordnode.take
code: /-- O(log n). Get the first `i` elements of the set, counted from the left.

     take 2 {a, b, c, d} = {a, b}
     take 5 {a, b, c, d} = {a, b, c, d} -/
def take (i : ℕ) (t : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.dropAux
code: /-- Auxiliary definition for `drop`. (Can also be used in lieu of `drop` if you know the
index is within the range of the data structure.)

    drop_aux {a, b, c, d} 2 = {c, d}
    drop_aux {a, b, c, d} 5 = ∅ -/
def dropAux : Ordnode α → ℕ → Ordnode α
  
goal: Ordnode α → ℕ → Ordnode α

full_name: Ordnode.drop
code: /-- O(log n). Remove the first `i` elements of the set, counted from the left.

     drop 2 {a, b, c, d} = {c, d}
     drop 5 {a, b, c, d} = ∅ -/
def drop (i : ℕ) (t : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.splitAtAux
code: /-- Auxiliary definition for `splitAt`. (Can also be used in lieu of `splitAt` if you know the
index is within the range of the data structure.)

    splitAtAux {a, b, c, d} 2 = ({a, b}, {c, d})
    splitAtAux {a, b, c, d} 5 = ({a, b, c, d}, ∅) -/
def splitAtAux : Ordnode α → ℕ → Ordnode α × Ordnode α
  
goal: Ordnode α → ℕ → Ordnode α × Ordnode α

full_name: Ordnode.splitAt
code: /-- O(log n). Split a set at the `i`th element, getting the first `i` and everything else.

     splitAt 2 {a, b, c, d} = ({a, b}, {c, d})
     splitAt 5 {a, b, c, d} = ({a, b, c, d}, ∅) -/
def splitAt (i : ℕ) (t : Ordnode α) : Ordnode α × Ordnode α 
goal: Ordnode α × Ordnode α

full_name: Ordnode.takeWhile
code: /-- O(log n). Get an initial segment of the set that satisfies the predicate `p`.
`p` is required to be antitone, that is, `x < y → p y → p x`.

    takeWhile (fun x ↦ x < 4) {1, 2, 3, 4, 5} = {1, 2, 3}
    takeWhile (fun x ↦ x > 4) {1, 2, 3, 4, 5} = precondition violation -/
def takeWhile (p : α → Prop) [DecidablePred p] : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.dropWhile
code: /-- O(log n). Remove an initial segment of the set that satisfies the predicate `p`.
`p` is required to be antitone, that is, `x < y → p y → p x`.

    dropWhile (fun x ↦ x < 4) {1, 2, 3, 4, 5} = {4, 5}
    dropWhile (fun x ↦ x > 4) {1, 2, 3, 4, 5} = precondition violation -/
def dropWhile (p : α → Prop) [DecidablePred p] : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.span
code: /-- O(log n). Split the set into those satisfying and not satisfying the predicate `p`.
`p` is required to be antitone, that is, `x < y → p y → p x`.

    span (fun x ↦ x < 4) {1, 2, 3, 4, 5} = ({1, 2, 3}, {4, 5})
    span (fun x ↦ x > 4) {1, 2, 3, 4, 5} = precondition violation -/
def span (p : α → Prop) [DecidablePred p] : Ordnode α → Ordnode α × Ordnode α
  
goal: Ordnode α → Ordnode α × Ordnode α

full_name: Ordnode.ofAscListAux₁
code: /-- Auxiliary definition for `ofAscList`.

**Note:** This function is defined by well founded recursion, so it will probably not compute
in the kernel, meaning that you probably can't prove things like
`ofAscList [1, 2, 3] = {1, 2, 3}` by `rfl`.
This implementation is optimized for VM evaluation. -/
def ofAscListAux₁ : ∀ l : List α, ℕ → Ordnode α × { l' : List α // l'.length ≤ l.length }
  
goal: ℕ → Ordnode α × { l' // l'.length ≤ l.length }

full_name: Ordnode.ofAscListAux₂
code: /-- Auxiliary definition for `ofAscList`. -/
def ofAscListAux₂ : List α → Ordnode α → ℕ → Ordnode α
  
goal: List α → Ordnode α → ℕ → Ordnode α

full_name: Ordnode.ofAscList
code: /-- O(n). Build a set from a list which is already sorted. Performs no comparisons.

     ofAscList [1, 2, 3] = {1, 2, 3}
     ofAscList [3, 2, 1] = precondition violation -/
def ofAscList : List α → Ordnode α
  
goal: List α → Ordnode α

full_name: Ordnode.mem
code: /-- O(log n). Does the set (approximately) contain the element `x`? That is,
is there an element that is equivalent to `x` in the order?

    1 ∈ {1, 2, 3} = true
    4 ∈ {1, 2, 3} = false

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    (1, 1) ∈ {(0, 1), (1, 2)} = true
    (3, 1) ∈ {(0, 1), (1, 2)} = false -/
def mem (x : α) : Ordnode α → Bool
  
goal: Ordnode α → Bool

full_name: Ordnode.find
code: /-- O(log n). Retrieve an element in the set that is equivalent to `x` in the order,
if it exists.

    find 1 {1, 2, 3} = some 1
    find 4 {1, 2, 3} = none

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    find (1, 1) {(0, 1), (1, 2)} = some (1, 2)
    find (3, 1) {(0, 1), (1, 2)} = none -/
def find (x : α) : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.instMembership
code: instance : Membership α (Ordnode α) 
goal: Membership α (Ordnode α)

full_name: Ordnode.mem.decidable
code: instance mem.decidable (x : α) (t : Ordnode α) : Decidable (x ∈ t) 
goal: Decidable (x ∈ t)

full_name: Ordnode.insertWith
code: /-- O(log n). Insert an element into the set, preserving balance and the BST property.
If an equivalent element is already in the set, the function `f` is used to generate
the element to insert (being passed the current value in the set).

    insertWith f 0 {1, 2, 3} = {0, 1, 2, 3}
    insertWith f 1 {1, 2, 3} = {f 1, 2, 3}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    insertWith f (1, 1) {(0, 1), (1, 2)} = {(0, 1), f (1, 2)}
    insertWith f (3, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 2), (3, 1)} -/
def insertWith (f : α → α) (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.adjustWith
code: /-- O(log n). Modify an element in the set with the given function,
doing nothing if the key is not found.
Note that the element returned by `f` must be equivalent to `x`.

    adjustWith f 0 {1, 2, 3} = {1, 2, 3}
    adjustWith f 1 {1, 2, 3} = {f 1, 2, 3}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    adjustWith f (1, 1) {(0, 1), (1, 2)} = {(0, 1), f (1, 2)}
    adjustWith f (3, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 2)} -/
def adjustWith (f : α → α) (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.updateWith
code: /-- O(log n). Modify an element in the set with the given function,
doing nothing if the key is not found.
Note that the element returned by `f` must be equivalent to `x`.

    updateWith f 0 {1, 2, 3} = {1, 2, 3}
    updateWith f 1 {1, 2, 3} = {2, 3}     if f 1 = none
                              = {a, 2, 3}  if f 1 = some a -/
def updateWith (f : α → Option α) (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.alter
code: /-- O(log n). Modify an element in the set with the given function,
doing nothing if the key is not found.
Note that the element returned by `f` must be equivalent to `x`.

    alter f 0 {1, 2, 3} = {1, 2, 3}     if f none = none
                        = {a, 1, 2, 3}  if f none = some a
    alter f 1 {1, 2, 3} = {2, 3}     if f 1 = none
                        = {a, 2, 3}  if f 1 = some a -/
def alter (f : Option α → Option α) (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.insert
code: /-- O(log n). Insert an element into the set, preserving balance and the BST property.
If an equivalent element is already in the set, this replaces it.

    insert 1 {1, 2, 3} = {1, 2, 3}
    insert 4 {1, 2, 3} = {1, 2, 3, 4}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    insert (1, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 1)}
    insert (3, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 2), (3, 1)} -/
protected def insert (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.instInsert
code: instance : Insert α (Ordnode α) 
goal: Insert α (Ordnode α)

full_name: Ordnode.insert'
code: /-- O(log n). Insert an element into the set, preserving balance and the BST property.
If an equivalent element is already in the set, the set is returned as is.

    insert' 1 {1, 2, 3} = {1, 2, 3}
    insert' 4 {1, 2, 3} = {1, 2, 3, 4}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    insert' (1, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 2)}
    insert' (3, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 2), (3, 1)} -/
def insert' (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.split
code: /-- O(log n). Split the tree into those smaller than `x` and those greater than it.
If an element equivalent to `x` is in the set, it is discarded.

    split 2 {1, 2, 4} = ({1}, {4})
    split 3 {1, 2, 4} = ({1, 2}, {4})
    split 4 {1, 2, 4} = ({1, 2}, ∅)

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    split (1, 1) {(0, 1), (1, 2)} = ({(0, 1)}, ∅)
    split (3, 1) {(0, 1), (1, 2)} = ({(0, 1), (1, 2)}, ∅) -/
def split (x : α) : Ordnode α → Ordnode α × Ordnode α
  
goal: Ordnode α → Ordnode α × Ordnode α

full_name: Ordnode.split3
code: /-- O(log n). Split the tree into those smaller than `x` and those greater than it,
plus an element equivalent to `x`, if it exists.

    split3 2 {1, 2, 4} = ({1}, some 2, {4})
    split3 3 {1, 2, 4} = ({1, 2}, none, {4})
    split3 4 {1, 2, 4} = ({1, 2}, some 4, ∅)

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    split3 (1, 1) {(0, 1), (1, 2)} = ({(0, 1)}, some (1, 2), ∅)
    split3 (3, 1) {(0, 1), (1, 2)} = ({(0, 1), (1, 2)}, none, ∅) -/
def split3 (x : α) : Ordnode α → Ordnode α × Option α × Ordnode α
  
goal: Ordnode α → Ordnode α × Option α × Ordnode α

full_name: Ordnode.erase
code: /-- O(log n). Remove an element from the set equivalent to `x`. Does nothing if there
is no such element.

    erase 1 {1, 2, 3} = {2, 3}
    erase 4 {1, 2, 3} = {1, 2, 3}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    erase (1, 1) {(0, 1), (1, 2)} = {(0, 1)}
    erase (3, 1) {(0, 1), (1, 2)} = {(0, 1), (1, 2)} -/
def erase (x : α) : Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α

full_name: Ordnode.findLtAux
code: /-- Auxiliary definition for `findLt`. -/
def findLtAux (x : α) : Ordnode α → α → α
  
goal: Ordnode α → α → α

full_name: Ordnode.findLt
code: /-- O(log n). Get the largest element in the tree that is `< x`.

     findLt 2 {1, 2, 4} = some 1
     findLt 3 {1, 2, 4} = some 2
     findLt 0 {1, 2, 4} = none -/
def findLt (x : α) : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.findGtAux
code: /-- Auxiliary definition for `findGt`. -/
def findGtAux (x : α) : Ordnode α → α → α
  
goal: Ordnode α → α → α

full_name: Ordnode.findGt
code: /-- O(log n). Get the smallest element in the tree that is `> x`.

     findGt 2 {1, 2, 4} = some 4
     findGt 3 {1, 2, 4} = some 4
     findGt 4 {1, 2, 4} = none -/
def findGt (x : α) : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.findLeAux
code: /-- Auxiliary definition for `findLe`. -/
def findLeAux (x : α) : Ordnode α → α → α
  
goal: Ordnode α → α → α

full_name: Ordnode.findLe
code: /-- O(log n). Get the largest element in the tree that is `≤ x`.

     findLe 2 {1, 2, 4} = some 2
     findLe 3 {1, 2, 4} = some 2
     findLe 0 {1, 2, 4} = none -/
def findLe (x : α) : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.findGeAux
code: /-- Auxiliary definition for `findGe`. -/
def findGeAux (x : α) : Ordnode α → α → α
  
goal: Ordnode α → α → α

full_name: Ordnode.findGe
code: /-- O(log n). Get the smallest element in the tree that is `≥ x`.

     findGe 2 {1, 2, 4} = some 2
     findGe 3 {1, 2, 4} = some 4
     findGe 5 {1, 2, 4} = none -/
def findGe (x : α) : Ordnode α → Option α
  
goal: Ordnode α → Option α

full_name: Ordnode.findIndexAux
code: /-- Auxiliary definition for `findIndex`. -/
def findIndexAux (x : α) : Ordnode α → ℕ → Option ℕ
  
goal: Ordnode α → ℕ → Option ℕ

full_name: Ordnode.findIndex
code: /-- O(log n). Get the index, counting from the left,
of an element equivalent to `x` if it exists.

    findIndex 2 {1, 2, 4} = some 1
    findIndex 4 {1, 2, 4} = some 2
    findIndex 5 {1, 2, 4} = none -/
def findIndex (x : α) (t : Ordnode α) : Option ℕ 
goal: Option ℕ

full_name: Ordnode.isSubsetAux
code: /-- Auxiliary definition for `isSubset`. -/
def isSubsetAux : Ordnode α → Ordnode α → Bool
  
goal: Ordnode α → Ordnode α → Bool

full_name: Ordnode.isSubset
code: /-- O(m + n). Is every element of `t₁` equivalent to some element of `t₂`?

     is_subset {1, 4} {1, 2, 4} = tt
     is_subset {1, 3} {1, 2, 4} = ff -/
def isSubset (t₁ t₂ : Ordnode α) : Bool 
goal: Bool

full_name: Ordnode.disjoint
code: /-- O(m + n). Is every element of `t₁` not equivalent to any element of `t₂`?

     disjoint {1, 3} {2, 4} = tt
     disjoint {1, 2} {2, 4} = ff -/
def disjoint : Ordnode α → Ordnode α → Bool
  
goal: Ordnode α → Ordnode α → Bool

full_name: Ordnode.union
code: /-- O(m * log(|m ∪ n| + 1)), m ≤ n. The union of two sets, preferring members of
  `t₁` over those of `t₂` when equivalent elements are encountered.

    union {1, 2} {2, 3} = {1, 2, 3}
    union {1, 3} {2} = {1, 2, 3}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    union {(1, 1)} {(0, 1), (1, 2)} = {(0, 1), (1, 1)} -/
def union : Ordnode α → Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α → Ordnode α

full_name: Ordnode.diff
code: /-- O(m * log(|m ∪ n| + 1)), m ≤ n. Difference of two sets.

    diff {1, 2} {2, 3} = {1}
    diff {1, 2, 3} {2} = {1, 3} -/
def diff : Ordnode α → Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α → Ordnode α

full_name: Ordnode.inter
code: /-- O(m * log(|m ∪ n| + 1)), m ≤ n. Intersection of two sets, preferring members of
`t₁` over those of `t₂` when equivalent elements are encountered.

    inter {1, 2} {2, 3} = {2}
    inter {1, 3} {2} = ∅ -/
def inter : Ordnode α → Ordnode α → Ordnode α
  
goal: Ordnode α → Ordnode α → Ordnode α

full_name: Ordnode.ofList
code: /-- O(n * log n). Build a set from a list, preferring elements that appear earlier in the list
in the case of equivalent elements.

    ofList [1, 2, 3] = {1, 2, 3}
    ofList [2, 1, 1, 3] = {1, 2, 3}

Using a preorder on `ℕ × ℕ` that only compares the first coordinate:

    ofList [(1, 1), (0, 1), (1, 2)] = {(0, 1), (1, 1)} -/
def ofList (l : List α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.ofList'
code: /-- O(n * log n). Adaptively chooses between the linear and log-linear algorithm depending
  on whether the input list is already sorted.

    ofList' [1, 2, 3] = {1, 2, 3}
    ofList' [2, 1, 1, 3] = {1, 2, 3} -/
def ofList' : List α → Ordnode α
  
goal: List α → Ordnode α

full_name: Ordnode.image
code: /-- O(n * log n). Map a function on a set. Unlike `map` this has no requirements on
`f`, and the resulting set may be smaller than the input if `f` is noninjective.
Equivalent elements are selected with a preference for smaller source elements.

    image (fun x ↦ x + 2) {1, 2, 4} = {3, 4, 6}
    image (fun x : ℕ ↦ x - 2) {1, 2, 4} = {0, 2} -/
def image {α β} [LE β] [@DecidableRel β (· ≤ ·)] (f : α → β) (t : Ordnode α) : Ordnode β 
goal: Ordnode β