{-# 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