Documentation

Complexity.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.Forest

Forest invariants and pure state transitions for a Fibonacci heap #

This file lifts the single-tree model of Trees.lean to the full multi-root forest invariant FibRawInv and proves the structural transitions required by all priority-queue operations:

Main definitions #

Main results #

References #

List surgery lemmas for child removal and replacement #

theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.forestNodes_nodup_idx_disjoint {n : ℕ} {cs : List (FHTree n)} (hnd : (forestNodes cs).Nodup) {i j : ℕ} (hi : i < cs.length) (hj : j < cs.length) (hij : i ≠ j) {x : Fin n} (hxi : x ∈ cs[i].nodes) (hxj : x ∈ cs[j].nodes) :
theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.forestNodes_set_perm {n : ℕ} (cs : List (FHTree n)) (i : ℕ) (hi : i < cs.length) (T_cut c' : FHTree n) :
(T_cut.nodes ++ c'.nodes).Perm cs[i].nodes → (T_cut.nodes ++ forestNodes (cs.set i c')).Perm (forestNodes cs)

Parent witnesses and subtree cutting #

theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.ValidSubtree.par_of_mem_children {n : ℕ} {st : RawState n} {pending : Option (Fin n)} {T : FHTree n} (hT : ValidSubtree st pending T) (x : Fin n) :
x ∈ forestNodes T.children → ∃ q ∈ T.nodes, st.par x = ↑q + 1

Every strict descendant x of T has st.par x = q.val + 1 for some q ∈ T.nodes.

theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.ValidSubtree.frame_root_mark {n : ℕ} {st st' : RawState n} {pending pending' : Option (Fin n)} {T : FHTree n} (hT : ValidSubtree st pending T) (hnd : T.nodes.Nodup) (hrm : st'.mark T.root ≤ 1) (hroot : st'.inHeap T.root = st.inHeap T.root ∧ st'.deg T.root = st.deg T.root ∧ st'.child T.root = st.child T.root ∧ st'.key T.root = st.key T.root) (hdesc_node : ∀ x ∈ forestNodes T.children, st'.inHeap x = st.inHeap x ∧ st'.mark x = st.mark x ∧ st'.deg x = st.deg x ∧ st'.child x = st.child x ∧ st'.key x = st.key x) (hdesc_ptr : ∀ x ∈ forestNodes T.children, st'.par x = st.par x ∧ st'.left x = st.left x ∧ st'.right x = st.right x ∧ (some x = pending' ↔ some x = pending)) :
ValidSubtree st' pending' T

Updating only the root's mark to a value ≤ 1 while keeping all other subtree fields fixed preserves ValidSubtree.

theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.exists_parent_info {n : ℕ} {st : RawState n} {pending : Option (Fin n)} {T : FHTree n} (hT : ValidSubtree st pending T) {cur p : Fin n} (hcur : cur ∈ forestNodes T.children) (hpar_cur : st.par cur = ↑p + 1) :
p ∈ T.nodes ∧ st.inHeap p ≠ 0 ∧ st.mark p ≤ 1 ∧ st.inHeap cur ≠ 0 ∧ st.mark cur ≤ 1 ∧ 1 ≤ st.deg p ∧ (2 ≤ st.deg p → ∃ (h : Fin n) (tail : List (Fin n)), st.child p = ↑h + 1 ∧ IsCircList st.left st.right (h :: tail) ∧ cur ∈ h :: tail ∧ 2 ≤ (h :: tail).length ∧ ∀ x ∈ h :: tail, st.par x = ↑p + 1)

Pre-cut structural properties of cur and its parent p inside any valid subtree containing cur as a strict descendant.

theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.ValidSubtree.exists_cut {n : ℕ} {st st' : RawState n} {pending : Option (Fin n)} {T : FHTree n} (hT : ValidSubtree st pending T) (hnd : T.nodes.Nodup) {cur p : Fin n} (hcur : cur ∈ forestNodes T.children) (hpar_cur : st.par cur = ↑p + 1) (hpend : pending = none ∨ pending = some cur) (hin_eq : ∀ x ∈ T.nodes, st'.inHeap x = st.inHeap x ∧ st'.key x = st.key x) (hmark' : st'.mark cur = 0 ∧ ∀ x ∈ T.nodes, x ≠ cur → st'.mark x = st.mark x) (hdeg' : st'.deg p + 1 = st.deg p ∧ ∀ x ∈ T.nodes, x ≠ p → st'.deg x = st.deg x) (hpar' : st'.par cur = 0 ∧ ∀ x ∈ T.nodes, x ≠ cur → st'.par x = st.par x) (hchild_p : (st.deg p = 1 → st'.child p = 0) ∧ ∀ (h : Fin n) (tail : List (Fin n)), 2 ≤ st.deg p → st.child p = ↑h + 1 → IsCircList st.left st.right (h :: tail) → cur ∈ h :: tail → ∃ (r : Fin n) (rest : List (Fin n)), st'.child p = ↑r + 1 ∧ IsCircList st'.left st'.right (r :: rest) ∧ (r :: rest).Perm ((h :: tail).erase cur)) (hchild_other : ∀ x ∈ T.nodes, x ≠ p → st'.child x = st.child x) (hlr_other : ∀ x ∈ T.nodes, st.par x ≠ ↑p + 1 → st.par x ≠ 0 → st'.left x = st.left x ∧ st'.right x = st.right x) :
∃ (T_cut : FHTree n) (T' : FHTree n), T_cut.root = cur ∧ T'.root = T.root ∧ p ∈ T'.nodes ∧ (T_cut.nodes ++ T'.nodes).Perm T.nodes ∧ ValidRoot st' none T_cut ∧ ValidSubtree st' (some p) T'

Cutting a strict descendant cur (with st.par cur = p.val + 1) from T splits T into a new root tree T_cut (T_cut.root = cur) and a pruned tree T' (T'.root = T.root, p ∈ T'.nodes) satisfying ValidRoot st' none T_cut and ValidSubtree st' (some p) T'.

theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.ValidSubtree.mark_pending {n : ℕ} {st st' : RawState n} {z : Fin n} {T : FHTree n} (hT : ValidSubtree st (some z) T) (hm0 : st.mark z = 0) (hm1 : st'.mark z = 1) (hm_other : ∀ x ∈ T.nodes, x ≠ z → st'.mark x = st.mark x) (hunch : ∀ x ∈ T.nodes, st'.inHeap x = st.inHeap x ∧ st'.deg x = st.deg x ∧ st'.child x = st.child x ∧ st'.key x = st.key x) (hptr : ∀ x ∈ forestNodes T.children, st'.par x = st.par x ∧ st'.left x = st.left x ∧ st'.right x = st.right x) :

Marking an unmarked pending = some z node (st.mark z = 0, st'.mark z = 1) absorbs the transient rank slack and restores ValidSubtree st' none T.

Full heap representation invariant and core consequences #

Full structural, key, counter, and root-list invariant relating s : IndexedMinPQ.State n to st : RawState n.

Instances For

    Transient forest invariant during decreaseKey v k while cascading cuts propagate from pending.

    Instances For
      theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.FibRawInv.empty {n K_max : ℕ} {st : RawState n} (hin : ∀ (v : Fin n), st.inHeap v = 0) (hcons : ∀ d ≤ n, st.cons d = 0) (hmin : st.minRoot = 0) (hnr : st.numRoots = 0) (hnm : st.numMarked = 0) (hsz : st.sz = 0) :

      FibRawInv holds on the empty priority queue whenever inHeap and cons[0..n] are zeroed and the four scalar counters are 0.

      All scalar counters of a valid Fibonacci heap are bounded by n.

      theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.FibRawInv.unique {n K_max : ℕ} {s₁ s₂ : Lean.IndexedMinPQ.State n} {st : RawState n} (h₁ : FibRawInv n K_max s₁ st) (h₂ : FibRawInv n K_max s₂ st) :
      s₁ = s₂

      Concrete state uniquely determines the represented IndexedMinPQ.State n.

      When st.minRoot = 0, dom s = ∅ and IndexedMinPQ.findMin s = none.

      theorem Cslib.Algorithms.WordRAM.PriorityQueue.FibonacciHeap.FibRawInv.findMin_eq_some {n K_max : ℕ} {s : Lean.IndexedMinPQ.State n} {st : RawState n} (h : FibRawInv n K_max s st) {z : Fin n} (hz : st.minRoot = ↑z + 1) :
      Lean.IndexedMinPQ.findMin s = some (z, st.key z) ∧ s z = some (st.key z) ∧ st.key z ≤ K_max

      When st.minRoot = z.val + 1, IndexedMinPQ.findMin s = some (z, st.key z).