open import Relation.Binary
open import Prelude
module Data.Heap {ℓ₁} {Key : Type ℓ₁} {ℓ₂ ℓ₃} (ord : TotalOrder Key ℓ₂ ℓ₃) where
open import Data.List
open import Data.Maybe
open import Relation.Binary.Construct.LowerBound ord
open TotalOrder ord using (_≤|≥_)
open TotalOrder lb-ord hiding (_≤|≥_)
private
variable
u v : Level
U : Key → Type u
V : Key → Type v
record Heap⁺ {v} (lb : ⌊∙⌋) (V : Key → Type v) : Type (v ℓ⊔ ℓ₁ ℓ⊔ ℓ₃) where
inductive; pattern; constructor node
field
key : Key
val : V key
bnd : lb ≤ ⌊ key ⌋
rst : List (Heap⁺ ⌊ key ⌋ V)
open Heap⁺ public
private variable lb : ⌊∙⌋
_∪_ : Heap⁺ lb V → Heap⁺ lb V → Heap⁺ lb V
node kˣ vˣ bˣ rˣ ∪ node kʸ vʸ bʸ rʸ with kˣ ≤|≥ kʸ
... | inl x≤y = node kˣ vˣ bˣ (node kʸ vʸ x≤y rʸ ∷ rˣ)
... | inr y≤x = node kʸ vʸ bʸ (node kˣ vˣ y≤x rˣ ∷ rʸ)
merge⁺ : Heap⁺ lb V → List (Heap⁺ lb V) → Heap⁺ lb V
merge⁺ x [] = x
merge⁺ x₁ (x₂ ∷ []) = x₁ ∪ x₂
merge⁺ x₁ (x₂ ∷ x₃ ∷ xs) = (x₁ ∪ x₂) ∪ merge⁺ x₃ xs
merge : List (Heap⁺ lb V) → Maybe (Heap⁺ lb V)
merge [] = nothing
merge (x ∷ xs) = just (merge⁺ x xs)
popMin⁺ : Heap⁺ lb V → ∃ k × V k × (lb ≤ ⌊ k ⌋) × Maybe (Heap⁺ ⌊ k ⌋ V)
popMin⁺ (node k v b r) = k , v , b , merge r