\begin{code} {-# OPTIONS --safe #-} open import Prelude open import Algebra open import Algebra.Monus module Codata.Bush {W : Type} (mon : WellFoundedMonus W) where open WellFoundedMonus mon open Weight (weight W tapom) open import Data.Weighted ⊕-semigroup hiding (⟪_⟫) open import Data.Weighted.Monad (weight W tapom) hiding (_>>=_; return) import Data.Weighted.Monad (weight _ tapom) as WB open import Codata.Chain W record Forest∞ (A : Type) : Type where coinductive; constructor ⟪_⟫ field out : (W × List (Forest∞ A)) ⊎ A open Forest∞ public Forest : Type → Type Forest = List ∘ Forest∞ private variable s : W foldWeight : (A → Weighted B) → List A → Weighted B foldWeight f = foldr (_∪_ ∘ f) ⟅⟆ module _ {A : Type} {s : W} where open Reasoning mutual depth : ∀ w → Acc [ s ]_≺_ w → Forest A → Weighted A depth w wf = foldr (_∪_ ∘ (step w wf ▿ return) ∘ out) ⟅⟆ where return = WB.return step : ∀ w → Acc [ s ]_≺_ w → W × Forest A → Weighted A step w wf (v , _) with s ≤? v | v ≤? w ... | no _ | _ = ⟅⟆ ... | _ | no _ = ⟅⟆ step w (acc wf) (v , x) | yes s≤v | yes (k , w≡v∙k) = depth k (wf k ≲[ ≤[ ≤-cong k s≤v ] ≲; ≡[ comm k v ] ≲; ≡[ sym w≡v∙k ] ]) x \end{code} %<*cutoff-sig> \begin{code}[number=code:cutoff-sig] _∣_⊢_ : Forest A → Step → W → Weighted A \end{code} %</cutoff-sig> \begin{code} xs ∣ s ⊢ w = depth w (well-founded s w) xs Equiv-UpTo : Forest A → Forest A → Type \end{code} %<*equiv-def> \begin{code} Equiv-UpTo xs ys = ∀ s w → xs ∣ s ⊢ w ≡ ys ∣ s ⊢ w \end{code} %</equiv-def> \begin{code} Bush : Type → Type \end{code} %<*bush> \begin{code}[number=bush] Bush A = Forest A / Equiv-UpTo \end{code} %</bush> \begin{code} open import Data.Link W \end{code} %<*merge> \begin{code} _⋈_ : W × Forest A → W × Forest A → W × Forest A (wₗ , ls) ⋈ (wᵣ , rs) with wₗ ≤|≥ wᵣ ... | inl (wᵣ∸wₗ , _) = wₗ , ⟪ inl (wᵣ∸wₗ , rs) ⟫ ∷ ls ... | inr (wₗ∸wᵣ , _) = wᵣ , ⟪ inl (wₗ∸wᵣ , ls) ⟫ ∷ rs \end{code} %</merge> \begin{code} merges⁺ : W × Forest A → List (W × Forest A) → W × Forest A merges⁺ x₁ [] = x₁ merges⁺ x₁ (x₂ ∷ []) = x₁ ⋈ x₂ merges⁺ x₁ (x₂ ∷ x₃ ∷ xs) = (x₁ ⋈ x₂) ⋈ merges⁺ x₃ xs \end{code} %<*merges-sig> \begin{code} merges : List (W × Forest A) → Link (Forest A) \end{code} %</merges-sig> \begin{code} merges [] = nothing merges (x ∷ xs) = just (merges⁺ x xs) \end{code} %<*popMin> \begin{code} popMin : Forest A → List A × Link (Forest A) popMin = map₂ merges ∘ swap ∘ partition out \end{code} %</popMin> %<*search> \begin{code} search : Forest A → Chain (List A) search = ana popMin \end{code} %</search>