open import NeilPrelude1
open import Ord1

module Core1 where

-- We need lists of sets

data List1 (S : Set1) : Set1 where
  []      : List1 S
  _∷_     : S  List1 S  List1 S


_++_ : {S : Set1}  List1 S  List1 S  List1 S
[] ++ bs = bs
(a  as) ++ bs = a  (as ++ bs)

[_] : {S : Set1}  S  List1 S
[ s ] = s  []


-- Decoupledness Descriptors -- 

-- Rather than create a datatype for Dec, we use booleans so we can use existing
-- boolean proofs

Dec : Set
Dec = Bool

dec : Dec
dec = false

cau : Dec
cau = true

-- Signal Descriptors --

data SigDesc : Set1 where
  E : Set  SigDesc
  C : Set  SigDesc

SVDesc : Set1
SVDesc = List1 SigDesc

SigRep : SigDesc  Set 
SigRep (C A) = A
SigRep (E A) = Maybe A


data SVRep : List1 SigDesc  Set1 where
  ⟨⟩  : SVRep []
  _∷_ : {a : SigDesc}  {as : SVDesc}  SigRep a  SVRep as  SVRep (a  as)

_+++_ : {as bs : SVDesc}  SVRep as  SVRep bs  SVRep (as ++ bs)
⟨⟩ +++ bs = bs
(a  as) +++ bs = a  (as +++ bs) 

svsplit : {as bs : SVDesc}  SVRep (as ++ bs)  SVRep as 1×1 SVRep bs
svsplit {[]} asbs = ⟨⟩ & asbs
svsplit {_  AS} (a  asbs) with svsplit {AS} asbs
... | as & bs = (a  as) & bs

---------------------------------------------------------------------------------

Time : Set
Time = 

Δt = Time

t0 = 0


-- Signal Function Representation --

infixl 91 _***_
infixl 90 _>>>_


data SF : SVDesc  SVDesc  Dec  Set1 where
  prim    : {as bs : SVDesc}  {State : Set}  (Δt  State  SVRep as  State ×1 SVRep bs)  State     SF as bs cau
  dprim   : {as bs : SVDesc}  {State : Set}  (Δt  State  (SVRep as  State) 1×1 SVRep bs)  State  SF as bs dec
  _>>>_   : {d₁ d₂ : Dec}  {as bs cs : SVDesc}  SF as bs d₁  SF bs cs d₂                            SF as cs (d₁  d₂)
  _***_   : {d₁ d₂ : Dec}  {as bs cs ds : SVDesc}  SF as cs d₁  SF bs ds d₂                         SF (as ++ bs) (cs ++ ds) (d₁  d₂)
  loop    : {d : Dec}  {as bs cs ds : SVDesc}  SF (as ++ cs) (bs ++ ds) d  SF ds cs dec             SF as bs d
  switch  : {d₁ d₂ : Dec}  {as bs : SVDesc}  {e : Set}  SF as (E e  bs) d₁  (e  SF as bs d₂)     SF as bs (d₁  d₂)
  dswitch : {d₁ d₂ : Dec}  {as bs : SVDesc}  {e : Set}  SF as (E e  bs) d₁  (e  SF as bs d₂)     SF as bs (d₁  d₂)
  weaken  : {d d' : Dec}  {as bs : SVDesc}  d  d'  SF as bs d                                      SF as bs d'