------------------------------------------------------------------------
-- This approach appears to be both awkward to use and non-trivial to
-- understand
------------------------------------------------------------------------

module Deterministic.LongestPrefix where

open import Data.Nat
open import Data.List
open import Data.Colist hiding ([_])
open import Coinduction
open import Data.Maybe
open import Data.Product
open import Data.Empty
open import Function.Equality
open import Function.Equivalence
open import Relation.Nullary
open import Relation.Binary.PropositionalEquality

open import Deterministic.Expr

-- ms ⊑Trace[ e ] means that ms is a prefix of the trace of e.

infix 4 _⊑Trace[_]

data _⊑Trace[_] : List Msg  Expr  Set where
  []   :  {e}                              []     ⊑Trace[ e        ]
  nop  :  {e ms}   (x : ms ⊑Trace[  e ])  ms     ⊑Trace[ nop    e ]
  tick :  {e m ms} (x : ms ⊑Trace[  e ])  m  ms ⊑Trace[ tick m e ]

-- Note that the trace is the longest colist which is a prefix of the
-- trace.

infix 4 _HasTrace_

_HasTrace_ : Semantics
e HasTrace ms =  {p}  p ⊑Trace[ e ]    fromList p  ms

------------------------------------------------------------------------
-- Examples

possible : nops HasTrace []
possible = equivalent longest (prefix _)
  where
  longest :  {ms}  ms ⊑Trace[ nops ]  fromList ms  []
  longest []      = []
  longest (nop x) = longest x

  prefix :  ms  fromList ms  []  ms ⊑Trace[ nops ]
  prefix []       _  = []
  prefix (m  ms) ()

no-msgs :  {m p}  ¬ m  p ⊑Trace[ nops ]
no-msgs (nop x) = no-msgs x

impossible :  {m ms}  ¬ nops HasTrace (m  ms)
impossible {m} ht = no-msgs (Equivalent.from ht ⟨$⟩ m   [])

ok : ticks HasTrace scissors
ok = equivalent longest (prefix _)
  where
  longest :  {ms}  ms ⊑Trace[ ticks ]  fromList ms  scissors
  longest []       = []
  longest (tick x) =    longest x

  prefix :  ms  fromList ms  scissors  ms ⊑Trace[ ticks ]
  prefix []        _        = []
  prefix (.  ms) (.  p) = tick (prefix ms ( p))