{-# OPTIONS --no-positivity-check --no-termination-check --allow-unsolved-metas #-} open import Algebra open import Prelude open import Relation.Binary open import WellFounded open import Algebra.Monus open import Data.Maybe module Control.Comonad.IntervalHeap {s} {𝑆 : Type s} (mon : TMAPOM 𝑆) {𝑊 : 𝑆 → Type s → Type s} (comon : GradedComonad (TMAPOM.monoid mon) 𝑊) where open TMAPOM mon open GradedComonad comon renaming (map to cmap) Weighted : (𝑆 → Type a → Type b) → Type a → Type (s ℓ⊔ b) Weighted C A = ∃ w × C w A private variable u v w : 𝑆 module OnFunctor {𝐹 : Type s → Type s} (functor : Functor 𝐹) where open Functor functor renaming (map to fmap) record Cofree⁺ (w : 𝑆) (A : Type s) : Type s where constructor ⟪_⟫ field step : 𝑊 w (A × 𝐹 (Weighted Cofree⁺ A)) open Cofree⁺ public Cofree : Type s → Type s Cofree = Cofree⁺ ε extend′ : (Cofree A → B) → Cofree⁺ w A → Cofree⁺ w B extend′ f x .step = x .step =>>[ ∙ε _ ] λ ys → f ⟪ ys ⟫ , fmap (map₂ (extend′ f)) (snd (extract ys)) extract′ : Cofree A → A extract′ = fst ∘ extract ∘ step traceT : (𝑊 ε A → B) → (𝑊 ε A → 𝐹 (Weighted 𝑊 A)) → 𝑊 w A → Cofree⁺ w B traceT f c r .step = r =>>[ ∙ε _ ] λ rs → f rs , fmap (map₂ (traceT f c)) (c rs) iterT : (𝑊 ε A → 𝐹 (Weighted 𝑊 A)) → 𝑊 ε A → Cofree A iterT = traceT extract ana : (𝐺 : 𝑆 → Type s) → (∀ {w} → 𝐺 w → 𝑊 w (A × 𝐹 (∃ u × 𝐺 u))) → 𝐺 w → Cofree⁺ w A ana 𝐺 alg x .step = cmap (map₂ (fmap (map₂ (ana 𝐺 alg)))) (alg x) module AsHeap (_<*>_ : ∀ {w A B} → 𝑊 w (A → B) → 𝑊 w A → 𝑊 w B) where open import Data.List.Properties using (listFunctor) open import Data.List using (List; _∷_; []) open OnFunctor listFunctor Heap : Type s → Type s Heap = Weighted Cofree⁺ _∪_ : Heap A → Heap A → Heap A (xʷ , xs) ∪ (yʷ , ys) with xʷ ≤|≥ yʷ ... | inl (k , y≡x∙k) = xʷ , ⟪ (step ys =>>[ sym y≡x∙k ] λ { y (x , xs) → x , ((k , ⟪ y ⟫) ∷ xs)}) <*> step xs ⟫ ... | inr (k , x≡y∙k) = yʷ , ⟪ (step xs =>>[ sym x≡y∙k ] λ { x (y , ys) → y , ((k , ⟪ x ⟫) ∷ ys)}) <*> step ys ⟫ merge⁺ : Heap A → List (Heap A) → Heap A merge⁺ x [] = x merge⁺ x₁ (x₂ ∷ []) = x₁ ∪ x₂ merge⁺ x₁ (x₂ ∷ x₃ ∷ xs) = (x₁ ∪ x₂) ∪ merge⁺ x₃ xs merge : List (Heap A) → Maybe (Heap A) merge [] = nothing merge (x ∷ xs) = just (merge⁺ x xs) open import Data.Maybe.Properties using (maybeFunctor) open import Data.Maybe using (mapMaybe) module L = OnFunctor maybeFunctor search : Cofree⁺ w A → L.Cofree⁺ w A search = L.ana (flip Cofree⁺ _) (cmap (map₂ merge) ∘ step) data Tree {a} (A : Type a) : Type a where [_] : A → Tree A _*_ : Tree A → Tree A → Tree A List⁺ : Type → Type List⁺ A = A × List A -- huffman′ : Heap A → Tree A -- huffman′ = {!!} -- data Heap (A : Type s) : Type s where -- _◃_ : (w : 𝑆) → (xs : 𝐹 w (A × List (Heap A))) → Heap A -- extend : (Heap A → B) → Heap A → Heap B -- extend f (w ◃ xs) = w ◃ (xs =>>[ ∙ε w ] (λ ys → f (ε ◃ ys) , Lmap (extend f) (snd (extract ys)))) -- module _ (2-monoid : ∀ {A B w} → 𝐹 w A → 𝐹 w B → 𝐹 w (A × B)) where -- _∪_ : Heap A → Heap A → Heap A -- (xw ◃ xs) ∪ (yw ◃ ys) with xw ≤|≥ yw -- ... | inl (k , p) = xw ◃ map (λ { (y , (x , xs)) → x , (k ◃ y) ∷ xs }) (2-monoid (ys =>>[ sym p ] id) xs) -- ... | inr (k , p) = yw ◃ map (λ { (x , (y , ys)) → y , (k ◃ x) ∷ ys }) (2-monoid (xs =>>[ sym p ] id) ys) -- -- mutual -- -- record Heap (A : Type a) : Type (s ℓ⊔ a) where -- -- inductive; constructor _◃_ -- -- field -- -- hd : A -- -- tl : Next A -- -- record Next {a} (A : Type a) : Type (s ℓ⊔ a) where -- -- coinductive; constructor ⟪_⟫ -- -- field next : Span A -- -- data Span {a} (A : Type a) : Type (s ℓ⊔ a) where -- -- [] : Span A -- -- until : (s : 𝑆) → (s≢ε : s ≢ ε) → (xs : Heap A) → Span A -- -- open Heap public -- -- open Next public -- -- State : Type a → Type _ -- -- State A = 𝑆 → A × 𝑆 -- -- pop′ : (s : 𝑆) → Acc _<_ s → Heap A → A × 𝑆 -- -- pop′ s₂ a xs with xs .tl .next -- -- pop′ s₂ a xs | [] = xs .hd , ε -- -- pop′ s₂ a xs | until s₁ s₁≢ε ys with s₁ ≤? s₂ -- -- pop′ s₂ a xs | until s₁ s₁≢ε ys | no s₁≰s₂ = xs .hd , fst (<⇒≤ s₁≰s₂) -- -- pop′ s₂ (acc wf) xs | until s₁ s₁≢ε ys | yes (k₁ , s₂≡s₁∙k₁) = pop′ k₁ (wf k₁ lemma) ys -- -- where -- -- lemma : k₁ < s₂ -- -- lemma (k₂ , k₁≡s₂∙k₂) = s₁≢ε (zeroSumFree s₁ k₂ (sym (cancel k₁ _ _ p))) -- -- where -- -- p : k₁ ∙ ε ≡ k₁ ∙ (s₁ ∙ k₂) -- -- p = ∙ε k₁ ; k₁≡s₂∙k₂ ; cong (_∙ k₂) s₂≡s₁∙k₁ ; cong (_∙ k₂) (comm s₁ k₁) ; assoc k₁ s₁ k₂ -- -- pop : Heap A → State A -- -- pop xs s = pop′ s (wf s) xs -- -- mutual -- -- stepFrom : State A → (s : 𝑆) → Dec (s ≡ ε) → Span A -- -- stepFrom f s (yes p) = [] -- -- stepFrom f s (no ¬p) = until s ¬p (tabulate (f ∘ (s ∙_))) -- -- tabulate : State A → Heap A -- -- tabulate f = -- -- let x , s = f ε -- -- in x ◃ λ where .next → stepFrom f s (s ≟ ε) -- -- pop-ε : (xs : Heap A) (a : Acc _<_ ε) → pop′ ε a xs .fst ≡ xs .hd -- -- pop-ε xs _ with xs .tl .next -- -- pop-ε xs _ | [] = refl -- -- pop-ε xs _ | until s s≢ε ys with s ≤? ε -- -- pop-ε xs _ | until s s≢ε ys | no s≰ε = refl -- -- pop-ε xs _ | until s s≢ε ys | yes s≤ε = ⊥-elim (s≢ε (antisym s≤ε (positive s))) -- -- -- slide : Heap A → Heap A -- -- -- slide xs with xs .tl .next -- -- -- slide xs | [] = xs -- -- -- slide xs | [] = [] -- -- -- pop-tl : ∀ (x : A) s₁ (s₁≢ε : s₁ ≢ ε) xs s₂ → pop (x ◃ ⟪ until s₁ s₁≢ε xs ⟫) (s₁ ∙ s₂) ≡ pop xs s₂ -- -- -- pop-tl x s₁ s₁≢ε xs s₂ with s₁ ≤? (s₁ ∙ s₂) -- -- -- pop-tl x s₁ s₁≢ε xs s₂ | no s₁≰s₁∙s₂ = ⊥-elim (s₁≰s₁∙s₂ (s₂ , refl)) -- -- -- pop-tl x s₁ s₁≢ε xs s₂ | yes (k , s₁≤s₁∙s₂) = -- -- -- let p = cancel s₁ s₂ k s₁≤s₁∙s₂ -- -- -- in {!!} ; cong (λ w → pop′ s₂ w xs) (isPropAcc {!!} (wf s₂)) -- -- -- seg-leftInv′ : (x : Heap A) → tabulate (pop x) ≡ x -- -- -- seg-leftInv′ x = {!!} -- -- -- mutual -- -- -- seg-leftInv′ : (xs : Heap A) → stepFrom (pop xs) (pop xs ε .snd) (pop xs ε .snd ≟ ε) ≡ xs .tl .next -- -- -- seg-leftInv′ (x ◃ xs) with pop (x ◃ xs) ε .snd ≟ ε -- -- -- seg-leftInv′ (x ◃ xs) | yes s≡ε = {!!} -- -- -- seg-leftInv′ (x ◃ xs) | no s≢ε = {!!} -- -- -- seg-leftInv : (x : Heap A) → tabulate (pop x) ≡ x -- -- -- seg-leftInv (x ◃ xs) i .hd = pop-ε (x ◃ xs) (wf ε) i -- -- -- seg-leftInv (x ◃ xs) i .tl .next = seg-leftInv′ (x ◃ xs) i -- -- -- state-iso : Heap A ⇔ State A -- -- -- state-iso .fun = pop -- -- -- state-iso .inv = tabulate -- -- -- state-iso .rightInv = {!!} -- -- -- state-iso .leftInv = {!!}