Skip to content
Snippets Groups Projects
DelayMonad.agda 8.51 KiB
Newer Older
{-# OPTIONS --guardedness --rewriting --guarded #-}

 -- to allow opening this module in other files while there are still holes
{-# OPTIONS --allow-unsolved-metas #-}


module Semantics.Adequacy.Coinductive.DelayMonad where

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Function
open import Cubical.Data.Sum
open import Cubical.Data.Unit renaming (Unit to ⊤)
open import Cubical.Data.Nat
open import Cubical.HITs.PropositionalTruncation as PT

open import Cubical.Categories.Category
open import Cubical.Categories.Functor
open import Cubical.Categories.Monad.Base
open import Cubical.Categories.Instances.Sets

open import Cubical.Foundations.Structure

import Cubical.Data.Equality as Eq

open import Common.Preorder.Base
open import Semantics.Adequacy.Coinductive.Delay
open import Semantics.Adequacy.Coinductive.DelayErrorOrdering

private
  variable
    ℓ ℓ' : Level



-- ************************************
--  Utility functions
-- ************************************

private 
  S : Type ℓ -> Type ℓ
  S X = State (X ⊎ ⊤)

  T : Type ℓ -> Type ℓ
  T X = Delay (X ⊎ ⊤)

-- DelayCod→StateCod
DFun→SFun : {Γ X Y : Type ℓ} -> (Γ -> X -> T Y) -> (Γ -> X -> S Y)
DFun→SFun f γ x = view (f γ x)

-- SFun→DFun
SFun→DFun : {Γ X Y : Type ℓ} -> (Γ -> X -> S Y) -> (Γ -> X -> T Y)
SFun→DFun f γ x = fromState (f γ x)


-- ************************************
--  Strong unit and bind
-- ************************************


unit-d : {X : Type ℓ} -> X -> T X
view (unit-d x) = done (inl x)

-- Unit of the strong monad
unitΓ-d : {Γ X : Type ℓ} -> Γ -> X -> T X
unitΓ-d γ x = unit-d x

unitΓ-s : {Γ X : Type ℓ} -> Γ -> X -> S X
unitΓ-s γ x = done (inl x)



strong-bind-d : ∀ {Γ X Y : Type ℓ} -> (Γ -> X -> T Y) -> (Γ -> T X -> T Y)
strong-bind-s : ∀ {Γ X Y : Type ℓ} -> (Γ -> X -> S Y) -> (Γ -> S X -> S Y)

strong-bind-s f γ (done (inl x)) = f γ x
strong-bind-s f γ (done (inr tt)) = done (inr tt)
strong-bind-s f γ (running d) =
  running (strong-bind-d (λ γ' x' -> fromState (f γ' x')) γ d)

(strong-bind-d f γ d) .view = strong-bind-s (λ γ' x' -> view (f γ' x')) γ (view d)


{-
fromState-lem2 : ∀ {Γ X Y Z : Type ℓ} ->
  (f : Γ -> Y -> State Z) -> (g : (Γ -> X -> State Y)) -> (γ : Γ) -> (x : X) ->
  (fromState (strong-bind-s f γ (g γ x))) ≡ strong-bind-d (SFun→DFun f) γ (fromState (g γ x))
fromState-lem2 f g γ x i .view = strong-bind-s f γ (g γ x)
-}

-- ************************************
--  Properties
-- ************************************

-- Left unit

unitL-s : {Γ X : Type ℓ} -> (γ : Γ) -> (s : S X) ->
   (strong-bind-s unitΓ-s) γ s ≡ s
unitL-d : {Γ X : Type ℓ} -> (γ : Γ) -> (d : T X) ->
   (strong-bind-d unitΓ-d) γ d ≡ d
 
unitL-s γ (done (inl x)) = refl
unitL-s γ (done (inr tt)) = refl
unitL-s {Γ = Γ} γ (running d) i = running (goal _ (Eq.pathToEq fromState-lem) i)
  -- cong running ((λ j -> strong-bind-d (fromState-lem j) γ d) ∙ unitL-d γ d)
  where
    fromState-lem : ∀ {Γ X : Type ℓ} -> (λ γ x -> fromState (unitΓ-s γ x)) ≡ unitΓ-d
    fromState-lem {Γ = Γ} {X = X} = funExt λ γ -> funExt (λ x -> aux γ x)
      where
        aux : (γ : Γ) (x : X) -> fromState (unitΓ-s γ x) ≡ unitΓ-d γ x
        aux γ x i .view = done (inl x)

    goal : ∀ f -> f Eq.≡ unitΓ-d -> strong-bind-d f γ d ≡ d
    goal .unitΓ-d Eq.refl = unitL-d γ d

-- NTS: strong-bind-d (λ γ' x' → fromState (unitΓ-s γ' x')) γ d ≡ d 

unitL-d γ d i .view = unitL-s γ (view d) i



-- Right unit

unitR-s : {Γ X Y : Type ℓ} -> (f : Γ -> X -> S Y) -> (γ : Γ) -> (x : X) ->
   strong-bind-s f γ (unitΓ-s γ x) ≡ f γ x
unitR-s f γ x = refl

unitR-d : {Γ X Y : Type ℓ} -> (f : Γ -> X -> T Y) -> (γ : Γ) -> (x : X) ->
   strong-bind-d f γ (unitΓ-d γ x) ≡ f γ x
unitR-d f γ x i .view = unitR-s (λ γ' x' -> view (f γ' x')) γ x i



-- Composition

comp-s : {Γ X Y Z : Type ℓ} -> (f : Γ -> Y -> S Z) -> (g : (Γ -> X -> S Y)) ->
  (γ : Γ) -> (x : X) -> (s : S X) ->
  strong-bind-s f γ (strong-bind-s g γ s) ≡
  strong-bind-s (λ γ' x' -> strong-bind-s f γ' (g γ' x')) γ s
comp-d : {Γ X Y Z : Type ℓ} -> (f : Γ -> Y -> T Z) -> (g : (Γ -> X -> T Y)) ->
  (γ : Γ) -> (x : X) -> (d : T X) ->
  strong-bind-d f γ (strong-bind-d g γ d) ≡
  strong-bind-d (λ γ' x' -> strong-bind-d f γ' (g γ' x')) γ d

comp-s f g γ x (done (inl y)) = refl
comp-s f g γ x (done (inr tt)) = refl
comp-s {Γ = Γ} {X = X} {Z = Z} f g γ x (running d) i =
  running (goal
    (λ γ' x' -> fromState (strong-bind-s f γ' (g γ' x')))
    (Eq.pathToEq (funExt (λ γ' -> funExt λ x' -> lem γ' x'))) i)
  {- cong running (comp-d (SFun→DFun f) (SFun→DFun g) γ x d ∙
    λ j -> strong-bind-d (λ γ' x' -> lem γ' x' j) γ d) -}
  where
    lem : ∀ γ' x' ->
      fromState (strong-bind-s f γ' (g γ' x')) ≡
      strong-bind-d (SFun→DFun f) γ' (SFun→DFun g γ' x')
    (lem γ' x' i) .view = strong-bind-s f γ' (g γ' x')

    goal : ∀ (f' : Γ -> X -> T Z) ->
      f' Eq.≡ (λ γ' x' -> strong-bind-d (SFun→DFun f) γ' (SFun→DFun g γ' x')) ->
      strong-bind-d (λ γ' x' -> fromState (f γ' x')) γ
        (strong-bind-d (λ γ' x' -> fromState (g γ' x')) γ d) ≡
      strong-bind-d f' γ d
    goal .(λ γ' x' → strong-bind-d (SFun→DFun f) γ' (SFun→DFun g γ' x')) Eq.refl =
      comp-d (SFun→DFun f) (SFun→DFun g) γ x d

{-
  Know:
  strong-bind-d (SFun→DFun f) γ (SFun→DFun g γ x) ≡
  fromState (strong-bind-s f γ (g γ x))

  Informally, we have the following chain of equalities:

 strong-bind-d (λ γ' x' → fromState (f γ' x')) γ (strong-bind-d (λ γ' x' → fromState (g γ' x')) γ d) ≡ [by coind hyp]

 strong-bind-d (λ γ' x' → strong-bind-d (SFun→DFun f) γ' (SFun→DFun g γ' x')) γ d ≡ [by lem]
                          ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

 strong-bind-d (λ γ' x' → fromState (strong-bind-s f γ' (g γ' x'))) γ d
                          ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
-}

comp-d f g γ x d i .view = comp-s (DFun→SFun f) (DFun→SFun g) γ x (view d) i




-- ************************************
--  Monotonicity
-- ************************************

{-

-- The operations are monotone with respect to the ordering on Delay
module Monotone (X : Preorder ℓ ℓ') where
  open ResultPreorder X   -- Ordering on ⟨ X ⟩ ⊎ ⊤
  open Ord X              -- Ordering on Delay (⟨ X ⟩ ⊎ ⊤)
  open Alternative (⟨ X ⟩ ⊎ ⊤) -- Function-based definition of Delay


  fromDelay-unit : ∀ x? -> fromDelay (unit-d x?) zero ≡ {!!}
  fromDelay-unit x? = refl

  lem : ∀ x? y? -> terminatesWith (fromDelay (unit-d x?)) y? -> {!!}
  lem x? y? (n , eq) = {!!}

  unit-d-monotone : {Γ : Preorder ℓ ℓ'} -> {x y : ⟨ X ⟩} {γ : ⟨ Γ ⟩} ->
    rel X x y -> (unitΓ-d γ x) ⊑ (unitΓ-d γ y)
  unit-d-monotone x≤y = ∣ {!!} ∣₁



 -- Need lemmas:
 -- FromDelay (unit-d x?) terminates in zero steps.
 --
 -- If fromDelay (unit-d x?) n ≡ inl (inl x), then x? = inl x
 -- More generally: If fromDelay (unit-d x?) ↓ y? , then x? ≡ y?

strong-bind-d-monotone : {Γ X Y : Preorder ℓ ℓ'} ->
  {d d' : T ⟨ X ⟩} -> {γ γ' : ⟨ Γ ⟩} ->
  {f : ⟨ Γ ⟩ -> (⟨ X ⟩) -> T (⟨ Y ⟩)} ->
  rel Γ γ γ' ->
  Ord._⊑_ X d d' ->
  Ord._⊑_ Y (strong-bind-d f γ d) (strong-bind-d f γ d')
strong-bind-d-monotone {d = d} {d' = d'} {γ = γ} {γ' = γ'} {f = f}
  γ≤γ' d≤d' with d .view | d' .view
... | done (inl x) | done (inl x₁) = {!!}
... | done (inl x) | done (inr x₁) = {!!}
... | done (inr x) | done (inl x₁) = {!!}
... | done (inr x) | done (inr x₁) = {!!}
... | done x | running x₁ = {!!}
... | running x | done x₁ = {!!}
... | running x | running x₁ = {!!}

-}





{-

 -- Functor structure
mapState : {X Y : Type ℓ} -> (X -> Y) -> (State X -> State Y)
mapDelay : {X Y : Type ℓ} -> (X -> Y) -> (Delay X -> Delay Y)

mapState f (done x) = done (f x)
mapState f (running d') = running (mapDelay f d')

view (mapDelay f d) = mapState f (view d)


mapIdS : {X : Type ℓ} -> Path (State X -> State X) (mapState (λ x -> x)) (λ x -> x)
mapIdD : {X : Type ℓ} -> Path (Delay X -> Delay X) (mapDelay (λ x -> x)) (λ x -> x)
mapIdS i (done x) = done x
mapIdS i (running d) = running (mapIdD i d)
mapIdD i x .view = mapIdS i (x .view)



-- Monad on Set
DELAY : Monad (SET ℓ)
Functor.F-ob (fst DELAY) x = (Delay ⟨ x ⟩) , isSetDelay (x .snd)
Functor.F-hom (fst DELAY) = mapDelay
Functor.F-id (fst DELAY) = mapIdD
Functor.F-seq (fst DELAY) = {!!}
snd DELAY = {!!}

-}