{-# OPTIONS --cubical --safe #-}
open import Algebra
open import Relation.Binary
open import Algebra.Monus
open import Level
module Data.MonoidalHeap {s} {𝑆 : Type s} (monus : TMPOM 𝑆) where
open TMPOM monus
open import Prelude
open import Data.List using (List; _∷_; [])
import Data.Nat as ℕ
import Data.Nat.Properties as ℕ
𝒮 : Type s
𝒮 = 𝑆 → 𝑆
⟦_⇑⟧ : 𝑆 → 𝒮
⟦_⇑⟧ = _∙_
⟦_⇓⟧ : 𝒮 → 𝑆
⟦ x ⇓⟧ = x ε
infixl 10 _⊙_
_⊙_ : (𝑆 → A) → 𝑆 → 𝑆 → A
f ⊙ x = λ y → f (x ∙ y)
infixr 6 _∹_&_
data Heap (V : 𝑆 → Type a) : Type (a ℓ⊔ s) where
[] : Heap V
_∹_&_ : (key : 𝑆) (val : V key) (children : List (Heap (V ⊙ key))) → Heap V
Heap⋆ : (V : 𝑆 → Type a) → Type (a ℓ⊔ s)
Heap⋆ V = List (Heap V)
private
variable
v : Level
V : 𝑆 → Type v
⊙ε : V ≡ V ⊙ ε
⊙ε {V = V} i x = V (sym (ε∙ x) i)
lemma : ∀ x y k → x ≡ y ∙ k → ⟦ x ⇑⟧ ≡ ⟦ y ⇑⟧ ∘ ⟦ k ⇑⟧
lemma x y k x≡y∙k i z = (cong (_∙ z) x≡y∙k ; assoc y k z) i
merge : Heap V → Heap V → Heap V
merge [] ys = ys
merge (x ∹ xv & xs) [] = x ∹ xv & xs
merge {V = V} (x ∹ xv & xs) (y ∹ yv & ys) with x ≤|≥ y
... | inl (k , x≤y) = x ∹ xv & (k ∹ subst V x≤y yv & subst (List ∘ Heap ∘ _∘_ V) (lemma y x k x≤y) ys ∷ xs)
... | inr (k , x≥y) = y ∹ yv & (k ∹ subst V x≥y xv & subst (List ∘ Heap ∘ _∘_ V) (lemma x y k x≥y) xs ∷ ys)
mergeQs⁺ : Heap V → Heap⋆ V → Heap V
mergeQs⁺ x₁ [] = x₁
mergeQs⁺ x₁ (x₂ ∷ []) = merge x₁ x₂
mergeQs⁺ x₁ (x₂ ∷ x₃ ∷ xs) = merge (merge x₁ x₂) (mergeQs⁺ x₃ xs)
mergeQs : Heap⋆ V → Heap V
mergeQs [] = []
mergeQs (x ∷ xs) = mergeQs⁺ x xs
singleton : ∀ x → V x → Heap V
singleton x xv = x ∹ xv & []
insert : ∀ x → V x → Heap V → Heap V
insert x xv = merge (singleton x xv)
minView : Heap V → Maybe (∃ p × V p × Heap (V ⊙ p))
minView [] = nothing
minView (x ∹ xv & xs) = just (x , xv , mergeQs xs)
variable
v₁ v₂ : Level
V₁ : 𝑆 → Type v₁
V₂ : 𝑆 → Type v₂
mutual
maps : (∀ {x} → V₁ x → V₂ x) → Heap⋆ V₁ → Heap⋆ V₂
maps f [] = []
maps f (x ∷ xs) = map f x ∷ maps f xs
map : (∀ {x} → V₁ x → V₂ x) → Heap V₁ → Heap V₂
map f [] = []
map f (k ∹ v & xs) = k ∹ f v & maps f xs
mutual
size : Heap V → ℕ
size [] = zero
size (_ ∹ _ & xs) = suc (sizes xs)
sizes : Heap⋆ V → ℕ
sizes [] = 0
sizes (x ∷ xs) = size x ℕ.+ sizes xs
open import Data.Maybe using (maybe)
open import Path.Reasoning
open import Cubical.Foundations.Prelude using (substRefl)
lemma₂ : ∀ {x y : 𝑆 → 𝑆} xs (p : x ≡ y) → sizes (subst (List ∘ Heap ∘ _∘_ V) p xs) ≡ sizes xs
lemma₂ {V = V} xs = J (λ _ p → sizes (subst (List ∘ Heap ∘ _∘_ V) p xs) ≡ sizes xs) (cong sizes (substRefl {B = List ∘ Heap ∘ _∘_ V} xs))
merge-size : (xs ys : Heap V) → size (merge xs ys) ≡ size xs ℕ.+ size ys
merge-size [] ys = refl
merge-size (x ∹ xv & xs) [] = sym (ℕ.+-idʳ _)
merge-size {V = V} (x ∹ xv & xs) (y ∹ yv & ys) with x ≤|≥ y
merge-size {V = V} (x ∹ xv & xs) (y ∹ yv & ys) | inr (k , x≥y) =
suc (suc (sizes (subst (List ∘ Heap ∘ _∘_ V) (lemma x y k x≥y) xs)) ℕ.+ sizes ys) ≡˘⟨ ℕ.+-suc _ (sizes ys) ⟩
suc (sizes (subst (List ∘ Heap ∘ _∘_ V) (lemma x y k x≥y) xs)) ℕ.+ suc (sizes ys) ≡⟨ cong (ℕ._+ suc (sizes ys)) (cong suc (lemma₂ {V = V} xs (lemma x y k x≥y))) ⟩
suc (sizes xs) ℕ.+ suc (sizes ys) ∎
merge-size {V = V} (x ∹ xv & xs) (y ∹ yv & ys) | inl (k , x≤y) =
suc (suc (sizes (subst (List ∘ Heap ∘ _∘_ V) (lemma y x k x≤y) ys)) ℕ.+ sizes xs) ≡˘⟨ ℕ.+-suc _ (sizes xs) ⟩
suc (sizes (subst (List ∘ Heap ∘ _∘_ V) (lemma y x k x≤y) ys)) ℕ.+ suc (sizes xs) ≡⟨ cong (ℕ._+ suc (sizes xs)) (cong suc (lemma₂ {V = V} ys (lemma y x k x≤y))) ⟩
suc (sizes ys) ℕ.+ suc (sizes xs) ≡⟨ ℕ.+-comm (suc (sizes ys)) (suc (sizes xs)) ⟩
suc (sizes xs) ℕ.+ suc (sizes ys) ∎
mutual
minViewSizes : (xs : Heap⋆ V) → sizes xs ≡ size (mergeQs xs)
minViewSizes [] = refl
minViewSizes (x ∷ xs) = minViewSizes⁺ x xs
minViewSizes⁺ : (x : Heap V) → (xs : Heap⋆ V) → sizes (x ∷ xs) ≡ size (mergeQs⁺ x xs)
minViewSizes⁺ x₁ [] = ℕ.+-idʳ _
minViewSizes⁺ x₁ (x₂ ∷ []) = cong (λ z → size x₁ ℕ.+ z) (ℕ.+-idʳ _) ; sym (merge-size x₁ x₂)
minViewSizes⁺ x₁ (x₂ ∷ x₃ ∷ xs) =
size x₁ ℕ.+ (size x₂ ℕ.+ sizes (x₃ ∷ xs)) ≡˘⟨ ℕ.+-assoc (size x₁) (size x₂) (sizes (x₃ ∷ xs)) ⟩
(size x₁ ℕ.+ size x₂) ℕ.+ sizes (x₃ ∷ xs) ≡⟨ cong ((size x₁ ℕ.+ size x₂) ℕ.+_) (minViewSizes⁺ x₃ xs) ⟩
(size x₁ ℕ.+ size x₂) ℕ.+ size (mergeQs⁺ x₃ xs) ≡˘⟨ cong (ℕ._+ size (mergeQs⁺ x₃ xs)) (merge-size x₁ x₂) ⟩
size (merge x₁ x₂) ℕ.+ size (mergeQs⁺ x₃ xs) ≡˘⟨ merge-size (merge x₁ x₂) (mergeQs⁺ x₃ xs) ⟩
size (merge (merge x₁ x₂) (mergeQs⁺ x₃ xs)) ∎
minViewSize : (xs : Heap V) → size xs ≡ maybe zero (suc ∘ size ∘ snd ∘ snd) (minView xs)
minViewSize [] = refl
minViewSize (x ∹ xv & xs) = cong suc (minViewSizes xs)
zer : Heap⋆ V
zer = []
one : Heap⋆ V
one = [] ∷ []
open import Data.List using (_++_; concatMap)
_<+>_ : Heap⋆ V → Heap⋆ V → Heap⋆ V
_<+>_ = _++_
multIn : (p : 𝑆 → 𝑆) → (c : ∀ {x y} → V (p x) → V y → V (p (x ∙ y))) → (V ⇒ V ∘ p) → Heap⋆ (V ∘ p) → Heap⋆ V → Heap⋆ (V ∘ p)
multIn {V = V} p c f [] ys = []
multIn {V = V} p c f ([] ∷ xs) ys = maps f ys ++ multIn p c f xs ys
multIn {V = V} p c f (x ∹ xv & xc ∷ xs) ys = x ∹ xv & multIn (p ∘ ⟦ x ⇑⟧) (λ v₁ v₂ → subst V (cong p (assoc x _ _)) (c v₁ v₂)) (c xv) xc ys ∷ multIn p c f xs ys
appl : (∀ {x y} → V x → V y → V (x ∙ y)) → Heap⋆ V → Heap⋆ V → Heap⋆ V
appl {V = V} f xs ys = multIn {V = V} id f id xs ys