File: Mathlib/Data/Ordmap/Ordset.lean

full_name: Ordnode.not_le_delta
code: theorem not_le_delta {s} (H : 1 ≤ s) : ¬s ≤ delta * 0 
goal: ¬s ≤ Ordnode.delta * 0

full_name: Ordnode.delta_lt_false
code: theorem delta_lt_false {a b : ℕ} (h₁ : delta * a < b) (h₂ : delta * b < a) : False 
goal: False

full_name: Ordnode.realSize
code: /-- O(n). Computes the actual number of elements in the set, ignoring the cached `size` field. -/
def realSize : Ordnode α → ℕ
  
goal: Ordnode α → ℕ

full_name: Ordnode.Sized
code: /-- The `Sized` property asserts that all the `size` fields in nodes match the actual size of the
respective subtrees. -/
def Sized : Ordnode α → Prop
  
goal: Ordnode α → Prop

full_name: Ordnode.Sized.node'
code: theorem Sized.node' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (node' l x r) 
goal: (l.node' x r).Sized

full_name: Ordnode.Sized.eq_node'
code: theorem Sized.eq_node' {s l x r} (h : @Sized α (node s l x r)) : node s l x r = .node' l x r 
goal: Ordnode.node s l x r = l.node' x r

full_name: Ordnode.Sized.size_eq
code: theorem Sized.size_eq {s l x r} (H : Sized (@node α s l x r)) :
    size (@node α s l x r) = size l + size r + 1 
goal: (Ordnode.node s l x r).size = l.size + r.size + 1

full_name: Ordnode.Sized.induction
code: @[elab_as_elim]
theorem Sized.induction {t} (hl : @Sized α t) {C : Ordnode α → Prop} (H0 : C nil)
    (H1 : ∀ l x r, C l → C r → C (.node' l x r)) : C t 
goal: C t

full_name: Ordnode.size_eq_realSize
code: theorem size_eq_realSize : ∀ {t : Ordnode α}, Sized t → size t = realSize t
  
goal: t.Sized → t.size = t.realSize

full_name: Ordnode.Sized.size_eq_zero
code: @[simp]
theorem Sized.size_eq_zero {t : Ordnode α} (ht : Sized t) : size t = 0 ↔ t = nil 
goal: t.size = 0 ↔ t = Ordnode.nil

full_name: Ordnode.Sized.pos
code: theorem Sized.pos {s l x r} (h : Sized (@node α s l x r)) : 0 < s 
goal: 0 < s

full_name: Ordnode.dual_dual
code: theorem dual_dual : ∀ t : Ordnode α, dual (dual t) = t
  
goal: t.dual.dual = t

full_name: Ordnode.size_dual
code: @[simp]
theorem size_dual (t : Ordnode α) : size (dual t) = size t 
goal: t.dual.size = t.size

full_name: Ordnode.BalancedSz
code: /-- The `BalancedSz l r` asserts that a hypothetical tree with children of sizes `l` and `r` is
balanced: either `l ≤ δ * r` and `r ≤ δ * r`, or the tree is trivial with a singleton on one side
and nothing on the other. -/
def BalancedSz (l r : ℕ) : Prop 
goal: Prop

full_name: Ordnode.BalancedSz.dec
code: instance BalancedSz.dec : DecidableRel BalancedSz 
goal: DecidableRel Ordnode.BalancedSz

full_name: Ordnode.Balanced
code: /-- The `Balanced t` asserts that the tree `t` satisfies the balance invariants
(at every level). -/
def Balanced : Ordnode α → Prop
  
goal: Ordnode α → Prop

full_name: Ordnode.Balanced.dec
code: instance Balanced.dec : DecidablePred (@Balanced α)
  
goal: DecidablePred Ordnode.Balanced

full_name: Ordnode.BalancedSz.symm
code: @[symm]
theorem BalancedSz.symm {l r : ℕ} : BalancedSz l r → BalancedSz r l 
goal: Ordnode.BalancedSz l r → Ordnode.BalancedSz r l

full_name: Ordnode.balancedSz_zero
code: theorem balancedSz_zero {l : ℕ} : BalancedSz l 0 ↔ l ≤ 1 
goal: Ordnode.BalancedSz l 0 ↔ l ≤ 1

full_name: Ordnode.balancedSz_up
code: theorem balancedSz_up {l r₁ r₂ : ℕ} (h₁ : r₁ ≤ r₂) (h₂ : l + r₂ ≤ 1 ∨ r₂ ≤ delta * l)
    (H : BalancedSz l r₁) : BalancedSz l r₂ 
goal: Ordnode.BalancedSz l r₂

full_name: Ordnode.balancedSz_down
code: theorem balancedSz_down {l r₁ r₂ : ℕ} (h₁ : r₁ ≤ r₂) (h₂ : l + r₂ ≤ 1 ∨ l ≤ delta * r₁)
    (H : BalancedSz l r₂) : BalancedSz l r₁ 
goal: Ordnode.BalancedSz l r₁

full_name: Ordnode.Balanced.dual
code: theorem Balanced.dual : ∀ {t : Ordnode α}, Balanced t → Balanced (dual t)
  
goal: t.Balanced → t.dual.Balanced

full_name: Ordnode.node3L
code: /-- Build a tree from three nodes, left associated (ignores the invariants). -/
def node3L (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.node3R
code: /-- Build a tree from three nodes, right associated (ignores the invariants). -/
def node3R (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.node4L
code: /-- Build a tree from three nodes, with `a () b -> (a ()) b` and `a (b c) d -> ((a b) (c d))`. -/
def node4L : Ordnode α → α → Ordnode α → α → Ordnode α → Ordnode α
  
goal: Ordnode α → α → Ordnode α → α → Ordnode α → Ordnode α

full_name: Ordnode.node4R
code: /-- Build a tree from three nodes, with `a () b -> a (() b)` and `a (b c) d -> ((a b) (c d))`. -/
def node4R : Ordnode α → α → Ordnode α → α → Ordnode α → Ordnode α
  
goal: Ordnode α → α → Ordnode α → α → Ordnode α → Ordnode α

full_name: Ordnode.rotateL
code: /-- Concatenate two nodes, performing a left rotation `x (y z) -> ((x y) z)`
if balance is upset. -/
def rotateL : Ordnode α → α → Ordnode α → Ordnode α
  
goal: Ordnode α → α → Ordnode α → Ordnode α

full_name: Ordnode.rotateL_node
code: theorem rotateL_node (l : Ordnode α) (x : α) (sz : ℕ) (m : Ordnode α) (y : α) (r : Ordnode α) :
    rotateL l x (node sz m y r) =
      if size m < ratio * size r then node3L l x m y r else node4L l x m y r 
goal: l.rotateL x (Ordnode.node sz m y r) = if m.size < Ordnode.ratio * r.size then l.node3L x m y r else l.node4L x m y r

full_name: Ordnode.rotateL_nil
code: theorem rotateL_nil (l : Ordnode α) (x : α) : rotateL l x nil = node' l x nil 
goal: l.rotateL x Ordnode.nil = l.node' x Ordnode.nil

full_name: Ordnode.rotateR
code: /-- Concatenate two nodes, performing a right rotation `(x y) z -> (x (y z))`
if balance is upset. -/
def rotateR : Ordnode α → α → Ordnode α → Ordnode α
  
goal: Ordnode α → α → Ordnode α → Ordnode α

full_name: Ordnode.rotateR_node
code: theorem rotateR_node (sz : ℕ) (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) :
    rotateR (node sz l x m) y r =
      if size m < ratio * size l then node3R l x m y r else node4R l x m y r 
goal: (Ordnode.node sz l x m).rotateR y r = if m.size < Ordnode.ratio * l.size then l.node3R x m y r else l.node4R x m y r

full_name: Ordnode.rotateR_nil
code: theorem rotateR_nil (y : α) (r : Ordnode α) : rotateR nil y r = node' nil y r 
goal: Ordnode.nil.rotateR y r = Ordnode.nil.node' y r

full_name: Ordnode.balanceL'
code: /-- A left balance operation. This will rebalance a concatenation, assuming the original nodes are
not too far from balanced. -/
def balanceL' (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.balanceR'
code: /-- A right balance operation. This will rebalance a concatenation, assuming the original nodes are
not too far from balanced. -/
def balanceR' (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.balance'
code: /-- The full balance operation. This is the same as `balance`, but with less manual inlining.
It is somewhat easier to work with this version in proofs. -/
def balance' (l : Ordnode α) (x : α) (r : Ordnode α) : Ordnode α 
goal: Ordnode α

full_name: Ordnode.dual_node'
code: theorem dual_node' (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (node' l x r) = node' (dual r) x (dual l) 
goal: (l.node' x r).dual = r.dual.node' x l.dual

full_name: Ordnode.dual_node3L
code: theorem dual_node3L (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) :
    dual (node3L l x m y r) = node3R (dual r) y (dual m) x (dual l) 
goal: (l.node3L x m y r).dual = r.dual.node3R y m.dual x l.dual

full_name: Ordnode.dual_node3R
code: theorem dual_node3R (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) :
    dual (node3R l x m y r) = node3L (dual r) y (dual m) x (dual l) 
goal: (l.node3R x m y r).dual = r.dual.node3L y m.dual x l.dual

full_name: Ordnode.dual_node4L
code: theorem dual_node4L (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) :
    dual (node4L l x m y r) = node4R (dual r) y (dual m) x (dual l) 
goal: (l.node4L x m y r).dual = r.dual.node4R y m.dual x l.dual

full_name: Ordnode.dual_node4R
code: theorem dual_node4R (l : Ordnode α) (x : α) (m : Ordnode α) (y : α) (r : Ordnode α) :
    dual (node4R l x m y r) = node4L (dual r) y (dual m) x (dual l) 
goal: (l.node4R x m y r).dual = r.dual.node4L y m.dual x l.dual

full_name: Ordnode.dual_rotateL
code: theorem dual_rotateL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (rotateL l x r) = rotateR (dual r) x (dual l) 
goal: (l.rotateL x r).dual = r.dual.rotateR x l.dual

full_name: Ordnode.dual_rotateR
code: theorem dual_rotateR (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (rotateR l x r) = rotateL (dual r) x (dual l) 
goal: (l.rotateR x r).dual = r.dual.rotateL x l.dual

full_name: Ordnode.dual_balance'
code: theorem dual_balance' (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balance' l x r) = balance' (dual r) x (dual l) 
goal: (l.balance' x r).dual = r.dual.balance' x l.dual

full_name: Ordnode.dual_balanceL
code: theorem dual_balanceL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceL l x r) = balanceR (dual r) x (dual l) 
goal: (l.balanceL x r).dual = r.dual.balanceR x l.dual

full_name: Ordnode.dual_balanceR
code: theorem dual_balanceR (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceR l x r) = balanceL (dual r) x (dual l) 
goal: (l.balanceR x r).dual = r.dual.balanceL x l.dual

full_name: Ordnode.Sized.node3L
code: theorem Sized.node3L {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node3L l x m y r) 
goal: (l.node3L x m y r).Sized

full_name: Ordnode.Sized.node3R
code: theorem Sized.node3R {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node3R l x m y r) 
goal: (l.node3R x m y r).Sized

full_name: Ordnode.Sized.node4L
code: theorem Sized.node4L {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node4L l x m y r) 
goal: (l.node4L x m y r).Sized

full_name: Ordnode.node3L_size
code: theorem node3L_size {l x m y r} : size (@node3L α l x m y r) = size l + size m + size r + 2 
goal: (l.node3L x m y r).size = l.size + m.size + r.size + 2

full_name: Ordnode.node3R_size
code: theorem node3R_size {l x m y r} : size (@node3R α l x m y r) = size l + size m + size r + 2 
goal: (l.node3R x m y r).size = l.size + m.size + r.size + 2

full_name: Ordnode.node4L_size
code: theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 
goal: (l.node4L x m y r).size = l.size + m.size + r.size + 2

full_name: Ordnode.Sized.dual
code: theorem Sized.dual : ∀ {t : Ordnode α}, Sized t → Sized (dual t)
  
goal: t.Sized → t.dual.Sized

full_name: Ordnode.Sized.dual_iff
code: theorem Sized.dual_iff {t : Ordnode α} : Sized (.dual t) ↔ Sized t 
goal: t.dual.Sized ↔ t.Sized

full_name: Ordnode.Sized.rotateL
code: theorem Sized.rotateL {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateL l x r) 
goal: (l.rotateL x r).Sized

full_name: Ordnode.Sized.rotateR
code: theorem Sized.rotateR {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateR l x r) 
goal: (l.rotateR x r).Sized

full_name: Ordnode.Sized.rotateL_size
code: theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 
goal: (l.rotateL x r).size = l.size + r.size + 1

full_name: Ordnode.Sized.rotateR_size
code: theorem Sized.rotateR_size {l x r} (hl : Sized l) :
    size (@Ordnode.rotateR α l x r) = size l + size r + 1 
goal: (l.rotateR x r).size = l.size + r.size + 1

full_name: Ordnode.Sized.balance'
code: theorem Sized.balance' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (balance' l x r) 
goal: (l.balance' x r).Sized

full_name: Ordnode.size_balance'
code: theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 
goal: (l.balance' x r).size = l.size + r.size + 1

full_name: Ordnode.All.imp
code: theorem All.imp {P Q : α → Prop} (H : ∀ a, P a → Q a) : ∀ {t}, All P t → All Q t
  
goal: Ordnode.All P t → Ordnode.All Q t

full_name: Ordnode.Any.imp
code: theorem Any.imp {P Q : α → Prop} (H : ∀ a, P a → Q a) : ∀ {t}, Any P t → Any Q t
  
goal: Ordnode.Any P t → Ordnode.Any Q t

full_name: Ordnode.all_singleton
code: theorem all_singleton {P : α → Prop} {x : α} : All P (singleton x) ↔ P x 
goal: Ordnode.All P {x} ↔ P x

full_name: Ordnode.any_singleton
code: theorem any_singleton {P : α → Prop} {x : α} : Any P (singleton x) ↔ P x 
goal: Ordnode.Any P {x} ↔ P x

full_name: Ordnode.all_dual
code: theorem all_dual {P : α → Prop} : ∀ {t : Ordnode α}, All P (dual t) ↔ All P t
  
goal: Ordnode.All P t.dual ↔ Ordnode.All P t

full_name: Ordnode.all_iff_forall
code: theorem all_iff_forall {P : α → Prop} : ∀ {t}, All P t ↔ ∀ x, Emem x t → P x
  
goal: Ordnode.All P t ↔ ∀ (x : α), Ordnode.Emem x t → P x

full_name: Ordnode.any_iff_exists
code: theorem any_iff_exists {P : α → Prop} : ∀ {t}, Any P t ↔ ∃ x, Emem x t ∧ P x
  
goal: Ordnode.Any P t ↔ ∃ x, Ordnode.Emem x t ∧ P x

full_name: Ordnode.emem_iff_all
code: theorem emem_iff_all {x : α} {t} : Emem x t ↔ ∀ P, All P t → P x 
goal: Ordnode.Emem x t ↔ ∀ (P : α → Prop), Ordnode.All P t → P x

full_name: Ordnode.all_node'
code: theorem all_node' {P l x r} : @All α P (node' l x r) ↔ All P l ∧ P x ∧ All P r 
goal: Ordnode.All P (l.node' x r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P r

full_name: Ordnode.all_node3L
code: theorem all_node3L {P l x m y r} :
    @All α P (node3L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r 
goal: Ordnode.All P (l.node3L x m y r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P m ∧ P y ∧ Ordnode.All P r

full_name: Ordnode.all_node3R
code: theorem all_node3R {P l x m y r} :
    @All α P (node3R l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r 
goal: Ordnode.All P (l.node3R x m y r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P m ∧ P y ∧ Ordnode.All P r

full_name: Ordnode.all_node4L
code: theorem all_node4L {P l x m y r} :
    @All α P (node4L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r 
goal: Ordnode.All P (l.node4L x m y r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P m ∧ P y ∧ Ordnode.All P r

full_name: Ordnode.all_node4R
code: theorem all_node4R {P l x m y r} :
    @All α P (node4R l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r 
goal: Ordnode.All P (l.node4R x m y r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P m ∧ P y ∧ Ordnode.All P r

full_name: Ordnode.all_rotateL
code: theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r 
goal: Ordnode.All P (l.rotateL x r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P r

full_name: Ordnode.all_rotateR
code: theorem all_rotateR {P l x r} : @All α P (rotateR l x r) ↔ All P l ∧ P x ∧ All P r 
goal: Ordnode.All P (l.rotateR x r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P r

full_name: Ordnode.all_balance'
code: theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r 
goal: Ordnode.All P (l.balance' x r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P r

full_name: Ordnode.foldr_cons_eq_toList
code: theorem foldr_cons_eq_toList : ∀ (t : Ordnode α) (r : List α), t.foldr List.cons r = toList t ++ r
  
goal: Ordnode.foldr List.cons t r = t.toList ++ r

full_name: Ordnode.toList_nil
code: @[simp]
theorem toList_nil : toList (@nil α) = [] 
goal: Ordnode.nil.toList = []

full_name: Ordnode.toList_node
code: @[simp]
theorem toList_node (s l x r) : toList (@node α s l x r) = toList l ++ x :: toList r 
goal: (Ordnode.node s l x r).toList = l.toList ++ x :: r.toList

full_name: Ordnode.emem_iff_mem_toList
code: theorem emem_iff_mem_toList {x : α} {t} : Emem x t ↔ x ∈ toList t 
goal: Ordnode.Emem x t ↔ x ∈ t.toList

full_name: Ordnode.length_toList'
code: theorem length_toList' : ∀ t : Ordnode α, (toList t).length = t.realSize
  
goal: t.toList.length = t.realSize

full_name: Ordnode.length_toList
code: theorem length_toList {t : Ordnode α} (h : Sized t) : (toList t).length = t.size 
goal: t.toList.length = t.size

full_name: Ordnode.equiv_iff
code: theorem equiv_iff {t₁ t₂ : Ordnode α} (h₁ : Sized t₁) (h₂ : Sized t₂) :
    Equiv t₁ t₂ ↔ toList t₁ = toList t₂ 
goal: t₁.Equiv t₂ ↔ t₁.toList = t₂.toList

full_name: Ordnode.pos_size_of_mem
code: theorem pos_size_of_mem [LE α] [@DecidableRel α (· ≤ ·)] {x : α} {t : Ordnode α} (h : Sized t)
    (h_mem : x ∈ t) : 0 < size t 
goal: 0 < t.size

full_name: Ordnode.findMin'_dual
code: theorem findMin'_dual : ∀ (t) (x : α), findMin' (dual t) x = findMax' x t
  
goal: t.dual.findMin' x = Ordnode.findMax' x t

full_name: Ordnode.findMax'_dual
code: theorem findMax'_dual (t) (x : α) : findMax' x (dual t) = findMin' t x 
goal: Ordnode.findMax' x t.dual = t.findMin' x

full_name: Ordnode.findMin_dual
code: theorem findMin_dual : ∀ t : Ordnode α, findMin (dual t) = findMax t
  
goal: t.dual.findMin = t.findMax

full_name: Ordnode.findMax_dual
code: theorem findMax_dual (t : Ordnode α) : findMax (dual t) = findMin t 
goal: t.dual.findMax = t.findMin

full_name: Ordnode.dual_eraseMin
code: theorem dual_eraseMin : ∀ t : Ordnode α, dual (eraseMin t) = eraseMax (dual t)
  
goal: t.eraseMin.dual = t.dual.eraseMax

full_name: Ordnode.dual_eraseMax
code: theorem dual_eraseMax (t : Ordnode α) : dual (eraseMax t) = eraseMin (dual t) 
goal: t.eraseMax.dual = t.dual.eraseMin

full_name: Ordnode.splitMin_eq
code: theorem splitMin_eq :
    ∀ (s l) (x : α) (r), splitMin' l x r = (findMin' l x, eraseMin (node s l x r))
  
goal: l.splitMin' x r = (l.findMin' x, (Ordnode.node s l x r).eraseMin)

full_name: Ordnode.splitMax_eq
code: theorem splitMax_eq :
    ∀ (s l) (x : α) (r), splitMax' l x r = (eraseMax (node s l x r), findMax' x r)
  
goal: l.splitMax' x r = ((Ordnode.node s l x r).eraseMax, Ordnode.findMax' x r)

full_name: Ordnode.findMin'_all
code: theorem findMin'_all {P : α → Prop} : ∀ (t) (x : α), All P t → P x → P (findMin' t x)
  
goal: Ordnode.All P t → P x → P (t.findMin' x)

full_name: Ordnode.findMax'_all
code: theorem findMax'_all {P : α → Prop} : ∀ (x : α) (t), P x → All P t → P (findMax' x t)
  
goal: P x → Ordnode.All P t → P (Ordnode.findMax' x t)

full_name: Ordnode.merge_nil_left
code: @[simp]
theorem merge_nil_left (t : Ordnode α) : merge t nil = t 
goal: t.merge Ordnode.nil = t

full_name: Ordnode.merge_nil_right
code: @[simp]
theorem merge_nil_right (t : Ordnode α) : merge nil t = t 
goal: Ordnode.nil.merge t = t

full_name: Ordnode.merge_node
code: @[simp]
theorem merge_node {ls ll lx lr rs rl rx rr} :
    merge (@node α ls ll lx lr) (node rs rl rx rr) =
      if delta * ls < rs then balanceL (merge (node ls ll lx lr) rl) rx rr
      else if delta * rs < ls then balanceR ll lx (merge lr (node rs rl rx rr))
      else glue (node ls ll lx lr) (node rs rl rx rr) 
goal: (Ordnode.node ls ll lx lr).merge (Ordnode.node rs rl rx rr) =
  if Ordnode.delta * ls < rs then ((Ordnode.node ls ll lx lr).merge rl).balanceL rx rr
  else
    if Ordnode.delta * rs < ls then ll.balanceR lx (lr.merge (Ordnode.node rs rl rx rr))
    else (Ordnode.node ls ll lx lr).glue (Ordnode.node rs rl rx rr)

full_name: Ordnode.dual_insert
code: theorem dual_insert [Preorder α] [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t : Ordnode α, dual (Ordnode.insert x t) = @Ordnode.insert αᵒᵈ _ _ x (dual t)
  
goal: (Ordnode.insert x t).dual = Ordnode.insert x t.dual

full_name: Ordnode.balance_eq_balance'
code: theorem balance_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l)
    (sr : Sized r) : @balance α l x r = balance' l x r 
goal: l.balance x r = l.balance' x r

full_name: Ordnode.balanceL_eq_balance
code: theorem balanceL_eq_balance {l x r} (sl : Sized l) (sr : Sized r) (H1 : size l = 0 → size r ≤ 1)
    (H2 : 1 ≤ size l → 1 ≤ size r → size r ≤ delta * size l) :
    @balanceL α l x r = balance l x r 
goal: l.balanceL x r = l.balance x r

full_name: Ordnode.Raised
code: /-- `Raised n m` means `m` is either equal or one up from `n`. -/
def Raised (n m : ℕ) : Prop 
goal: Prop

full_name: Ordnode.raised_iff
code: theorem raised_iff {n m} : Raised n m ↔ n ≤ m ∧ m ≤ n + 1 
goal: Ordnode.Raised n m ↔ n ≤ m ∧ m ≤ n + 1

full_name: Ordnode.Raised.dist_le
code: theorem Raised.dist_le {n m} (H : Raised n m) : Nat.dist n m ≤ 1 
goal: n.dist m ≤ 1

full_name: Ordnode.Raised.dist_le'
code: theorem Raised.dist_le' {n m} (H : Raised n m) : Nat.dist m n ≤ 1 
goal: m.dist n ≤ 1

full_name: Ordnode.Raised.add_left
code: theorem Raised.add_left (k) {n m} (H : Raised n m) : Raised (k + n) (k + m) 
goal: Ordnode.Raised (k + n) (k + m)

full_name: Ordnode.Raised.add_right
code: theorem Raised.add_right (k) {n m} (H : Raised n m) : Raised (n + k) (m + k) 
goal: Ordnode.Raised (n + k) (m + k)

full_name: Ordnode.Raised.right
code: theorem Raised.right {l x₁ x₂ r₁ r₂} (H : Raised (size r₁) (size r₂)) :
    Raised (size (@node' α l x₁ r₁)) (size (@node' α l x₂ r₂)) 
goal: Ordnode.Raised (l.node' x₁ r₁).size (l.node' x₂ r₂).size

full_name: Ordnode.balanceL_eq_balance'
code: theorem balanceL_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l)
    (sr : Sized r)
    (H :
      (∃ l', Raised l' (size l) ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised (size r) r' ∧ BalancedSz (size l) r') :
    @balanceL α l x r = balance' l x r 
goal: l.balanceL x r = l.balance' x r

full_name: Ordnode.balance_sz_dual
code: theorem balance_sz_dual {l r}
    (H : (∃ l', Raised (@size α l) l' ∧ BalancedSz l' (@size α r)) ∨
        ∃ r', Raised r' (size r) ∧ BalancedSz (size l) r') :
    (∃ l', Raised l' (size (dual r)) ∧ BalancedSz l' (size (dual l))) ∨
      ∃ r', Raised (size (dual l)) r' ∧ BalancedSz (size (dual r)) r' 
goal: (∃ l', Ordnode.Raised l' r.dual.size ∧ Ordnode.BalancedSz l' l.dual.size) ∨
  ∃ r', Ordnode.Raised l.dual.size r' ∧ Ordnode.BalancedSz r.dual.size r'

full_name: Ordnode.size_balanceL
code: theorem size_balanceL {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l) (sr : Sized r)
    (H : (∃ l', Raised l' (size l) ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised (size r) r' ∧ BalancedSz (size l) r') :
    size (@balanceL α l x r) = size l + size r + 1 
goal: (l.balanceL x r).size = l.size + r.size + 1

full_name: Ordnode.all_balanceL
code: theorem all_balanceL {P l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l) (sr : Sized r)
    (H :
      (∃ l', Raised l' (size l) ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised (size r) r' ∧ BalancedSz (size l) r') :
    All P (@balanceL α l x r) ↔ All P l ∧ P x ∧ All P r 
goal: Ordnode.All P (l.balanceL x r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P r

full_name: Ordnode.balanceR_eq_balance'
code: theorem balanceR_eq_balance' {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l)
    (sr : Sized r)
    (H : (∃ l', Raised (size l) l' ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised r' (size r) ∧ BalancedSz (size l) r') :
    @balanceR α l x r = balance' l x r 
goal: l.balanceR x r = l.balance' x r

full_name: Ordnode.size_balanceR
code: theorem size_balanceR {l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l) (sr : Sized r)
    (H : (∃ l', Raised (size l) l' ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised r' (size r) ∧ BalancedSz (size l) r') :
    size (@balanceR α l x r) = size l + size r + 1 
goal: (l.balanceR x r).size = l.size + r.size + 1

full_name: Ordnode.all_balanceR
code: theorem all_balanceR {P l x r} (hl : Balanced l) (hr : Balanced r) (sl : Sized l) (sr : Sized r)
    (H :
      (∃ l', Raised (size l) l' ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised r' (size r) ∧ BalancedSz (size l) r') :
    All P (@balanceR α l x r) ↔ All P l ∧ P x ∧ All P r 
goal: Ordnode.All P (l.balanceR x r) ↔ Ordnode.All P l ∧ P x ∧ Ordnode.All P r

full_name: Ordnode.Bounded
code: /-- `Bounded t lo hi` says that every element `x ∈ t` is in the range `lo < x < hi`, and also this
property holds recursively in subtrees, making the full tree a BST. The bounds can be set to
`lo = ⊥` and `hi = ⊤` if we care only about the internal ordering constraints. -/
def Bounded : Ordnode α → WithBot α → WithTop α → Prop
  
goal: Ordnode α → WithBot α → WithTop α → Prop

full_name: Ordnode.Bounded.dual
code: theorem Bounded.dual :
    ∀ {t : Ordnode α} {o₁ o₂}, Bounded t o₁ o₂ → @Bounded αᵒᵈ _ (dual t) o₂ o₁
  
goal: t.Bounded o₁ o₂ → t.dual.Bounded o₂ o₁

full_name: Ordnode.Bounded.dual_iff
code: theorem Bounded.dual_iff {t : Ordnode α} {o₁ o₂} :
    Bounded t o₁ o₂ ↔ @Bounded αᵒᵈ _ (.dual t) o₂ o₁ 
goal: t.Bounded o₁ o₂ ↔ t.dual.Bounded o₂ o₁

full_name: Ordnode.Bounded.weak_left
code: theorem Bounded.weak_left : ∀ {t : Ordnode α} {o₁ o₂}, Bounded t o₁ o₂ → Bounded t ⊥ o₂
  
goal: t.Bounded o₁ o₂ → t.Bounded ⊥ o₂

full_name: Ordnode.Bounded.weak_right
code: theorem Bounded.weak_right : ∀ {t : Ordnode α} {o₁ o₂}, Bounded t o₁ o₂ → Bounded t o₁ ⊤
  
goal: t.Bounded o₁ o₂ → t.Bounded o₁ ⊤

full_name: Ordnode.Bounded.weak
code: theorem Bounded.weak {t : Ordnode α} {o₁ o₂} (h : Bounded t o₁ o₂) : Bounded t ⊥ ⊤ 
goal: t.Bounded ⊥ ⊤

full_name: Ordnode.Bounded.mono_left
code: theorem Bounded.mono_left {x y : α} (xy : x ≤ y) :
    ∀ {t : Ordnode α} {o}, Bounded t y o → Bounded t x o
  
goal: t.Bounded (↑y) o → t.Bounded (↑x) o

full_name: Ordnode.Bounded.mono_right
code: theorem Bounded.mono_right {x y : α} (xy : x ≤ y) :
    ∀ {t : Ordnode α} {o}, Bounded t o x → Bounded t o y
  
goal: t.Bounded o ↑x → t.Bounded o ↑y

full_name: Ordnode.Bounded.to_lt
code: theorem Bounded.to_lt : ∀ {t : Ordnode α} {x y : α}, Bounded t x y → x < y
  
goal: t.Bounded ↑x ↑y → x < y

full_name: Ordnode.Bounded.to_nil
code: theorem Bounded.to_nil {t : Ordnode α} : ∀ {o₁ o₂}, Bounded t o₁ o₂ → Bounded nil o₁ o₂
  
goal: t.Bounded o₁ o₂ → Ordnode.nil.Bounded o₁ o₂

full_name: Ordnode.Bounded.trans_left
code: theorem Bounded.trans_left {t₁ t₂ : Ordnode α} {x : α} :
    ∀ {o₁ o₂}, Bounded t₁ o₁ x → Bounded t₂ x o₂ → Bounded t₂ o₁ o₂
  
goal: t₁.Bounded o₁ ↑x → t₂.Bounded (↑x) o₂ → t₂.Bounded o₁ o₂

full_name: Ordnode.Bounded.trans_right
code: theorem Bounded.trans_right {t₁ t₂ : Ordnode α} {x : α} :
    ∀ {o₁ o₂}, Bounded t₁ o₁ x → Bounded t₂ x o₂ → Bounded t₁ o₁ o₂
  
goal: t₁.Bounded o₁ ↑x → t₂.Bounded (↑x) o₂ → t₁.Bounded o₁ o₂

full_name: Ordnode.Bounded.mem_lt
code: theorem Bounded.mem_lt : ∀ {t o} {x : α}, Bounded t o x → All (· < x) t
  
goal: t.Bounded o ↑x → Ordnode.All (fun x_1 => x_1 < x) t

full_name: Ordnode.Bounded.mem_gt
code: theorem Bounded.mem_gt : ∀ {t o} {x : α}, Bounded t x o → All (· > x) t
  
goal: t.Bounded (↑x) o → Ordnode.All (fun x_1 => x_1 > x) t

full_name: Ordnode.Bounded.of_lt
code: theorem Bounded.of_lt :
    ∀ {t o₁ o₂} {x : α}, Bounded t o₁ o₂ → Bounded nil o₁ x → All (· < x) t → Bounded t o₁ x
  
goal: t.Bounded o₁ o₂ → Ordnode.nil.Bounded o₁ ↑x → Ordnode.All (fun x_1 => x_1 < x) t → t.Bounded o₁ ↑x

full_name: Ordnode.Bounded.of_gt
code: theorem Bounded.of_gt :
    ∀ {t o₁ o₂} {x : α}, Bounded t o₁ o₂ → Bounded nil x o₂ → All (· > x) t → Bounded t x o₂
  
goal: t.Bounded o₁ o₂ → Ordnode.nil.Bounded (↑x) o₂ → Ordnode.All (fun x_1 => x_1 > x) t → t.Bounded (↑x) o₂

full_name: Ordnode.Bounded.to_sep
code: theorem Bounded.to_sep {t₁ t₂ o₁ o₂} {x : α}
    (h₁ : Bounded t₁ o₁ (x : WithTop α)) (h₂ : Bounded t₂ (x : WithBot α) o₂) :
    t₁.All fun y => t₂.All fun z : α => y < z 
goal: Ordnode.All (fun y => Ordnode.All (fun z => y < z) t₂) t₁

full_name: Ordnode.Valid'.ord
code: /-- The validity predicate for an `Ordnode` subtree. This asserts that the `size` fields are
correct, the tree is balanced, and the elements of the tree are organized according to the
ordering. This version of `Valid` also puts all elements in the tree in the interval `(lo, hi)`. -/
structure Valid' (lo : WithBot α) (t : Ordnode α) (hi : WithTop α) : Prop where
  ord : t.Bounded lo hi
  sz : t.Sized
  bal : t.Balanced
goal: t.Bounded lo hi

full_name: Ordnode.Valid'
code: /-- The validity predicate for an `Ordnode` subtree. This asserts that the `size` fields are
correct, the tree is balanced, and the elements of the tree are organized according to the
ordering. This version of `Valid` also puts all elements in the tree in the interval `(lo, hi)`. -/
structure Valid' (lo : WithBot α) (t : Ordnode α) (hi : WithTop α) : Prop where
  ord : t.Bounded lo hi
  sz : t.Sized
  bal : t.Balanced
goal: Prop

full_name: Ordnode.Valid'.bal
code: /-- The validity predicate for an `Ordnode` subtree. This asserts that the `size` fields are
correct, the tree is balanced, and the elements of the tree are organized according to the
ordering. This version of `Valid` also puts all elements in the tree in the interval `(lo, hi)`. -/
structure Valid' (lo : WithBot α) (t : Ordnode α) (hi : WithTop α) : Prop where
  ord : t.Bounded lo hi
  sz : t.Sized
  bal : t.Balanced
goal: t.Balanced

full_name: Ordnode.Valid'.sz
code: /-- The validity predicate for an `Ordnode` subtree. This asserts that the `size` fields are
correct, the tree is balanced, and the elements of the tree are organized according to the
ordering. This version of `Valid` also puts all elements in the tree in the interval `(lo, hi)`. -/
structure Valid' (lo : WithBot α) (t : Ordnode α) (hi : WithTop α) : Prop where
  ord : t.Bounded lo hi
  sz : t.Sized
  bal : t.Balanced
goal: t.Sized

full_name: Ordnode.Valid
code: /-- The validity predicate for an `Ordnode` subtree. This asserts that the `size` fields are
correct, the tree is balanced, and the elements of the tree are organized according to the
ordering. -/
def Valid (t : Ordnode α) : Prop 
goal: Prop

full_name: Ordnode.Valid'.mono_left
code: theorem Valid'.mono_left {x y : α} (xy : x ≤ y) {t : Ordnode α} {o} (h : Valid' y t o) :
    Valid' x t o 
goal: Ordnode.Valid' (↑x) t o

full_name: Ordnode.Valid'.mono_right
code: theorem Valid'.mono_right {x y : α} (xy : x ≤ y) {t : Ordnode α} {o} (h : Valid' o t x) :
    Valid' o t y 
goal: Ordnode.Valid' o t ↑y

full_name: Ordnode.Valid'.trans_left
code: theorem Valid'.trans_left {t₁ t₂ : Ordnode α} {x : α} {o₁ o₂} (h : Bounded t₁ o₁ x)
    (H : Valid' x t₂ o₂) : Valid' o₁ t₂ o₂ 
goal: Ordnode.Valid' o₁ t₂ o₂

full_name: Ordnode.Valid'.trans_right
code: theorem Valid'.trans_right {t₁ t₂ : Ordnode α} {x : α} {o₁ o₂} (H : Valid' o₁ t₁ x)
    (h : Bounded t₂ x o₂) : Valid' o₁ t₁ o₂ 
goal: Ordnode.Valid' o₁ t₁ o₂

full_name: Ordnode.Valid'.of_lt
code: theorem Valid'.of_lt {t : Ordnode α} {x : α} {o₁ o₂} (H : Valid' o₁ t o₂) (h₁ : Bounded nil o₁ x)
    (h₂ : All (· < x) t) : Valid' o₁ t x 
goal: Ordnode.Valid' o₁ t ↑x

full_name: Ordnode.Valid'.of_gt
code: theorem Valid'.of_gt {t : Ordnode α} {x : α} {o₁ o₂} (H : Valid' o₁ t o₂) (h₁ : Bounded nil x o₂)
    (h₂ : All (· > x) t) : Valid' x t o₂ 
goal: Ordnode.Valid' (↑x) t o₂

full_name: Ordnode.Valid'.valid
code: theorem Valid'.valid {t o₁ o₂} (h : @Valid' α _ o₁ t o₂) : Valid t 
goal: t.Valid

full_name: Ordnode.valid'_nil
code: theorem valid'_nil {o₁ o₂} (h : Bounded nil o₁ o₂) : Valid' o₁ (@nil α) o₂ 
goal: Ordnode.Valid' o₁ Ordnode.nil o₂

full_name: Ordnode.valid_nil
code: theorem valid_nil : Valid (@nil α) 
goal: Ordnode.nil.Valid

full_name: Ordnode.Valid'.node
code: theorem Valid'.node {s l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H : BalancedSz (size l) (size r)) (hs : s = size l + size r + 1) :
    Valid' o₁ (@node α s l x r) o₂ 
goal: Ordnode.Valid' o₁ (Ordnode.node s l x r) o₂

full_name: Ordnode.Valid'.dual
code: theorem Valid'.dual : ∀ {t : Ordnode α} {o₁ o₂}, Valid' o₁ t o₂ → @Valid' αᵒᵈ _ o₂ (dual t) o₁
  
goal: Ordnode.Valid' o₁ t o₂ → Ordnode.Valid' o₂ t.dual o₁

full_name: Ordnode.Valid'.dual_iff
code: theorem Valid'.dual_iff {t : Ordnode α} {o₁ o₂} : Valid' o₁ t o₂ ↔ @Valid' αᵒᵈ _ o₂ (.dual t) o₁ 
goal: Ordnode.Valid' o₁ t o₂ ↔ Ordnode.Valid' o₂ t.dual o₁

full_name: Ordnode.Valid.dual
code: theorem Valid.dual {t : Ordnode α} : Valid t → @Valid αᵒᵈ _ (.dual t) 
goal: t.Valid → t.dual.Valid

full_name: Ordnode.Valid.dual_iff
code: theorem Valid.dual_iff {t : Ordnode α} : Valid t ↔ @Valid αᵒᵈ _ (.dual t) 
goal: t.Valid ↔ t.dual.Valid

full_name: Ordnode.Valid'.left
code: theorem Valid'.left {s l x r o₁ o₂} (H : Valid' o₁ (@Ordnode.node α s l x r) o₂) : Valid' o₁ l x 
goal: Ordnode.Valid' o₁ l ↑x

full_name: Ordnode.Valid'.right
code: theorem Valid'.right {s l x r o₁ o₂} (H : Valid' o₁ (@Ordnode.node α s l x r) o₂) : Valid' x r o₂ 
goal: Ordnode.Valid' (↑x) r o₂

full_name: Ordnode.Valid.left
code: nonrec theorem Valid.left {s l x r} (H : Valid (@node α s l x r)) : Valid l 
goal: l.Valid

full_name: Ordnode.Valid.right
code: nonrec theorem Valid.right {s l x r} (H : Valid (@node α s l x r)) : Valid r 
goal: r.Valid

full_name: Ordnode.Valid.size_eq
code: theorem Valid.size_eq {s l x r} (H : Valid (@node α s l x r)) :
    size (@node α s l x r) = size l + size r + 1 
goal: (Ordnode.node s l x r).size = l.size + r.size + 1

full_name: Ordnode.Valid'.node'
code: theorem Valid'.node' {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H : BalancedSz (size l) (size r)) : Valid' o₁ (@node' α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.node' x r) o₂

full_name: Ordnode.valid'_singleton
code: theorem valid'_singleton {x : α} {o₁ o₂} (h₁ : Bounded nil o₁ x) (h₂ : Bounded nil x o₂) :
    Valid' o₁ (singleton x : Ordnode α) o₂ 
goal: Ordnode.Valid' o₁ {x} o₂

full_name: Ordnode.valid_singleton
code: theorem valid_singleton {x : α} : Valid (singleton x : Ordnode α) 
goal: {x}.Valid

full_name: Ordnode.Valid'.node3L
code: theorem Valid'.node3L {l} {x : α} {m} {y : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hm : Valid' x m y)
    (hr : Valid' y r o₂) (H1 : BalancedSz (size l) (size m))
    (H2 : BalancedSz (size l + size m + 1) (size r)) : Valid' o₁ (@node3L α l x m y r) o₂ 
goal: Ordnode.Valid' o₁ (l.node3L x m y r) o₂

full_name: Ordnode.Valid'.node3R
code: theorem Valid'.node3R {l} {x : α} {m} {y : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hm : Valid' x m y)
    (hr : Valid' y r o₂) (H1 : BalancedSz (size l) (size m + size r + 1))
    (H2 : BalancedSz (size m) (size r)) : Valid' o₁ (@node3R α l x m y r) o₂ 
goal: Ordnode.Valid' o₁ (l.node3R x m y r) o₂

full_name: Ordnode.Valid'.node4L_lemma₁
code: theorem Valid'.node4L_lemma₁ {a b c d : ℕ} (lr₂ : 3 * (b + c + 1 + d) ≤ 16 * a + 9)
    (mr₂ : b + c + 1 ≤ 3 * d) (mm₁ : b ≤ 3 * c) : b < 3 * a + 1 
goal: b < 3 * a + 1

full_name: Ordnode.Valid'.node4L_lemma₂
code: theorem Valid'.node4L_lemma₂ {b c d : ℕ} (mr₂ : b + c + 1 ≤ 3 * d) : c ≤ 3 * d 
goal: c ≤ 3 * d

full_name: Ordnode.Valid'.node4L_lemma₃
code: theorem Valid'.node4L_lemma₃ {b c d : ℕ} (mr₁ : 2 * d ≤ b + c + 1) (mm₁ : b ≤ 3 * c) :
    d ≤ 3 * c 
goal: d ≤ 3 * c

full_name: Ordnode.Valid'.node4L_lemma₄
code: theorem Valid'.node4L_lemma₄ {a b c d : ℕ} (lr₁ : 3 * a ≤ b + c + 1 + d) (mr₂ : b + c + 1 ≤ 3 * d)
    (mm₁ : b ≤ 3 * c) : a + b + 1 ≤ 3 * (c + d + 1) 
goal: a + b + 1 ≤ 3 * (c + d + 1)

full_name: Ordnode.Valid'.node4L_lemma₅
code: theorem Valid'.node4L_lemma₅ {a b c d : ℕ} (lr₂ : 3 * (b + c + 1 + d) ≤ 16 * a + 9)
    (mr₁ : 2 * d ≤ b + c + 1) (mm₂ : c ≤ 3 * b) : c + d + 1 ≤ 3 * (a + b + 1) 
goal: c + d + 1 ≤ 3 * (a + b + 1)

full_name: Ordnode.Valid'.node4L
code: theorem Valid'.node4L {l} {x : α} {m} {y : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hm : Valid' x m y)
    (hr : Valid' (↑y) r o₂) (Hm : 0 < size m)
    (H : size l = 0 ∧ size m = 1 ∧ size r ≤ 1 ∨
        0 < size l ∧
          ratio * size r ≤ size m ∧
            delta * size l ≤ size m + size r ∧
              3 * (size m + size r) ≤ 16 * size l + 9 ∧ size m ≤ delta * size r) :
    Valid' o₁ (@node4L α l x m y r) o₂ 
goal: Ordnode.Valid' o₁ (l.node4L x m y r) o₂

full_name: Ordnode.Valid'.rotateL_lemma₁
code: theorem Valid'.rotateL_lemma₁ {a b c : ℕ} (H2 : 3 * a ≤ b + c) (hb₂ : c ≤ 3 * b) : a ≤ 3 * b 
goal: a ≤ 3 * b

full_name: Ordnode.Valid'.rotateL_lemma₂
code: theorem Valid'.rotateL_lemma₂ {a b c : ℕ} (H3 : 2 * (b + c) ≤ 9 * a + 3) (h : b < 2 * c) :
    b < 3 * a + 1 
goal: b < 3 * a + 1

full_name: Ordnode.Valid'.rotateL_lemma₃
code: theorem Valid'.rotateL_lemma₃ {a b c : ℕ} (H2 : 3 * a ≤ b + c) (h : b < 2 * c) : a + b < 3 * c 
goal: a + b < 3 * c

full_name: Ordnode.Valid'.rotateL_lemma₄
code: theorem Valid'.rotateL_lemma₄ {a b : ℕ} (H3 : 2 * b ≤ 9 * a + 3) : 3 * b ≤ 16 * a + 9 
goal: 3 * b ≤ 16 * a + 9

full_name: Ordnode.Valid'.rotateL
code: theorem Valid'.rotateL {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H1 : ¬size l + size r ≤ 1) (H2 : delta * size l < size r)
    (H3 : 2 * size r ≤ 9 * size l + 5 ∨ size r ≤ 3) : Valid' o₁ (@rotateL α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.rotateL x r) o₂

full_name: Ordnode.Valid'.rotateR
code: theorem Valid'.rotateR {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H1 : ¬size l + size r ≤ 1) (H2 : delta * size r < size l)
    (H3 : 2 * size l ≤ 9 * size r + 5 ∨ size l ≤ 3) : Valid' o₁ (@rotateR α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.rotateR x r) o₂

full_name: Ordnode.Valid'.balance'_aux
code: theorem Valid'.balance'_aux {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H₁ : 2 * @size α r ≤ 9 * size l + 5 ∨ size r ≤ 3)
    (H₂ : 2 * @size α l ≤ 9 * size r + 5 ∨ size l ≤ 3) : Valid' o₁ (@balance' α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balance' x r) o₂

full_name: Ordnode.Valid'.balance'_lemma
code: theorem Valid'.balance'_lemma {α l l' r r'} (H1 : BalancedSz l' r')
    (H2 : Nat.dist (@size α l) l' ≤ 1 ∧ size r = r' ∨ Nat.dist (size r) r' ≤ 1 ∧ size l = l') :
    2 * @size α r ≤ 9 * size l + 5 ∨ size r ≤ 3 
goal: 2 * r.size ≤ 9 * l.size + 5 ∨ r.size ≤ 3

full_name: Ordnode.Valid'.balance'
code: theorem Valid'.balance' {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H : ∃ l' r', BalancedSz l' r' ∧
          (Nat.dist (size l) l' ≤ 1 ∧ size r = r' ∨ Nat.dist (size r) r' ≤ 1 ∧ size l = l')) :
    Valid' o₁ (@balance' α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balance' x r) o₂

full_name: Ordnode.Valid'.balance
code: theorem Valid'.balance {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H : ∃ l' r', BalancedSz l' r' ∧
          (Nat.dist (size l) l' ≤ 1 ∧ size r = r' ∨ Nat.dist (size r) r' ≤ 1 ∧ size l = l')) :
    Valid' o₁ (@balance α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balance x r) o₂

full_name: Ordnode.Valid'.balanceL_aux
code: theorem Valid'.balanceL_aux {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H₁ : size l = 0 → size r ≤ 1) (H₂ : 1 ≤ size l → 1 ≤ size r → size r ≤ delta * size l)
    (H₃ : 2 * @size α l ≤ 9 * size r + 5 ∨ size l ≤ 3) : Valid' o₁ (@balanceL α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balanceL x r) o₂

full_name: Ordnode.Valid'.balanceL
code: theorem Valid'.balanceL {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H : (∃ l', Raised l' (size l) ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised (size r) r' ∧ BalancedSz (size l) r') :
    Valid' o₁ (@balanceL α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balanceL x r) o₂

full_name: Ordnode.Valid'.balanceR_aux
code: theorem Valid'.balanceR_aux {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H₁ : size r = 0 → size l ≤ 1) (H₂ : 1 ≤ size r → 1 ≤ size l → size l ≤ delta * size r)
    (H₃ : 2 * @size α r ≤ 9 * size l + 5 ∨ size r ≤ 3) : Valid' o₁ (@balanceR α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balanceR x r) o₂

full_name: Ordnode.Valid'.balanceR
code: theorem Valid'.balanceR {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂)
    (H : (∃ l', Raised (size l) l' ∧ BalancedSz l' (size r)) ∨
        ∃ r', Raised r' (size r) ∧ BalancedSz (size l) r') :
    Valid' o₁ (@balanceR α l x r) o₂ 
goal: Ordnode.Valid' o₁ (l.balanceR x r) o₂

full_name: Ordnode.Valid'.eraseMax_aux
code: theorem Valid'.eraseMax_aux {s l x r o₁ o₂} (H : Valid' o₁ (.node s l x r) o₂) :
    Valid' o₁ (@eraseMax α (.node' l x r)) ↑(findMax' x r) ∧
      size (.node' l x r) = size (eraseMax (.node' l x r)) + 1 
goal: Ordnode.Valid' o₁ (l.node' x r).eraseMax ↑(Ordnode.findMax' x r) ∧ (l.node' x r).size = (l.node' x r).eraseMax.size + 1

full_name: Ordnode.Valid'.eraseMin_aux
code: theorem Valid'.eraseMin_aux {s l} {x : α} {r o₁ o₂} (H : Valid' o₁ (.node s l x r) o₂) :
    Valid' ↑(findMin' l x) (@eraseMin α (.node' l x r)) o₂ ∧
      size (.node' l x r) = size (eraseMin (.node' l x r)) + 1 
goal: Ordnode.Valid' (↑(l.findMin' x)) (l.node' x r).eraseMin o₂ ∧ (l.node' x r).size = (l.node' x r).eraseMin.size + 1

full_name: Ordnode.eraseMin.valid
code: theorem eraseMin.valid : ∀ {t}, @Valid α _ t → Valid (eraseMin t)
  
goal: t.Valid → t.eraseMin.Valid

full_name: Ordnode.eraseMax.valid
code: theorem eraseMax.valid {t} (h : @Valid α _ t) : Valid (eraseMax t) 
goal: t.eraseMax.Valid

full_name: Ordnode.Valid'.glue_aux
code: theorem Valid'.glue_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) (bal : BalancedSz (size l) (size r)) :
    Valid' o₁ (@glue α l r) o₂ ∧ size (glue l r) = size l + size r 
goal: Ordnode.Valid' o₁ (l.glue r) o₂ ∧ (l.glue r).size = l.size + r.size

full_name: Ordnode.Valid'.glue
code: theorem Valid'.glue {l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Valid' x r o₂) :
    BalancedSz (size l) (size r) →
      Valid' o₁ (@glue α l r) o₂ ∧ size (@glue α l r) = size l + size r 
goal: Ordnode.BalancedSz l.size r.size → Ordnode.Valid' o₁ (l.glue r) o₂ ∧ (l.glue r).size = l.size + r.size

full_name: Ordnode.Valid'.merge_lemma
code: theorem Valid'.merge_lemma {a b c : ℕ} (h₁ : 3 * a < b + c + 1) (h₂ : b ≤ 3 * c) :
    2 * (a + b) ≤ 9 * c + 5 
goal: 2 * (a + b) ≤ 9 * c + 5

full_name: Ordnode.Valid'.merge_aux₁
code: theorem Valid'.merge_aux₁ {o₁ o₂ ls ll lx lr rs rl rx rr t}
    (hl : Valid' o₁ (@Ordnode.node α ls ll lx lr) o₂) (hr : Valid' o₁ (.node rs rl rx rr) o₂)
    (h : delta * ls < rs) (v : Valid' o₁ t rx) (e : size t = ls + size rl) :
    Valid' o₁ (.balanceL t rx rr) o₂ ∧ size (.balanceL t rx rr) = ls + rs 
goal: Ordnode.Valid' o₁ (t.balanceL rx rr) o₂ ∧ (t.balanceL rx rr).size = ls + rs

full_name: Ordnode.Valid'.merge_aux
code: theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r 
goal: Ordnode.Valid' o₁ (l.merge r) o₂ ∧ (l.merge r).size = l.size + r.size

full_name: Ordnode.Valid.merge
code: theorem Valid.merge {l r} (hl : Valid l) (hr : Valid r)
    (sep : l.All fun x => r.All fun y => x < y) : Valid (@merge α l r) 
goal: (l.merge r).Valid

full_name: Ordnode.insertWith.valid_aux
code: theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  
goal: Ordnode.Valid' o₁ t o₂ →
  Ordnode.nil.Bounded o₁ ↑x →
    Ordnode.nil.Bounded (↑x) o₂ →
      Ordnode.Valid' o₁ (Ordnode.insertWith f x t) o₂ ∧ Ordnode.Raised t.size (Ordnode.insertWith f x t).size

full_name: Ordnode.insertWith.valid
code: theorem insertWith.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) {t} (h : Valid t) : Valid (insertWith f x t) 
goal: (Ordnode.insertWith f x t).Valid

full_name: Ordnode.insert_eq_insertWith
code: theorem insert_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Ordnode.insert x t = insertWith (fun _ => x) x t
  
goal: Ordnode.insert x t = Ordnode.insertWith (fun x_1 => x) x t

full_name: Ordnode.insert.valid
code: theorem insert.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) :
    Valid (Ordnode.insert x t) 
goal: (Ordnode.insert x t).Valid

full_name: Ordnode.insert'_eq_insertWith
code: theorem insert'_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, insert' x t = insertWith id x t
  
goal: Ordnode.insert' x t = Ordnode.insertWith id x t

full_name: Ordnode.insert'.valid
code: theorem insert'.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) :
    Valid (insert' x t) 
goal: (Ordnode.insert' x t).Valid

full_name: Ordnode.Valid'.map_aux
code: theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size 
goal: Ordnode.Valid' (Option.map f a₁) (Ordnode.map f t) (Option.map f a₂) ∧ (Ordnode.map f t).size = t.size

full_name: Ordnode.map.valid
code: theorem map.valid {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t} (h : Valid t) :
    Valid (map f t) 
goal: (Ordnode.map f t).Valid

full_name: Ordnode.Valid'.erase_aux
code: theorem Valid'.erase_aux [@DecidableRel α (· ≤ ·)] (x : α) {t a₁ a₂} (h : Valid' a₁ t a₂) :
    Valid' a₁ (erase x t) a₂ ∧ Raised (erase x t).size t.size 
goal: Ordnode.Valid' a₁ (Ordnode.erase x t) a₂ ∧ Ordnode.Raised (Ordnode.erase x t).size t.size

full_name: Ordnode.erase.valid
code: theorem erase.valid [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) : Valid (erase x t) 
goal: (Ordnode.erase x t).Valid

full_name: Ordnode.size_erase_of_mem
code: theorem size_erase_of_mem [@DecidableRel α (· ≤ ·)] {x : α} {t a₁ a₂} (h : Valid' a₁ t a₂)
    (h_mem : x ∈ t) : size (erase x t) = size t - 1 
goal: (Ordnode.erase x t).size = t.size - 1

full_name: Ordset
code: /-- An `Ordset α` 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. The
correctness property of the tree is baked into the type, so all operations on this type are correct
by construction. -/
def Ordset (α : Type*) [Preorder α] 
goal: Type u_2

full_name: Ordset.nil
code: /-- O(1). The empty set. -/
nonrec def nil : Ordset α 
goal: Ordset α

full_name: Ordset.size
code: /-- O(1). Get the size of the set. -/
def size (s : Ordset α) : ℕ 
goal: ℕ

full_name: Ordset.singleton
code: /-- O(1). Construct a singleton set containing value `a`. -/
protected def singleton (a : α) : Ordset α 
goal: Ordset α

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

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

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

full_name: Ordset.Empty
code: /-- O(1). Is the set empty? -/
def Empty (s : Ordset α) : Prop 
goal: Prop

full_name: Ordset.empty_iff
code: theorem empty_iff {s : Ordset α} : s = ∅ ↔ s.1.empty 
goal: s = ∅ ↔ (↑s).empty = true

full_name: Ordset.Empty.instDecidablePred
code: instance Empty.instDecidablePred : DecidablePred (@Empty α _) 
goal: DecidablePred Ordset.Empty

full_name: Ordset.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. -/
protected def insert [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) (s : Ordset α) :
    Ordset α 
goal: Ordset α

full_name: Ordset.instInsert
code: instance instInsert [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] : Insert α (Ordset α) 
goal: Insert α (Ordset α)

full_name: Ordset.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. -/
nonrec def insert' [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) (s : Ordset α) :
    Ordset α 
goal: Ordset α

full_name: Ordset.mem
code: /-- O(log n). Does the set contain the element `x`? That is,
  is there an element that is equivalent to `x` in the order? -/
def mem (x : α) (s : Ordset α) : Bool 
goal: Bool

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

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

full_name: Ordset.mem.decidable
code: instance mem.decidable (x : α) (s : Ordset α) : Decidable (x ∈ s) 
goal: Decidable (x ∈ s)

full_name: Ordset.pos_size_of_mem
code: theorem pos_size_of_mem {x : α} {t : Ordset α} (h_mem : x ∈ t) : 0 < size t 
goal: 0 < t.size

full_name: Ordset.erase
code: /-- O(log n). Remove an element from the set equivalent to `x`. Does nothing if there
is no such element. -/
def erase [@DecidableRel α (· ≤ ·)] (x : α) (s : Ordset α) : Ordset α 
goal: Ordset α

full_name: Ordset.map
code: /-- O(n). Map a function across a tree, without changing the structure. -/
def map {β} [Preorder β] (f : α → β) (f_strict_mono : StrictMono f) (s : Ordset α) : Ordset β 
goal: Ordset β