File: .lake/packages/batteries/Batteries/Data/BinomialHeap/Basic.lean

full_name: Batteries.BinomialHeap.Imp.HeapNode.node
code: /--
A `HeapNode` is one of the internal nodes of the binomial heap.
It is always a perfect binary tree, with the depth of the tree stored in the `Heap`.
However the interpretation of the two pointers is different: we view the `child`
as going to the first child of this node, and `sibling` goes to the next sibling
of this tree. So it actually encodes a forest where each node has children
`node.child`, `node.child.sibling`, `node.child.sibling.sibling`, etc.

Each edge in this forest denotes a `le a b` relation that has been checked, so
the root is smaller than everything else under it.
-/
inductive HeapNode (α : Type u) where
  /-- An empty forest, which has depth `0`. -/
  | nil : HeapNode α
  /-- A forest of rank `r + 1` consists of a root `a`,
  a forest `child` of rank `r` elements greater than `a`,
  and another forest `sibling` of rank `r`. -/
  | node (a : α) (child sibling : HeapNode α) : HeapNode α
  deriving Repr
goal: Batteries.BinomialHeap.Imp.HeapNode α

full_name: Batteries.BinomialHeap.Imp.instReprHeapNode
code: /--
A `HeapNode` is one of the internal nodes of the binomial heap.
It is always a perfect binary tree, with the depth of the tree stored in the `Heap`.
However the interpretation of the two pointers is different: we view the `child`
as going to the first child of this node, and `sibling` goes to the next sibling
of this tree. So it actually encodes a forest where each node has children
`node.child`, `node.child.sibling`, `node.child.sibling.sibling`, etc.

Each edge in this forest denotes a `le a b` relation that has been checked, so
the root is smaller than everything else under it.
-/
inductive HeapNode (α : Type u) where
  /-- An empty forest, which has depth `0`. -/
  | nil : HeapNode α
  /-- A forest of rank `r + 1` consists of a root `a`,
  a forest `child` of rank `r` elements greater than `a`,
  and another forest `sibling` of rank `r`. -/
  | node (a : α) (child sibling : HeapNode α) : HeapNode α
  deriving Repr
goal: {α : Type u_1} → [inst : Repr α] → Repr (Batteries.BinomialHeap.Imp.HeapNode α)

full_name: Batteries.BinomialHeap.Imp.HeapNode.nil
code: /--
A `HeapNode` is one of the internal nodes of the binomial heap.
It is always a perfect binary tree, with the depth of the tree stored in the `Heap`.
However the interpretation of the two pointers is different: we view the `child`
as going to the first child of this node, and `sibling` goes to the next sibling
of this tree. So it actually encodes a forest where each node has children
`node.child`, `node.child.sibling`, `node.child.sibling.sibling`, etc.

Each edge in this forest denotes a `le a b` relation that has been checked, so
the root is smaller than everything else under it.
-/
inductive HeapNode (α : Type u) where
  /-- An empty forest, which has depth `0`. -/
  | nil : HeapNode α
  /-- A forest of rank `r + 1` consists of a root `a`,
  a forest `child` of rank `r` elements greater than `a`,
  and another forest `sibling` of rank `r`. -/
  | node (a : α) (child sibling : HeapNode α) : HeapNode α
  deriving Repr
goal: Batteries.BinomialHeap.Imp.HeapNode α

full_name: Batteries.BinomialHeap.Imp.HeapNode
code: /--
A `HeapNode` is one of the internal nodes of the binomial heap.
It is always a perfect binary tree, with the depth of the tree stored in the `Heap`.
However the interpretation of the two pointers is different: we view the `child`
as going to the first child of this node, and `sibling` goes to the next sibling
of this tree. So it actually encodes a forest where each node has children
`node.child`, `node.child.sibling`, `node.child.sibling.sibling`, etc.

Each edge in this forest denotes a `le a b` relation that has been checked, so
the root is smaller than everything else under it.
-/
inductive HeapNode (α : Type u) where
  /-- An empty forest, which has depth `0`. -/
  | nil : HeapNode α
  /-- A forest of rank `r + 1` consists of a root `a`,
  a forest `child` of rank `r` elements greater than `a`,
  and another forest `sibling` of rank `r`. -/
  | node (a : α) (child sibling : HeapNode α) : HeapNode α
  deriving Repr
goal: Type u

full_name: Batteries.BinomialHeap.Imp.HeapNode.realSize
code: /--
The "real size" of the node, counting up how many values of type `α` are stored.
This is `O(n)` and is intended mainly for specification purposes.
For a well formed `HeapNode` the size is always `2^n - 1` where `n` is the depth.
-/
@[simp] def HeapNode.realSize : HeapNode α → Nat
  
goal: Batteries.BinomialHeap.Imp.HeapNode α → Nat

full_name: Batteries.BinomialHeap.Imp.HeapNode.singleton
code: /-- A node containing a single element `a`. -/
def HeapNode.singleton (a : α) : HeapNode α 
goal: Batteries.BinomialHeap.Imp.HeapNode α

full_name: Batteries.BinomialHeap.Imp.HeapNode.rank
code: /--
`O(log n)`. The rank, or the number of trees in the forest.
It is also the depth of the forest.
-/
def HeapNode.rank : HeapNode α → Nat
  
goal: Batteries.BinomialHeap.Imp.HeapNode α → Nat

full_name: _private.«.lake».packages.batteries.Batteries.Data.BinomialHeap.Basic.0.Batteries.BinomialHeap.Imp.HeapNode.rankTR
code: /-- Tail-recursive version of `HeapNode.rank`. -/
@[inline] private def HeapNode.rankTR (s : HeapNode α) : Nat 
goal: Nat

full_name: _private.«.lake».packages.batteries.Batteries.Data.BinomialHeap.Basic.0.Batteries.BinomialHeap.Imp.HeapNode.rankTR.go
code: /-- Tail-recursive version of `HeapNode.rank`. -/
@[inline] private def HeapNode.rankTR (s : HeapNode α) : Nat 
goal: Batteries.BinomialHeap.Imp.HeapNode α → Nat → Nat

full_name: _private.«.lake».packages.batteries.Batteries.Data.BinomialHeap.Basic.0.Batteries.BinomialHeap.Imp.HeapNode.rankTR_eq
code: @[csimp] private theorem HeapNode.rankTR_eq : @rankTR = @rank 
goal: @Batteries.BinomialHeap.Imp.HeapNode.rankTR = @Batteries.BinomialHeap.Imp.HeapNode.rank

full_name: _private.«.lake».packages.batteries.Batteries.Data.BinomialHeap.Basic.0.Batteries.BinomialHeap.Imp.HeapNode.rankTR_eq.go
code: @[csimp] private theorem HeapNode.rankTR_eq : @rankTR = @rank 
goal: Batteries.BinomialHeap.Imp.HeapNode.rankTR.go s n = s.rank + n

full_name: Batteries.BinomialHeap.Imp.Heap
code: /--
A `Heap` is the top level structure in a binomial heap.
It consists of a forest of `HeapNode`s with strictly increasing ranks.
-/
inductive Heap (α : Type u) where
  /-- An empty heap. -/
  | nil : Heap α
  /-- A cons node contains a tree of root `val`, children `node` and rank `rank`,
  and then `next` which is the rest of the forest. -/
  | cons (rank : Nat) (val : α) (node : HeapNode α) (next : Heap α) : Heap α
  deriving Repr
goal: Type u

full_name: Batteries.BinomialHeap.Imp.Heap.nil
code: /--
A `Heap` is the top level structure in a binomial heap.
It consists of a forest of `HeapNode`s with strictly increasing ranks.
-/
inductive Heap (α : Type u) where
  /-- An empty heap. -/
  | nil : Heap α
  /-- A cons node contains a tree of root `val`, children `node` and rank `rank`,
  and then `next` which is the rest of the forest. -/
  | cons (rank : Nat) (val : α) (node : HeapNode α) (next : Heap α) : Heap α
  deriving Repr
goal: Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.Heap.cons
code: /--
A `Heap` is the top level structure in a binomial heap.
It consists of a forest of `HeapNode`s with strictly increasing ranks.
-/
inductive Heap (α : Type u) where
  /-- An empty heap. -/
  | nil : Heap α
  /-- A cons node contains a tree of root `val`, children `node` and rank `rank`,
  and then `next` which is the rest of the forest. -/
  | cons (rank : Nat) (val : α) (node : HeapNode α) (next : Heap α) : Heap α
  deriving Repr
goal: Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.instReprHeap
code: /--
A `Heap` is the top level structure in a binomial heap.
It consists of a forest of `HeapNode`s with strictly increasing ranks.
-/
inductive Heap (α : Type u) where
  /-- An empty heap. -/
  | nil : Heap α
  /-- A cons node contains a tree of root `val`, children `node` and rank `rank`,
  and then `next` which is the rest of the forest. -/
  | cons (rank : Nat) (val : α) (node : HeapNode α) (next : Heap α) : Heap α
  deriving Repr
goal: {α : Type u_1} → [inst : Repr α] → Repr (Batteries.BinomialHeap.Imp.Heap α)

full_name: Batteries.BinomialHeap.Imp.Heap.realSize
code: /--
`O(n)`. The "real size" of the heap, counting up how many values of type `α` are stored.
This is intended mainly for specification purposes.
Prefer `Heap.size`, which is the same for well formed heaps.
-/
@[simp] def Heap.realSize : Heap α → Nat
  
goal: Batteries.BinomialHeap.Imp.Heap α → Nat

full_name: Batteries.BinomialHeap.Imp.Heap.size
code: /-- `O(log n)`. The number of elements in the heap. -/
def Heap.size : Heap α → Nat
  
goal: Batteries.BinomialHeap.Imp.Heap α → Nat

full_name: Batteries.BinomialHeap.Imp.Heap.isEmpty
code: /-- `O(1)`. Is the heap empty? -/
@[inline] def Heap.isEmpty : Heap α → Bool
  
goal: Batteries.BinomialHeap.Imp.Heap α → Bool

full_name: Batteries.BinomialHeap.Imp.Heap.singleton
code: /-- `O(1)`. The heap containing a single value `a`. -/
@[inline] def Heap.singleton (a : α) : Heap α 
goal: Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.Heap.rankGT
code: /-- `O(1)`. Auxiliary for `Heap.merge`: Is the minimum rank in `Heap` strictly larger than `n`? -/
def Heap.rankGT : Heap α → Nat → Prop
  
goal: Batteries.BinomialHeap.Imp.Heap α → Nat → Prop

full_name: Batteries.BinomialHeap.Imp.instDecidableRankGT
code: instance : Decidable (Heap.rankGT s n) 
goal: {α : Type u_1} → {s : Batteries.BinomialHeap.Imp.Heap α} → {n : Nat} → Decidable (s.rankGT n)

full_name: Batteries.BinomialHeap.Imp.Heap.length
code: /-- `O(log n)`. The number of trees in the forest. -/
@[simp] def Heap.length : Heap α → Nat
  
goal: Batteries.BinomialHeap.Imp.Heap α → Nat

full_name: Batteries.BinomialHeap.Imp.combine
code: /--
`O(1)`. Auxiliary for `Heap.merge`: combines two heap nodes of the same rank
into one with the next larger rank.
-/
@[inline] def combine (le : α → α → Bool) (a₁ a₂ : α) (n₁ n₂ : HeapNode α) : α × HeapNode α 
goal: α × Batteries.BinomialHeap.Imp.HeapNode α

full_name: Batteries.BinomialHeap.Imp.Heap.merge
code: /--
Merge two forests of binomial trees. The forests are assumed to be ordered
by rank and `merge` maintains this invariant.
-/
@[specialize] def Heap.merge (le : α → α → Bool) : Heap α → Heap α → Heap α
  
goal: Batteries.BinomialHeap.Imp.Heap α → Batteries.BinomialHeap.Imp.Heap α → Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.HeapNode.toHeap.go
code: /--
`O(log n)`. Convert a `HeapNode` to a `Heap` by reversing the order of the nodes
along the `sibling` spine.
-/
def HeapNode.toHeap (s : HeapNode α) : Heap α 
goal: Batteries.BinomialHeap.Imp.HeapNode α → Nat → Batteries.BinomialHeap.Imp.Heap α → Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.HeapNode.toHeap
code: /--
`O(log n)`. Convert a `HeapNode` to a `Heap` by reversing the order of the nodes
along the `sibling` spine.
-/
def HeapNode.toHeap (s : HeapNode α) : Heap α 
goal: Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.Heap.headD
code: /-- `O(log n)`. Get the smallest element in the heap, including the passed in value `a`. -/
@[specialize] def Heap.headD (le : α → α → Bool) (a : α) : Heap α → α
  
goal: Batteries.BinomialHeap.Imp.Heap α → α

full_name: Batteries.BinomialHeap.Imp.Heap.head?
code: /-- `O(log n)`. Get the smallest element in the heap, if it has an element. -/
@[inline] def Heap.head? (le : α → α → Bool) : Heap α → Option α
  
goal: Batteries.BinomialHeap.Imp.Heap α → Option α

full_name: Batteries.BinomialHeap.Imp.FindMin.node
code: /--
The return type of `FindMin`, which encodes various quantities needed to
reconstruct the tree in `deleteMin`.
-/
structure FindMin (α) where
  /-- The list of elements prior to the minimum element, encoded as a "difference list". -/
  before : Heap α → Heap α := id
  /-- The minimum element. -/
  val : α
  /-- The children of the minimum element. -/
  node : HeapNode α
  /-- The forest after the minimum element. -/
  next : Heap α
goal: Batteries.BinomialHeap.Imp.HeapNode α

full_name: Batteries.BinomialHeap.Imp.FindMin.next
code: /--
The return type of `FindMin`, which encodes various quantities needed to
reconstruct the tree in `deleteMin`.
-/
structure FindMin (α) where
  /-- The list of elements prior to the minimum element, encoded as a "difference list". -/
  before : Heap α → Heap α := id
  /-- The minimum element. -/
  val : α
  /-- The children of the minimum element. -/
  node : HeapNode α
  /-- The forest after the minimum element. -/
  next : Heap α
goal: Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.FindMin.before
code: /--
The return type of `FindMin`, which encodes various quantities needed to
reconstruct the tree in `deleteMin`.
-/
structure FindMin (α) where
  /-- The list of elements prior to the minimum element, encoded as a "difference list". -/
  before : Heap α → Heap α := id
  /-- The minimum element. -/
  val : α
  /-- The children of the minimum element. -/
  node : HeapNode α
  /-- The forest after the minimum element. -/
  next : Heap α
goal: Batteries.BinomialHeap.Imp.Heap α → Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.FindMin.val
code: /--
The return type of `FindMin`, which encodes various quantities needed to
reconstruct the tree in `deleteMin`.
-/
structure FindMin (α) where
  /-- The list of elements prior to the minimum element, encoded as a "difference list". -/
  before : Heap α → Heap α := id
  /-- The minimum element. -/
  val : α
  /-- The children of the minimum element. -/
  node : HeapNode α
  /-- The forest after the minimum element. -/
  next : Heap α
goal: α

full_name: Batteries.BinomialHeap.Imp.FindMin
code: /--
The return type of `FindMin`, which encodes various quantities needed to
reconstruct the tree in `deleteMin`.
-/
structure FindMin (α) where
  /-- The list of elements prior to the minimum element, encoded as a "difference list". -/
  before : Heap α → Heap α := id
  /-- The minimum element. -/
  val : α
  /-- The children of the minimum element. -/
  node : HeapNode α
  /-- The forest after the minimum element. -/
  next : Heap α
goal: Type u_1

full_name: Batteries.BinomialHeap.Imp.Heap.findMin
code: /--
`O(log n)`. Find the minimum element, and return a data structure `FindMin` with information
needed to reconstruct the rest of the binomial heap.
-/
@[specialize] def Heap.findMin (le : α → α → Bool) (k : Heap α → Heap α) :
    Heap α → FindMin α → FindMin α
  
goal: Batteries.BinomialHeap.Imp.Heap α → Batteries.BinomialHeap.Imp.FindMin α → Batteries.BinomialHeap.Imp.FindMin α

full_name: Batteries.BinomialHeap.Imp.Heap.deleteMin
code: /-- `O(log n)`. Find and remove the the minimum element from the binomial heap. -/
def Heap.deleteMin (le : α → α → Bool) : Heap α → Option (α × Heap α)
  
goal: Batteries.BinomialHeap.Imp.Heap α → Option (α × Batteries.BinomialHeap.Imp.Heap α)

full_name: Batteries.BinomialHeap.Imp.Heap.tail?
code: /-- `O(log n)`. Get the tail of the binomial heap after removing the minimum element. -/
@[inline] def Heap.tail? (le : α → α → Bool) (h : Heap α) : Option (Heap α) 
goal: Option (Batteries.BinomialHeap.Imp.Heap α)

full_name: Batteries.BinomialHeap.Imp.Heap.tail
code: /-- `O(log n)`. Remove the minimum element of the heap. -/
@[inline] def Heap.tail (le : α → α → Bool) (h : Heap α) : Heap α 
goal: Batteries.BinomialHeap.Imp.Heap α

full_name: Batteries.BinomialHeap.Imp.Heap.realSize_merge
code: theorem Heap.realSize_merge (le) (s₁ s₂ : Heap α) :
    (s₁.merge le s₂).realSize = s₁.realSize + s₂.realSize 
goal: (Batteries.BinomialHeap.Imp.Heap.merge le s₁ s₂).realSize = s₁.realSize + s₂.realSize

full_name: _private.«.lake».packages.batteries.Batteries.Data.BinomialHeap.Basic.0.Batteries.BinomialHeap.Imp.FindMin.HasSize
code: private def FindMin.HasSize (res : FindMin α) (n : Nat) : Prop 
goal: Prop

full_name: _private.«.lake».packages.batteries.Batteries.Data.BinomialHeap.Basic.0.Batteries.BinomialHeap.Imp.Heap.realSize_findMin
code: private theorem Heap.realSize_findMin {s : Heap α}
    (m) (hk : ∀ s, (k s).realSize = m + s.realSize)
    (eq : n = m + s.realSize) (hres : res.HasSize n) :
    (s.findMin le k res).HasSize n 
goal: Batteries.BinomialHeap.Imp.FindMin.HasSize (Batteries.BinomialHeap.Imp.Heap.findMin le k s res) n

full_name: Batteries.BinomialHeap.Imp.HeapNode.realSize_toHeap.go
code: theorem HeapNode.realSize_toHeap (s : HeapNode α) : s.toHeap.realSize = s.realSize 
goal: (Batteries.BinomialHeap.Imp.HeapNode.toHeap.go s n res).realSize = s.realSize + res.realSize

full_name: Batteries.BinomialHeap.Imp.HeapNode.realSize_toHeap
code: theorem HeapNode.realSize_toHeap (s : HeapNode α) : s.toHeap.realSize = s.realSize 
goal: s.toHeap.realSize = s.realSize

full_name: Batteries.BinomialHeap.Imp.Heap.realSize_deleteMin
code: theorem Heap.realSize_deleteMin {s : Heap α} (eq : s.deleteMin le = some (a, s')) :
    s.realSize = s'.realSize + 1 
goal: s.realSize = s'.realSize + 1

full_name: Batteries.BinomialHeap.Imp.Heap.realSize_tail?
code: theorem Heap.realSize_tail? {s : Heap α} : s.tail? le = some s' →
    s.realSize = s'.realSize + 1 
goal: Batteries.BinomialHeap.Imp.Heap.tail? le s = some s' → s.realSize = s'.realSize + 1

full_name: Batteries.BinomialHeap.Imp.Heap.realSize_tail
code: theorem Heap.realSize_tail (le) (s : Heap α) : (s.tail le).realSize = s.realSize - 1 
goal: (Batteries.BinomialHeap.Imp.Heap.tail le s).realSize = s.realSize - 1

full_name: Batteries.BinomialHeap.Imp.Heap.foldM
code: /--
`O(n log n)`. Monadic fold over the elements of a heap in increasing order,
by repeatedly pulling the minimum element out of the heap.
-/
@[specialize] def Heap.foldM [Monad m] (le : α → α → Bool) (s : Heap α)
    (init : β) (f : β → α → m β) : m β 
goal: m β

full_name: Batteries.BinomialHeap.Imp.Heap.fold
code: /--
`O(n log n)`. Fold over the elements of a heap in increasing order,
by repeatedly pulling the minimum element out of the heap.
-/
@[inline] def Heap.fold (le : α → α → Bool) (s : Heap α) (init : β) (f : β → α → β) : β 
goal: β

full_name: Batteries.BinomialHeap.Imp.Heap.toArray
code: /-- `O(n log n)`. Convert the heap to an array in increasing order. -/
@[inline] def Heap.toArray (le : α → α → Bool) (s : Heap α) : Array α 
goal: Array α

full_name: Batteries.BinomialHeap.Imp.Heap.toList
code: /-- `O(n log n)`. Convert the heap to a list in increasing order. -/
@[inline] def Heap.toList (le : α → α → Bool) (s : Heap α) : List α 
goal: List α

full_name: Batteries.BinomialHeap.Imp.HeapNode.foldTreeM
code: /-- `O(n)`. Fold a monadic function over the tree structure to accumulate a value. -/
@[specialize] def HeapNode.foldTreeM : HeapNode α → m β
  
goal: Batteries.BinomialHeap.Imp.HeapNode α → m β

full_name: Batteries.BinomialHeap.Imp.Heap.foldTreeM
code: /-- `O(n)`. Fold a monadic function over the tree structure to accumulate a value. -/
@[specialize] def Heap.foldTreeM : Heap α → m β
  
goal: Batteries.BinomialHeap.Imp.Heap α → m β

full_name: Batteries.BinomialHeap.Imp.Heap.foldTree
code: /-- `O(n)`. Fold a function over the tree structure to accumulate a value. -/
@[inline] def Heap.foldTree (nil : β) (join : α → β → β → β) (s : Heap α) : β 
goal: β

full_name: Batteries.BinomialHeap.Imp.Heap.toListUnordered
code: /-- `O(n)`. Convert the heap to a list in arbitrary order. -/
def Heap.toListUnordered (s : Heap α) : List α 
goal: List α

full_name: Batteries.BinomialHeap.Imp.Heap.toArrayUnordered
code: /-- `O(n)`. Convert the heap to an array in arbitrary order. -/
def Heap.toArrayUnordered (s : Heap α) : Array α 
goal: Array α

full_name: Batteries.BinomialHeap.Imp.HeapNode.WF
code: /--
The well formedness predicate for a heap node.
It asserts that:
* If `a` is added at the top to make the forest into a tree, the resulting tree
  is a `le`-min-heap (if `le` is well-behaved)
* When interpreting `child` and `sibling` as left and right children of a binary tree,
  it is a perfect binary tree with depth `r`
-/
def HeapNode.WF (le : α → α → Bool) (a : α) : HeapNode α → Nat → Prop
  
goal: Batteries.BinomialHeap.Imp.HeapNode α → Nat → Prop

full_name: Batteries.BinomialHeap.Imp.Heap.WF
code: /--
The well formedness predicate for a binomial heap.
It asserts that:
* It consists of a list of well formed trees with the specified ranks
* The ranks are in strictly increasing order, and all are at least `n`
-/
def Heap.WF (le : α → α → Bool) (n : Nat) : Heap α → Prop
  
goal: Batteries.BinomialHeap.Imp.Heap α → Prop

full_name: Batteries.BinomialHeap.Imp.Heap.WF.nil
code: theorem Heap.WF.nil : Heap.nil.WF le n 
goal: ∀ {α : Type u_1} {le : α → α → Bool} {n : Nat},
  Batteries.BinomialHeap.Imp.Heap.WF le n Batteries.BinomialHeap.Imp.Heap.nil

full_name: Batteries.BinomialHeap.Imp.Heap.WF.singleton
code: theorem Heap.WF.singleton : (Heap.singleton a).WF le 0 
goal: ∀ {α : Type u_1} {a : α} {le : α → α → Bool},
  Batteries.BinomialHeap.Imp.Heap.WF le 0 (Batteries.BinomialHeap.Imp.Heap.singleton a)

full_name: Batteries.BinomialHeap.Imp.Heap.WF.of_rankGT
code: theorem Heap.WF.of_rankGT (hlt : s.rankGT n) (h : Heap.WF le n' s) : s.WF le (n+1) 
goal: ∀ {α : Type u_1} {le : α → α → Bool} {n' : Nat} {s : Batteries.BinomialHeap.Imp.Heap α} {n : Nat},
  s.rankGT n → Batteries.BinomialHeap.Imp.Heap.WF le n' s → Batteries.BinomialHeap.Imp.Heap.WF le (n + 1) s

full_name: Batteries.BinomialHeap.Imp.Heap.WF.of_le
code: theorem Heap.WF.of_le (hle : n ≤ n') (h : Heap.WF le n' s) : s.WF le n 
goal: ∀ {α : Type u_1} {le : α → α → Bool} {s : Batteries.BinomialHeap.Imp.Heap α},
  n ≤ n' → Batteries.BinomialHeap.Imp.Heap.WF le n' s → Batteries.BinomialHeap.Imp.Heap.WF le n s

full_name: Batteries.BinomialHeap.Imp.Heap.rankGT.of_le
code: theorem Heap.rankGT.of_le (h : Heap.rankGT s n) (h' : n' ≤ n) : s.rankGT n' 
goal: ∀ {α : Type u_1} {s : Batteries.BinomialHeap.Imp.Heap α} {n n' : Nat}, s.rankGT n → n' ≤ n → s.rankGT n'

full_name: Batteries.BinomialHeap.Imp.Heap.WF.rankGT
code: theorem Heap.WF.rankGT (h : Heap.WF lt (n+1) s) : s.rankGT n 
goal: ∀ {α : Type u_1} {lt : α → α → Bool} {n : Nat} {s : Batteries.BinomialHeap.Imp.Heap α},
  Batteries.BinomialHeap.Imp.Heap.WF lt (n + 1) s → s.rankGT n

full_name: Batteries.BinomialHeap.Imp.Heap.WF.merge'
code: theorem Heap.WF.merge' (h₁ : s₁.WF le n) (h₂ : s₂.WF le n) :
    (merge le s₁ s₂).WF le n ∧ ((s₁.rankGT n ↔ s₂.rankGT n) → (merge le s₁ s₂).rankGT n) 
goal: ∀ {α : Type u_1} {le : α → α → Bool} {s₁ s₂ : Batteries.BinomialHeap.Imp.Heap α} {n : Nat},
  Batteries.BinomialHeap.Imp.Heap.WF le n s₁ →
    Batteries.BinomialHeap.Imp.Heap.WF le n s₂ →
      Batteries.BinomialHeap.Imp.Heap.WF le n (Batteries.BinomialHeap.Imp.Heap.merge le s₁ s₂) ∧
        ((s₁.rankGT n ↔ s₂.rankGT n) → (Batteries.BinomialHeap.Imp.Heap.merge le s₁ s₂).rankGT n)

full_name: Batteries.BinomialHeap.Imp.Heap.WF.merge
code: theorem Heap.WF.merge (h₁ : s₁.WF le n) (h₂ : s₂.WF le n) : (merge le s₁ s₂).WF le n 
goal: ∀ {α : Type u_1} {le : α → α → Bool} {s₁ s₂ : Batteries.BinomialHeap.Imp.Heap α} {n : Nat},
  Batteries.BinomialHeap.Imp.Heap.WF le n s₁ →
    Batteries.BinomialHeap.Imp.Heap.WF le n s₂ →
      Batteries.BinomialHeap.Imp.Heap.WF le n (Batteries.BinomialHeap.Imp.Heap.merge le s₁ s₂)

full_name: Batteries.BinomialHeap.Imp.HeapNode.WF.rank_eq
code: theorem HeapNode.WF.rank_eq : ∀ {n} {s : HeapNode α}, s.WF le a n → s.rank = n
  
goal: Batteries.BinomialHeap.Imp.HeapNode.WF le a s n → s.rank = n

full_name: Batteries.BinomialHeap.Imp.HeapNode.WF.toHeap
code: theorem HeapNode.WF.toHeap {s : HeapNode α} (h : s.WF le a n) : s.toHeap.WF le 0 
goal: Batteries.BinomialHeap.Imp.Heap.WF le 0 s.toHeap

full_name: Batteries.BinomialHeap.Imp.HeapNode.WF.toHeap.go
code: theorem HeapNode.WF.toHeap {s : HeapNode α} (h : s.WF le a n) : s.toHeap.WF le 0 
goal: Batteries.BinomialHeap.Imp.HeapNode.WF le a s n →
  Batteries.BinomialHeap.Imp.Heap.WF le s.rank res →
    Batteries.BinomialHeap.Imp.Heap.WF le 0 (Batteries.BinomialHeap.Imp.HeapNode.toHeap.go s s.rank res)

full_name: Batteries.BinomialHeap.Imp.FindMin.WF.next
code: /--
The well formedness predicate for a `FindMin` value.
This is not actually a predicate, as it contains an additional data value
`rank` corresponding to the rank of the returned node, which is omitted from `findMin`.
-/
structure FindMin.WF (le : α → α → Bool) (res : FindMin α) where
  /-- The rank of the minimum element -/
  rank : Nat
  /-- `before` is a difference list which can be appended to a binomial heap
  with ranks at least `rank` to produce another well formed heap. -/
  before : ∀ {s}, s.WF le rank → (res.before s).WF le 0
  /-- `node` is a well formed forest of rank `rank` with `val` at the root. -/
  node : res.node.WF le res.val rank
  /-- `next` is a binomial heap with ranks above `rank + 1`. -/
  next : res.next.WF le (rank + 1)
goal: Batteries.BinomialHeap.Imp.Heap.WF le (self.rank + 1) res.next

full_name: Batteries.BinomialHeap.Imp.FindMin.WF.rank
code: /--
The well formedness predicate for a `FindMin` value.
This is not actually a predicate, as it contains an additional data value
`rank` corresponding to the rank of the returned node, which is omitted from `findMin`.
-/
structure FindMin.WF (le : α → α → Bool) (res : FindMin α) where
  /-- The rank of the minimum element -/
  rank : Nat
  /-- `before` is a difference list which can be appended to a binomial heap
  with ranks at least `rank` to produce another well formed heap. -/
  before : ∀ {s}, s.WF le rank → (res.before s).WF le 0
  /-- `node` is a well formed forest of rank `rank` with `val` at the root. -/
  node : res.node.WF le res.val rank
  /-- `next` is a binomial heap with ranks above `rank + 1`. -/
  next : res.next.WF le (rank + 1)
goal: Nat

full_name: Batteries.BinomialHeap.Imp.FindMin.WF.node
code: /--
The well formedness predicate for a `FindMin` value.
This is not actually a predicate, as it contains an additional data value
`rank` corresponding to the rank of the returned node, which is omitted from `findMin`.
-/
structure FindMin.WF (le : α → α → Bool) (res : FindMin α) where
  /-- The rank of the minimum element -/
  rank : Nat
  /-- `before` is a difference list which can be appended to a binomial heap
  with ranks at least `rank` to produce another well formed heap. -/
  before : ∀ {s}, s.WF le rank → (res.before s).WF le 0
  /-- `node` is a well formed forest of rank `rank` with `val` at the root. -/
  node : res.node.WF le res.val rank
  /-- `next` is a binomial heap with ranks above `rank + 1`. -/
  next : res.next.WF le (rank + 1)
goal: Batteries.BinomialHeap.Imp.HeapNode.WF le res.val res.node self.rank

full_name: Batteries.BinomialHeap.Imp.FindMin.WF.before
code: /--
The well formedness predicate for a `FindMin` value.
This is not actually a predicate, as it contains an additional data value
`rank` corresponding to the rank of the returned node, which is omitted from `findMin`.
-/
structure FindMin.WF (le : α → α → Bool) (res : FindMin α) where
  /-- The rank of the minimum element -/
  rank : Nat
  /-- `before` is a difference list which can be appended to a binomial heap
  with ranks at least `rank` to produce another well formed heap. -/
  before : ∀ {s}, s.WF le rank → (res.before s).WF le 0
  /-- `node` is a well formed forest of rank `rank` with `val` at the root. -/
  node : res.node.WF le res.val rank
  /-- `next` is a binomial heap with ranks above `rank + 1`. -/
  next : res.next.WF le (rank + 1)
goal: Batteries.BinomialHeap.Imp.Heap.WF le self.rank s → Batteries.BinomialHeap.Imp.Heap.WF le 0 (res.before s)

full_name: Batteries.BinomialHeap.Imp.FindMin.WF
code: /--
The well formedness predicate for a `FindMin` value.
This is not actually a predicate, as it contains an additional data value
`rank` corresponding to the rank of the returned node, which is omitted from `findMin`.
-/
structure FindMin.WF (le : α → α → Bool) (res : FindMin α) where
  /-- The rank of the minimum element -/
  rank : Nat
  /-- `before` is a difference list which can be appended to a binomial heap
  with ranks at least `rank` to produce another well formed heap. -/
  before : ∀ {s}, s.WF le rank → (res.before s).WF le 0
  /-- `node` is a well formed forest of rank `rank` with `val` at the root. -/
  node : res.node.WF le res.val rank
  /-- `next` is a binomial heap with ranks above `rank + 1`. -/
  next : res.next.WF le (rank + 1)
goal: Type

full_name: Batteries.BinomialHeap.Imp.Heap.WF.findMin
code: /-- The conditions under which `findMin` is well-formed. -/
def Heap.WF.findMin {s : Heap α} (h : s.WF le n) (hr : res.WF le)
    (hk : ∀ {s}, s.WF le n → (k s).WF le 0) : ((s : Heap α).findMin le k res).WF le 
goal: Batteries.BinomialHeap.Imp.FindMin.WF le (Batteries.BinomialHeap.Imp.Heap.findMin le k s res)

full_name: Batteries.BinomialHeap.Imp.Heap.WF.deleteMin
code: theorem Heap.WF.deleteMin {s : Heap α}
    (h : s.WF le n) (eq : s.deleteMin le = some (a, s')) : s'.WF le 0 
goal: Batteries.BinomialHeap.Imp.Heap.WF le 0 s'

full_name: Batteries.BinomialHeap.Imp.Heap.WF.tail?
code: theorem Heap.WF.tail? (hwf : (s : Heap α).WF le n) : s.tail? le = some tl → tl.WF le 0 
goal: Batteries.BinomialHeap.Imp.Heap.tail? le s = some tl → Batteries.BinomialHeap.Imp.Heap.WF le 0 tl

full_name: Batteries.BinomialHeap.Imp.Heap.WF.tail
code: theorem Heap.WF.tail (hwf : (s : Heap α).WF le n) : (s.tail le).WF le 0 
goal: Batteries.BinomialHeap.Imp.Heap.WF le 0 (Batteries.BinomialHeap.Imp.Heap.tail le s)

full_name: Batteries.BinomialHeap
code: /--
A [binomial heap](https://en.wikipedia.org/wiki/Binomial_heap) is a data structure which supports
the following primary operations:

* `insert : α → BinomialHeap α → BinomialHeap α`: add an element to the heap
* `deleteMin : BinomialHeap α → Option (α × BinomialHeap α)`:
  remove the minimum element from the heap
* `merge : BinomialHeap α → BinomialHeap α → BinomialHeap α`: combine two heaps

The first two operations are known as a "priority queue", so this could be called
a "mergeable priority queue". The standard choice for a priority queue is a binary heap,
which supports `insert` and `deleteMin` in `O(log n)`, but `merge` is `O(n)`.
With a `BinomialHeap`, all three operations are `O(log n)`.
-/
def BinomialHeap (α : Type u) (le : α → α → Bool) 
goal: Type u

full_name: Batteries.mkBinomialHeap
code: /-- `O(1)`. Make a new empty binomial heap. -/
@[inline] def mkBinomialHeap (α : Type u) (le : α → α → Bool) : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.empty
code: /-- `O(1)`. Make a new empty binomial heap. -/
@[inline] def empty : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.instEmptyCollection
code: instance : EmptyCollection (BinomialHeap α le) 
goal: EmptyCollection (Batteries.BinomialHeap α le)

full_name: Batteries.BinomialHeap.instInhabited
code: instance : Inhabited (BinomialHeap α le) 
goal: Inhabited (Batteries.BinomialHeap α le)

full_name: Batteries.BinomialHeap.isEmpty
code: /-- `O(1)`. Is the heap empty? -/
@[inline] def isEmpty (b : BinomialHeap α le) : Bool 
goal: Bool

full_name: Batteries.BinomialHeap.size
code: /-- `O(log n)`. The number of elements in the heap. -/
@[inline] def size (b : BinomialHeap α le) : Nat 
goal: Nat

full_name: Batteries.BinomialHeap.singleton
code: /-- `O(1)`. Make a new heap containing `a`. -/
@[inline] def singleton (a : α) : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.merge
code: /-- `O(log n)`. Merge the contents of two heaps. -/
@[inline] def merge : BinomialHeap α le → BinomialHeap α le → BinomialHeap α le
  
goal: Batteries.BinomialHeap α le → Batteries.BinomialHeap α le → Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.insert
code: /-- `O(log n)`. Add element `a` to the given heap `h`. -/
@[inline] def insert (a : α) (h : BinomialHeap α le) : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.ofList
code: /-- `O(n log n)`. Construct a heap from a list by inserting all the elements. -/
def ofList (le : α → α → Bool) (as : List α) : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.ofArray
code: /-- `O(n log n)`. Construct a heap from a list by inserting all the elements. -/
def ofArray (le : α → α → Bool) (as : Array α) : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.deleteMin
code: /-- `O(log n)`. Remove and return the minimum element from the heap. -/
@[inline] def deleteMin (b : BinomialHeap α le) : Option (α × BinomialHeap α le) 
goal: Option (α × Batteries.BinomialHeap α le)

full_name: Batteries.BinomialHeap.instStream
code: instance : Stream (BinomialHeap α le) α 
goal: Stream (Batteries.BinomialHeap α le) α

full_name: Batteries.BinomialHeap.forIn
code: /--
`O(n log n)`. Implementation of `for x in (b : BinomialHeap α le) ...` notation,
which iterates over the elements in the heap in increasing order.
-/
protected def forIn [Monad m] (b : BinomialHeap α le) (x : β) (f : α → β → m (ForInStep β)) : m β 
goal: m β

full_name: Batteries.BinomialHeap.instForIn
code: instance : ForIn m (BinomialHeap α le) α 
goal: ForIn m (Batteries.BinomialHeap α le) α

full_name: Batteries.BinomialHeap.head?
code: /-- `O(log n)`. Returns the smallest element in the heap, or `none` if the heap is empty. -/
@[inline] def head? (b : BinomialHeap α le) : Option α 
goal: Option α

full_name: Batteries.BinomialHeap.head!
code: /-- `O(log n)`. Returns the smallest element in the heap, or panics if the heap is empty. -/
@[inline] def head! [Inhabited α] (b : BinomialHeap α le) : α 
goal: α

full_name: Batteries.BinomialHeap.headI
code: /-- `O(log n)`. Returns the smallest element in the heap, or `default` if the heap is empty. -/
@[inline] def headI [Inhabited α] (b : BinomialHeap α le) : α 
goal: α

full_name: Batteries.BinomialHeap.tail?
code: /-- `O(log n)`. Removes the smallest element from the heap, or `none` if the heap is empty. -/
@[inline] def tail? (b : BinomialHeap α le) : Option (BinomialHeap α le) 
goal: Option (Batteries.BinomialHeap α le)

full_name: Batteries.BinomialHeap.tail
code: /-- `O(log n)`. Removes the smallest element from the heap, if possible. -/
@[inline] def tail (b : BinomialHeap α le) : BinomialHeap α le 
goal: Batteries.BinomialHeap α le

full_name: Batteries.BinomialHeap.foldM
code: /--
`O(n log n)`. Monadic fold over the elements of a heap in increasing order,
by repeatedly pulling the minimum element out of the heap.
-/
@[inline] def foldM [Monad m] (b : BinomialHeap α le) (init : β) (f : β → α → m β) : m β 
goal: m β

full_name: Batteries.BinomialHeap.fold
code: /--
`O(n log n)`. Fold over the elements of a heap in increasing order,
by repeatedly pulling the minimum element out of the heap.
-/
@[inline] def fold (b : BinomialHeap α le) (init : β) (f : β → α → β) : β 
goal: β

full_name: Batteries.BinomialHeap.toList
code: /-- `O(n log n)`. Convert the heap to a list in increasing order. -/
@[inline] def toList (b : BinomialHeap α le) : List α 
goal: List α

full_name: Batteries.BinomialHeap.toArray
code: /-- `O(n log n)`. Convert the heap to an array in increasing order. -/
@[inline] def toArray (b : BinomialHeap α le) : Array α 
goal: Array α

full_name: Batteries.BinomialHeap.toListUnordered
code: /-- `O(n)`. Convert the heap to a list in arbitrary order. -/
@[inline] def toListUnordered (b : BinomialHeap α le) : List α 
goal: List α

full_name: Batteries.BinomialHeap.toArrayUnordered
code: /-- `O(n)`. Convert the heap to an array in arbitrary order. -/
@[inline] def toArrayUnordered (b : BinomialHeap α le) : Array α 
goal: Array α