Download presentation
Presentation is loading. Please wait.
Published byIwan Sasmita Modified over 5 years ago
1
Compiling Real-Time Functional Reactive Programming (RT-FRP)
Dana N. Xu and Siau-Cheng Khoo National University of Singapore 2/19/2019
2
Compilation Partial evaluation Tupling Contribution:
RT-FRP program Functional Code Partial evaluation Automata Code We develop new techniques in PE and Tupling for compiling to automaton. Tupling Tupled Automaton Code Contribution: Systematic compilation via high-level source to source transformation
3
Contents Reactive System Introduction to RT-FRP
Translating RT-FRP to Functional Code Compiling Functional Code to Automaton Code Conclusion and Future Work 2/19/2019
4
Reactive System Reactive systems have to react to an physical environment which cannot wait. It requires cost (Time & Space) of running a program to be bounded and known before run-time. 2/19/2019
5
Contents Reactive System Introduction to RT-FRP
Translating RT-FRP to Functional Code Compiling Functional Code to Automata Code Conclusion and Future Work 2/19/2019
6
RT-FRP Reactive Part Base Language
Captures the essential ingredients of FRP programs Allows recursion and higher order functions Resource-bounded (both time and space) Base Language Choose a terminating and resource-bounded language FRP consists of combinators to express reactivity to events. Base Language is for programmer specified activities. 2/19/2019
7
RT-FRP Syntax e ::= x | c | () | (e1, e2) | e | | x.e | e1 e2
v ::= c | () | (v1, v2) | v | | x.e a. Base language syntax s, ev ::= input | time | ext e | delay v s | let snapshot x s1 in s2 | s1 switch on x ev in s2 | let continue {kj xj = uj } in s | u u ::= s until <evj kj> b. Reactive language syntax Input: a stream of values from environment. Time: a stream of clock values Figure 2. RT-FRP language syntax 2/19/2019
8
Example 1 - The when operator
when s = let snapshot x1 s in let snapshot x2 delay False s in ext (if x2x1 then () else ) x1 x2 when s Rising edge 2/19/2019
9
Contents Reactive System Introduction to RT-FRP
Translating RT-FRP to Functional Code Compiling Functional Code to Automata Code Conclusion and Future Work 2/19/2019
10
Event and Behavior in RT-FRP
type Behavior a = [Time] [a] Event a Behavior (Maybe a) data Maybe a = Nothing | Just a type Event a = [Time] [Maybe a] Behavior – continuous time-varying behaviors Event – discrete event-based reactivity time t1 t2 t3 t4 t5 t6 t7 … b v1 v2 v3 v4 v5 v6 v7 … … e j1 j4 j5 j7 2/19/2019
11
Stream Based Implementation
time :: Behavior Time time = \ts -> ts delay :: a -> Behavior a -> Behavior a delay v s = \ts -> v:(s ts) ==> :: Event a -> (a->b) -> Event b .|. :: Event a -> Event a -> Event a untilB :: Behavior a -> Event (Behavior a) -> Behavior a switcher :: Behavior a -> 2/19/2019
12
Lifting Lifting values/operations at base level to
stream of values/operations at reactive level. Example 1 lift0 = constantB constantB 5 = [5, 5, 5, …] Example 2 w1 = let snapshot x <- time in ext (x+1) w1 = lift1 (\x -> x+1) time $ is a Haskell infix operator. This is the specific language used in domain specific language. 2/19/2019
13
Translating RT-FRP to Functional Code
[]tr :: RExp -> VEnv -> BExp [ext e]tr = liftk (\v1..vk. e) w1..wk where ([v1..vk], [w1..wk]) =lookup e [delay v s]tr = delay v s’ where s’ = [s] 2/19/2019
14
Compiling RT-FRP to Functional Code
[let snapshot x s1 s2] = … [time] = time [s1 switch on x ev s2] = … [s until <evj => kj>j=1..n] = … [let continue {kj xj = uj}j=1..n in s] = … 2/19/2019
15
Equivalent Functional Representation at Abstract Level
z = let snapshot a delay True x in let snapshot b delay True z in let snapshot c input in ext (if a then b else ((a and b) or c)) z = lift3 (\a->\b->\c-> if a then b else ((a && b) || c)) (delay True x) (delay True z) input x = let snapshot a delay True x in let snapshot b z in ext (if a then False else b) x = lift2 (\a->\b->if a then False else b) (delay True x) z n = let snapshot a delay True x in let snapshot b delay 0 n in ext (if a then 0 else b+1) n = lift2 (\a->\b->if a then 0 else b+1) (delay True x) (delay 0 n) Translate to Translate to Translate to 2/19/2019
16
Contents Reactive System & Synchronous Language Introduction to RT-FRP
Translating RT-FRP to Functional Code Compiling Functional Code to Automata Code Conclusion and Future Work 2/19/2019
17
Our Algorithm to the body of the definition of a signal
Generalize all constants that may result in infinite variations. Apply a.Define configuration with state variables b.Instantiate signals c.Unfold & Unify d.Fold or goto 2a to the body of the definition of a signal 2/19/2019
18
From Previous Example z = lift3 (\a->\b->\c->
if a then b else ((a && b) || c)) (delay True x) (delay True z) input x = lift2 (\a->\b->if a then False else b) (delay True x) z n = lift2 (\a->\b->if a then 0 else b+1) (delay True x) (delay 0 n) 2/19/2019
19
Generalize Integer Constants
n = lift2 (\a->\b->if a then 0 else b+1) (delay True x) (delay 0 n) nconfig-1[c1,c2,c3]: n = lift2 (\a->\b->if a then c1 else b+c2) (delay True x) (delay c3 n) 2/19/2019
20
Instantiate signals Instantiate: x = delay x# x_ n = delay n# n_ [1]
n = lift2 (\a->\b->if a then c1 else b+c2) (delay True x) (delay c3 n) (delay True (delay x# x_)) (delay c3 (delay n# n_)) 2/19/2019
21
Unfold Once and Partial Evaluate
The unfolding rule used is : lift2 (\a->\b -> e) (delay v1 v) (delay w1 w) => delay e[v1/a,w1/b] (lift2 (\a->\b -> e) v w) n = lift2 (\a->\b->if a then c1 else b+c2) (delay True (delay x# x_)) (delay c3 (delay n# n_)) n = delay c1 (lift2 (\a->\b->if a then c1 else b+c2) (delay x# x_) (delay n# n_)) [2] 2/19/2019
22
Unification n = delay n# n_ [1]
n = delay c1 (lift2 (\a->\b->if a then c1 else b+c2) (delay x# x_) (delay n# n_)) [2] n= delay c1 n_ n_ = (lift2 (\a->\b->if a then c1 else b+c2) (delay x# x_) (delay c1 n_)) 2/19/2019
23
Adjust Time Backward (Future Current)
n_ = (lift2 (\a->\b->if a then c1 else b+c2) (delay x# x_) (delay c1 n_)) n = (lift2 (\a->\b->if a then c1 else b+c2) (delay xb x) (delay c1 n)) x# => xb x_ => x n_ => n 2/19/2019
24
Try Folding Folding fails
n = (lift2 (\a->\b->if a then c1 else b+c2) (delay xb x) (delay c1 n)) nconfig-1[c1,c2,c3]: n = lift2 (\a->\b->if a then c1 else b+c2) (delay True x) (delay c3 n) Folding fails 2/19/2019
25
Define a New Configuration
n = (lift2 (\a->\b->if a then c1 else b+c2) (delay xb x) (delay c1 n)) n = delay c1 nconfig-2[c1,c2,c1] nconfig-2[b1,b2,b3]: n = (lift2 (\a->\b->if a then b1 else b+b2) (delay xb x) (delay b3 n)) from n_ original n 2/19/2019
26
Instantiate Instantiate: x = delay x# x_ n = delay n# n_
n =(lift2 (\a->\b->if a then c1 else b+c2) (delay xb x) (delay c3 n) (delay xb (delay x# x_)) (delay c3 (delay n# n_))) 2/19/2019
27
Instantiate Unknown Boolean
case xb == False: n =(lift2 (\a->\b->if a then c1 else b+c2) (delay False (delay x# x_)) (delay c3 (delay n# n_))) n = delay (c3+c2) (lift2 (\a->\b->if a then c1 else b+c2) (delay x# x_) (delay n# n_)) {unification with instantiation n#=c3+c2} (delay x# x_) (delay (c3+c2) n_)) n = delay (c3+c2) nconfig-2[c1,c2,c3+c2] 2/19/2019
28
(cont.) case xb == True: n =(lift2 (\a->\b->if a then c1 else b+c2) (delay True (delay x# x_)) (delay c3 (delay n# n_))) n = delay c1 (lift2 (\a->\b->if a then c1 else b+c2) (delay x# x_) (delay n# n_)) {unification with instantiation n#=c1} (delay x# x_) (delay c1 n_)) n = delay c1 nconfig-2[c1,c2,c1] 2/19/2019
29
Automaton for n nconfig-1[c1,c2,c3]: n=delay c1 nconfig-2[c1,c2,c1]
case xb = False n=delay (c3+c2) nconfig-2[c1,c2,c3+c2] case xb = True Each state has memory. For each transition, the current value of the signal is emitted. Each configuration has its own distinct set of state variables. 2/19/2019
30
Automata for n, x and z 2/19/2019
31
Tupling To combine multiple automata into a single automaton Benefits
More efficient Less control logic More specialization across automata 2/19/2019
32
Tupling Combine three signals together mconfig-111[c1,c2,c3]
(n,x,z)=(nconfig-1[c1,c2,c3],xconfig-1,zconfig-1) = delay (c1,False,True) (nconfig-2[c1,c2,c1],xconfig2,zconfig-2) mconfig-222[c1,c2,c1] Tupling them to form a single automaton so that less logic and computation. 2/19/2019
33
Define, Unfold and Fold (twice)
mconfig-222[c1,c2,c3] st xb =False, zb =True (n,x,z)=(nconfig-2[c1,c2,c3],xconfig-2,zconfig-2) : = delay (c3+c2,True,True) mconfig-233[c1,c2,c3+c2] mconfig-233[c1,c2,c3] st xb =True, zb =True (n,x,z) = (nconfig-2[c1,c2,c3],xconfig-3,zconfig-3) = delay (c1,False,True) mconfig-223[c1,c2,c1] Check correctness later 2/19/2019
34
Define, Unfold and Fold mconfig-223[c1,c2,c3] st xb = False, zb = True
(n,x,z)= (nconfig-2[c1,c2,c3],xconfig-2,zconfig-3) : = delay (c3+c2,z#,input#) mconfig-233a[c1,c2,c3+c2] 2/19/2019
35
Define, Unfold and Fold mconfig-233a[c1,c2,c3] st x#=z#=input# (n,x,z)
= (nconfig-2[c1,c2,c3],xconfig-3,zconfig-3) case x#=z#=False = delay (c3+c2,z#,input#) (nconfig-2[c1,c2,c3+c2],xconfig-3,zconfig-3) =delay (c3+c2,z#,input#) mconfig-233a[c1,c2,c3+c2] case x#=z#=True = delay (c1,False,True) (nconfig-2[c1,c2,c1],xconfig-2,zconfig-3) =delay (c1,False,True) mconfig-223[c1,c2,c1] 2/19/2019
36
Final Tupled Automaton
mconfig-111[c1,c2,c3]: (n,x,z)= delay (c1,False,True) mconfig-222[c1,c2,c1] mconfig-222[c1,c2,c3]: (n,x,z)= delay (c3+c2,True,True) mconfig-233[c1,c2,c3+c2] mconfig-233[c1,c2,c3]: mconfig-223[c1,c2,c1] mconfig-223[c1,c2,c3]: (n,x,z)= delay (c3+c2,input#,input#) mconfig-233a[c1,c2,c3+c2] mconfig-233a[c1,c2,c3] st x#=z#=input# (n,x,z) = (nconfig-2[c1,c2,c3],xconfig-3,zconfig-3) case x#=z#=False = delay (c3+c2,input#,input#) case x#=z#=True =delay (c1,False,True) mconfig-223[c1,c2,c1] 2/19/2019
37
Final Tupled Automaton
2/19/2019
38
Automata for n, x and z 2/19/2019
39
Final Tupled Automaton
2/19/2019
40
Conclusion Introduce an approach to building reactive systems based on RT-FRP A two-stage compiler for RT-FRP RT-FRP Functional Code Functional Code Automaton Partial Evaluation Tupling 2/19/2019
41
Future Work Re-design RT-FRP event-driven deterministic concurrent
compile to hardware 2/19/2019
42
Unfolding Rules .|. :: Event a -> Event a -> Event a
(delay v) .|. (delay w1 w) => delay w1 (v .|. w) (delay (Just a) v) .|. (delay w1 w) => delay (Just a) (v .|. w) ==> :: Event a -> (a->b) -> Event b (delay v) ==> f => (delay (v ==> f)) (delay (Just a) v) ==> f => (delay (Just (f a))) bot) 2/19/2019
43
Unfolding Rules lift2 (\a->\b -> e) (delay v1 v) (delay w1 w)
=> delay e[v1/a,w1/b] (lift (\a b -> e) v w) switcher :: Behavior a->Event (Behavior a)->Behavior a switcher (delay v1 v) (delay w) => delay v1 (switcher v w) switcher (delay v1 v) (delay (Just k) w) => delay v1 (switcher k w) untilB :: Behavior a->Event (Behavior a)->Behavior a untilB (delay v1 v) (delay w) => delay v1 (untilB v w) untilB (delay v1 v) (delay (Just k) w) => delay v1 k 2/19/2019
44
Compiling RT-FRP to Functional Code
extr[s] = let v1..vn = freevar s - if (n=0) then [s] else lams v1..vn where lams = \ v1..vn -> [s] 2/19/2019
45
RT-FRP Example 1 s1 = let snapshot x time in ext (sin x) time value
2/19/2019
46
FRP vs. RT-FRP FRP RT-FRP type Behavior a = Time a
type Event a = [(Time, a)] RT-FRP Event a Behavior (Maybe a) data Maybe a = Nothing | Just a type Behavior a = [Time] [a] type Event a = [Time] [Maybe a] Behavior – continuous time-varying behaviors Event – discrete event-based reactivity 2/19/2019
47
Stream Based Implementation
==> :: Event a -> (a->b) -> Event b e1 ==> f = \ts loop ts (e1 ts) where loop (_:ts) (Nothing:ys) = Nothing:(loop ts ys) loop (_:ts) (Just a:ys) = (Just (f a)):(loop ts ys) fe ==> f = map (map f).fe 2/19/2019
48
Two Schemes for Reactive System Implementation
<Initialize Memory> foreach input_event do <Compute Outputs> <Update Memory> end foreach period do <Read Inputs> a. “Event driven” b. “Sampling” Figure 1. Execution schemes for reactive systems 2/19/2019
49
Stream Based Implementation
time :: Behavior Time time = \ts -> ts delay :: a -> Behavior a -> Behavior a delay v s = \ts -> v:(s ts) ==> :: Event a -> (a->b) -> Event b e ==> f = map (map f) . e 2/19/2019
50
Stream Based Implementation
==> :: Event a -> (a->b) -> Event b e1 ==> f = \ts loop ts (e1 ts) where loop (_:ts) (Nothing:es) = Nothing:(loop ts es) loop (_:ts) (Just a:es) = (Just (f a)):(loop ts es) 2/19/2019
51
Stream Based Implementation
.|. :: Event a -> Event a -> Event a e1 .|. e2 = \ts -> zipWith aux (e1 ts) (e2 ts) where aux Nothing Nothing = Nothing aux (Just x) _ = Just x aux _ (Just x) = Just x 2/19/2019
52
Stream Based Implementation
untilB :: Behavior a -> Event (Behavior a) -> Behavior a b `untilB` e = \ts -> loop ts (b ts) (e ts) where loop (_:ts’) (x:xs’) (Nothing:mb) = x:(loop ts’ xs’ mb) loop ts (x:xs’)(Just bn:_) = x:(bn ts) 2/19/2019
53
Stream Based Implementation
switcher :: Behavior a -> Event (Behavior a) -> Behavior a s `switcher` e = \ts -> loop ts (s ts) (e ts) where loop (_:ts’) (x:xs’) (Nothing:mb) = x:(loop ts’ xs’ mb) loop (_:ts’) (x:xs’) (Just bn:mb) = x:(loop ts’ (bn ts’) mb) 2/19/2019
54
Compiling RT-FRP to Functional Code
[let snapshot x s1 s2] = [s2] ’ where x’ =[s1] ’ ’ = {(x,x’)} [time] = time 2/19/2019
55
Compiling RT-FRP to Functional Code
[s1 switch on x ev s2] = switcher s1’ (ev’ ==> \x -> s2’) where ev’ =[ev] s1’ =[s1] s2’ =[s2] 2/19/2019
56
Compiling RT-FRP to Functional Code
[s until <evj => kj>j=1..n] s’ `untilB` (ev1’ ==> k1’ … .|. evj’ ==> kj’ … .|. evn’ ==> kn’) where evi’ = [evi] s’ = [s] kj’ = lookup kj 2/19/2019
57
Compiling RT-FRP to Functional Code
[let continue {kj xj = uj}j=1..n in s] = [s] ’ where ’ = {(kj,kj’)}j=1..n kj’ = \ xj -> [uj] ’ 2/19/2019
58
RT-FRP Examples 2 S3 = (ext 0) switch on x ev in (ext x)
… 2 … … 2/19/2019
59
Synchronous Programming
Automaton Simple structure Good coverage Efficient Difficult to design by hand Synchronous Programming High level Modularity Simple to re-use and compose Efficiency is not sacrificed The states are the valuations of the memory and each reaction corresponds to a transition of the automaton. Difficult to design automaton by hand, especially for complex systems with a large number of states. Performance of using synchronous programming is as good as carefully hand-written code. 2/19/2019
60
Compilation RT-FRP program Why intermediate functional code is needed?
Easier to validate its correctness Allows High-level s-to-s transformation Functional Code Partial Evaluation to propagate constant values to perform more aggressive specialization Automata Code Tupling to combine mutually dependent automata into a composite automaton Why Automaton? Simple, efficient, expressive [Halbwachs:CAV’98] Tupled Automaton Code 2/19/2019
61
Lifting fb $* xb = \ts zipWith ($) (fb ts) (xb ts))
lift0 = constantB lift1 f b1 = lift0 f $* b1 lift2 f b1 b2 = lift1 f b1 $* b2 lift3 f b1 b2 b3 = lift2 f b1 b2 $* b3 : $ is a Haskell infix operator. This is the specific language used in domain specific language. 2/19/2019
62
Code in RT-FRP(Example)
z = let snapshot a delay True x in let snapshot b delay True z in let snapshot c input in ext (if a then b else ((a and b) or c)) x = let snapshot a delay True x in let snapshot b z in ext (if a then False else b) n = let snapshot a delay True x in let snapshot b delay 0 n in ext (if a then 0 else b+1) 2/19/2019
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.