{-# OPTIONS --type-in-type #-}
module Library2 where
open import NeilPrelude
open import RealTime
open import Real
open import SigVecs
open import NaryFRP
open import Library1
open import RSwitch
open import Bool using (not)
switchWhen : {as bs : SVDesc} → {A : Set} → SF as bs → SF bs (E A) → (A → SF as bs) → SF as bs
switchWhen {as} {bs} {A} sf sfe = switch {as} {bs} (_>>>_ {as} {bs} {bs , E A} sf (forkSecond {bs} {E A} sfe))
rswitchWhen : {as bs : SVDesc} → {A : Set} → SF as bs → SF bs (E A) → (A → SF as bs) → SF as bs
rswitchWhen {as} {bs} {A} sf sfe f = rswitch {as} {bs} (_>>>_ {as} {bs} {bs , E A} sf (forkSecond {bs} {E A} sfe)) (λ e → _>>>_ {as} {bs} {bs , E A} (f e) (forkSecond {bs} {E A} sfe))
replace : {as bs : SVDesc} → {A : Set} → SF as bs → (A → SF as bs) → SF (as , E A) bs
replace {as} {bs} {A} sf f = rswitch {as , E A} {bs} (sfFirst {as} {bs} {E A} sf) (λ e → sfFirst {as} {bs} {E A} (f e))
constantC : {as : SVDesc} → {A : Set} → A → SF as (C A)
constantC {as} {A} a = _>>>_ {as} {S A} {C A} (constantS {as} a) fromS
dhold : {A : Set} → A → SF (E A) (C A)
dhold {A} a = _>>>_ {E A} {S A} {C A} (hold a) (dfromS a)
iIntegralS : ℜ → SF (S ℜ) (C ℜ)
iIntegralS x = _>>>_ {S ℜ} {C ℜ} {C ℜ} integralS (liftC (_+_ x))
iIntegralC : ℜ → SF (C ℜ) (C ℜ)
iIntegralC x = _>>>_ {C ℜ} {C ℜ} {C ℜ} integralC (liftC (_+_ x))
sampleC : {A B : Set} → SF (C A , E B) (E A)
sampleC = sampleWithC const
sampleS : {A B : Set} → SF (S A , E B) (E A)
sampleS = sampleWithS const
localTime : {as : SVDesc} → SF as (C ℜ)
localTime {as} = _>>>_ {as} {S ℜ} {C ℜ} (constantS {as} ı) integralS
after : {as : SVDesc} → Time⁺ → SF as (E Unit)
after {as} t = _>>>_ {as} {E Unit} {E Unit} (now {as}) (delayE t)
repeatedly : {as : SVDesc} → Time⁺ → SF as (E Unit)
repeatedly {as} t = rswitchWhen {as} {E Unit} (never {as}) (after {E Unit} t) (λ _ → now {as})
tag : {A B : Set} → A → SF (E B) (E A)
tag a = liftE (const a)
nowTag : {as : SVDesc} → {A : Set} → A → SF as (E A)
nowTag {as} {A} a = _>>>_ {as} {E Unit} {E A} (now {as}) (tag a)
afterTag : {as : SVDesc} → {A : Set} → Time⁺ → A → SF as (E A)
afterTag {as} {A} t a = _>>>_ {as} {E Unit} {E A} (after {as} t) (tag a)
once : {A : Set} → SF (E A) (E A)
once {A} = switch {E A} {E A} (sfFork {E A}) (nowTag {E A})
symLoop : {as bs cs ds : SVDesc} → SF (as , cs) (bs , ds) → SF ds cs → SF as bs
symLoop {as} {bs} {cs} {ds} sff sfb = _>>>_ {as} {bs , ds} {bs} (loop {as} {bs , ds} {cs} sff (_>>>_ {bs , ds} {ds} {cs} (sfSnd {bs} {ds}) sfb)) (sfFst {bs} {ds})
save : {as bs : SVDesc} → {A : Set} → SF as bs → SF (as , E A) (bs , E (SF as bs))
save {as} {bs} {A} sf = _>>>_ {as , E A} {bs , (C _ , E A)} {bs , E _} (_>>>_ {as , E A} {(bs , C _) , E A} {bs , (C _ , E A)} (sfFirst {as} {bs , C _} {E A} (freeze {as} {bs} sf)) (sfAssocR {bs} {C _} {E A})) (sfSecond {bs} {C _ , E A} {E _} sampleC)
saveReplace : {as bs : SVDesc} → {A : Set} → SF as bs → SF ((as , E A) , E (SF as bs)) (bs , E (SF as bs))
saveReplace {as} {bs} {A} sf = replace {as , E A} {bs , E _} (save {as} {bs} sf) (save {as} {bs})
saveResume : {as bs : SVDesc} → {A B : Set} → SF as bs → SF ((as , E A) , E B) bs
saveResume {as} {bs} {A} {B} sf = symLoop {(as , E A) , E B} {bs} {C _} {E _} (_>>>_ {((as , E A) , E B) , C _} {(as , E A) , E _} {bs , E _} (_>>>_ {((as , E A) , E B) , C _} {(as , E A) , E B , C _} {(as , E A) , E _} (sfAssocR {as , E A} {E B} {C _}) (sfSecond {as , E A} {E B , C _} {E _} (_>>>_ {E B , C _} {C _ , E B} {E _} (sfSwap {E B} {C _}) sampleC))) (saveReplace {as} {bs} sf)) (dhold sf)
open import BouncingBall
fallingBall : {as : SVDesc} → Ball → SF as (C Ball)
fallingBall {as} (h , v) = _>>>_ {as} {S _} {C _} (constantS {as} (negate g)) (_>>>_ {S _} {C _} {C _} (iIntegralS v) (_>>>_ {C _} {C _ , C _} {C _} (forkFirst {C _} {C _} (iIntegralC h)) (liftC2 (_,_))))
detectBounce : SF (C Ball) (E Ball)
detectBounce = when detectImpact
elasticBall : {as : SVDesc} → Ball → SF as (C Ball)
elasticBall {as} b = rswitchWhen {as} {C _} (fallingBall {as} b) detectBounce (fallingBall {as} ∘ negateVel)
inelasticBall : {as : SVDesc} → Ball → SF as (C Ball)
inelasticBall {as} b = switchWhen {as} {C _} (fallingBall {as} b) detectBounce (λ _ → constantC {as} (O , O))
resetBall : {as : SVDesc} → (Ball → SF as (C Ball)) → Ball → SF (as , E Ball) (C Ball)
resetBall {as} f b = replace {as} {C _} (f b) f
oneInelasticReset : Ball → SF (E Ball) (C Ball)
oneInelasticReset b = _>>>_ {E _} {E _} {C _} once (_>>>_ {E _} {E _ , E _} {C _} (sfFork {E _}) (resetBall {E _} (inelasticBall {E _}) b))
lamp : {as : SVDesc} → Time⁺ → Bool → SF as (S Bool)
lamp {as} t b = rswitch {as} {S _} (lampAux (t , b)) lampAux
where
lampAux : (Time⁺ × Bool) → SF as (S Bool , E (Time⁺ × Bool))
lampAux (t' , b') = _&&&_ {as} {S _} {E _} (constantS {as} b') (afterTag {as} t' (halfℜ⁺ t' , not b'))
sampleTime : {A : Set} → SF (E A) (E ℜ)
sampleTime = _>>>_ {E _} {C _ , E _} {E _} (forkFirst {E _} {C _} (localTime {E _})) sampleC