{-# OPTIONS --no-positivity-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.Stepped {s} {𝑆 : Type s} {𝑊 : 𝑆 → Type s → Type s} (mon : TMAPOM 𝑆) (comon : GradedComonad (TMAPOM.monoid mon) 𝑊) {𝐹 : Type s → Type s} (functor : Functor 𝐹) where open TMAPOM mon open GradedComonad comon renaming (map to cmap) open Functor functor renaming (map to fmap) CofreeF : Type s → 𝑆 → Type s → Type s CofreeF A w B = 𝑊 w (A × 𝐹 B) functorCofreeF : ∀ {w} → Functor (CofreeF A w) functorCofreeF .Functor.map f = cmap (map₂ (fmap f)) functorCofreeF .Functor.map-id = {!!} functorCofreeF .Functor.map-comp = {!!} module _ {A : Type s} where open import Codata.SegFix commutativeMonoid (CofreeF A) (functorCofreeF {A = A}) public using (Fix; unfold) Cofree⁺ : Type s → 𝑆 → Type s Cofree⁺ A = Fix {A = A} Cofree : Type s → Type s Cofree A = Cofree⁺ A ε private variable u v w : 𝑆 traceT-alg : (𝑊 ε A → B) → (𝑊 ε A → 𝐹 (∃ v × (v ≢ ε) × 𝑊 v A)) → 𝑊 w A → CofreeF B w (∃ v × (v ≢ ε) × 𝑊 v A) traceT-alg f c r = r =>>[ ∙ε _ ] λ rs → f rs , c rs module _ (wf : WellFounded _≺_) where traceT : (𝑊 ε A → B) → (𝑊 ε A → 𝐹 (∃ v × (v ≢ ε) × 𝑊 v A)) → 𝑊 w A → Cofree⁺ B w traceT f c = unfold wf (flip 𝑊 _) (traceT-alg f c) -- extend-alg : (Cofree A → B) → Cofree⁺ A w → CofreeF B w (∃ v × (v ≢ ε) × Cofree⁺ A v) -- extend-alg {w = w} f xs = xs =>>[ ∙ε _ ] (λ ys → f ys , fmap (λ k → fst (k {i = w}) , {!!} , cmap {!!} (snd (k {i = w}))) (snd (extract ys))) -- extend : (Cofree A → B) → Cofree⁺ A w → Cofree⁺ B w -- extend f = unfold wf (Cofree⁺ _) (extend-alg f) -- Weighted : (𝑆 → Type a → Type b) → Type a → Type (s ℓ⊔ b) -- Weighted C A = ∃ w × C w A -- module OnFunctor (functor : Functor s s) 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 -- iterT : (𝑊 ε A → 𝐹 (Weighted 𝑊 A)) → 𝑊 ε A → Cofree A -- iterT = traceT extract -- 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.⟪_⟫ ∘ map (map₂ (mapMaybe (map₂ search) ∘ merge)) ∘ step -- -- 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 = {!!}