{-# OPTIONS --cubical --no-positivity-check --no-termination-check #-}
open import Prelude
open import Algebra
open import Algebra.Monus
open import Relation.Binary
open import Data.Maybe
open import Data.List using (List; _β·_; []; foldr)
module Control.Monad.HeapT
{β} {π : Type β} {πΉ : π β Type β β Type β}
(monoid : Monoid π)
(gmon : GradedMonad monoid πΉ)
where
open Monoid monoid
open GradedMonad gmon
private
variable
w : π
infixr 5 _β·_
infixr 6 _β_
mutual
record Root (A : Type β) : Type β where
coinductive
constructor _β_
field
weight : π
step : πΉ weight (Branch A)
data Node (A : Type β) : Type β where
β_β : A β Node A
β_β : Root A β Node A
data Branch (A : Type β) : Type β where
[] : Branch A
_β·_ : Node A β πΉ Ξ΅ (Branch A) β Branch A
open Root public
Heap : Type β β Type β
Heap A = πΉ Ξ΅ (Branch A)
infixr 5 _++_
_++_ : πΉ w (Branch A) β πΉ Ξ΅ (Branch A) β πΉ w (Branch A)
xs ++ ys =
xs >>=Ξ΅ Ξ» { [] β ys
; (x β· xs) β return (x β· xs ++ ys) }
infixr 1 _>>=α΄Ί_ _>>=α΄΄_
mutual
_>>=α΄Ί_ : Node A β (A β Heap B) β Heap B
β x β >>=α΄Ί f = f x
β x β >>=α΄Ί f = return (β weight x β (step x >>=α΄΄ f) β β· return [])
_>>=α΄΄_ : πΉ w (Branch A) β (A β Heap B) β πΉ w (Branch B)
xs >>=α΄΄ f =
xs >>=Ξ΅ Ξ» { [] β return []
; (x β· xs) β (x >>=α΄Ί f) ++ (xs >>=α΄΄ f) }
returnα΄΄ : A β Heap A
returnα΄΄ x = return (β x β β· return [])
liftα΄΄ : πΉ w A β Heap A
liftα΄΄ xs = return (β _ β map (Ξ» x β β x β β· return []) xs β β· return [])
flatten : πΉ w (Branch A) β πΉ w (List A Γ List (Root A))
flatten xs =
xs >>=Ξ΅ Ξ» { [] β return ([] , [])
; (β x β β· xs) β map (mapβ (x β·_)) (flatten xs)
; (β x β β· xs) β map (mapβ (x β·_)) (flatten xs) }
module PopMin
(_β€|β₯_ : Total (Ξ» x y β β z Γ (y β‘ x β z)))
(decomp : β {A B wβ wβ wβ} β πΉ (wβ β wβ) A β πΉ (wβ β wβ) B β πΉ wβ (πΉ wβ A Γ πΉ wβ B)) where
_βͺ_ : Root A β Root A β Root A
xs βͺ ys with weight xs β€|β₯ weight ys
... | inl (k , wΚΈβ‘wΛ£βk) = weight xs β map (Ξ» { (xs , ys) β β k β ys β β· xs }) (decomp (subst (flip πΉ _) (sym (βΞ΅ _)) (step xs)) (subst (flip πΉ _) wΚΈβ‘wΛ£βk (step ys)))
... | inr (k , wΛ£β‘wΚΈβk) = weight ys β map (Ξ» { (ys , xs) β β k β xs β β· ys }) (decomp (subst (flip πΉ _) (sym (βΞ΅ _)) (step ys)) (subst (flip πΉ _) wΛ£β‘wΚΈβk (step xs)))
ββΊ : Root A β List (Root A) β Root A
ββΊ xβ [] = xβ
ββΊ xβ (xβ β· []) = xβ βͺ xβ
ββΊ xβ (xβ β· xβ β· xs) = (xβ βͺ xβ) βͺ ββΊ xβ xs
β : List (Root A) β Maybe (Root A)
β [] = nothing
β (x β· xs) = just (ββΊ x xs)
popMin : πΉ w (Branch A) β πΉ w (List A Γ Maybe (Root A))
popMin = map (mapβ β) β flatten