SLIDE 1 Divide and Recycle: Types and Compilation for a Hybrid Synchronous Language
Albert Benveniste1 Benoît Caillaud1 Timothy Bourke1 Marc Pouzet1,2,3
- 1. INRIA
- 2. Institut Universitaire de France
- 3. École normale supérieure (LIENS)
LCTES 2011, CPS Week, April 11–14, Chicago, IL, USA
SLIDE 2 Motivation
Hybrid Systems Modelers
◮ Platforms for simulation and development ◮ More and more important
◮ Semantics ◮ Efficiency and predictability ◮ Fidelity / Consistency
Simulink Ptolemy . . .
SLIDE 3 Motivation
Hybrid Systems Modelers
◮ Platforms for simulation and development ◮ More and more important
◮ Semantics ◮ Efficiency and predictability ◮ Fidelity / Consistency
Simulink Ptolemy . . . Conservative extension of a synchronous data-flow language
SLIDE 4 Motivation
Hybrid Systems Modelers
◮ Platforms for simulation and development ◮ More and more important
◮ Semantics ◮ Efficiency and predictability ◮ Fidelity / Consistency
Simulink Ptolemy . . . Conservative extension of a synchronous data-flow language
What distinguishes our approach?
◮ Compilation with existing tools
(after source-to-source transformation)
◮ Static typing ◮ Semantics based on non-standard analysis
SLIDE 5
Outline
Background Hybrid Synchronous Language Semantics Compilation Execution Typing Conclusion
SLIDE 6
Modeling
Model discrete systems with data-flow equations Model physical systems with Ordinary Differential Equations (ODEs)
SLIDE 7 Modeling
Model discrete systems with data-flow equations Model physical systems with Ordinary Differential Equations (ODEs) ˙ y (t) = f ( t , y ) instantaneous derivatives variables y (0) = yi initial values
(Causal) First-order ODEs
◮ Causal: inputs on right,
◮ First-order:
- ne equation = one variable
SLIDE 8 Bouncing ball
model
h F = m · a −g = m · d2h(t) dt2 d2h(t) dt2 = −g/m
SLIDE 9 Bouncing ball
model
h F = m · a −g = m · d2h(t) dt2 d2h(t) dt2 = −g/m ˙ v = −g/m v(0) = v0 ˙ h = v h(0) = h0
SLIDE 10 Bouncing ball
model
h F = m · a −g = m · d2h(t) dt2 d2h(t) dt2 = −g/m ˙ v = −g/m v(0) = v0 ˙ h = v h(0) = h0 v(t) = v0 + t (−g/m) .dτ h(t) = h0 + t v(τ) .dτ
SLIDE 11 Bouncing ball
model
h F = m · a −g = m · d2h(t) dt2 d2h(t) dt2 = −g/m ˙ v = −g/m v(0) = v0 ˙ h = v h(0) = h0 v(t) = v0 + t (−g/m) .dτ h(t) = h0 + t v(τ) .dτ Solver f yi approximation
SLIDE 12 Bouncing ball
model
h F = m · a −g = m · d2h(t) dt2 d2h(t) dt2 = −g/m ˙ v = −g/m v(0) = v0 ˙ h = v h(0) = h0 v(t) = v0 + t (−g/m) .dτ h(t) = h0 + t v(τ) .dτ Solver f yi approximation g event! up(-h)
SLIDE 13
Solver execution
t t
SLIDE 14
Solver execution
t t f
SLIDE 15
Solver execution
t t f f
SLIDE 16
Solver execution
t t f f f
SLIDE 17
Solver execution
t t f f f g
SLIDE 18
Solver execution
t t f f f g f g
SLIDE 19 Solver execution
t t f f f g f g f g
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 20 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 21 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 22 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 23 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 24 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g f g
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 25 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g f g f g
- 2. expression crosses zero
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 26 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g f g f g
- 2. expression crosses zero
g
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 27 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g f g f g
- 2. expression crosses zero
g g
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 28 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g f g f g
- 2. expression crosses zero
g g g
◮ Bigger and bigger steps (bound by hmin and hmax)
SLIDE 29 Solver execution
t t f f f g f g f g f g
- 1. approximation error too large
f f f g f g f g
- 2. expression crosses zero
g g g
◮ Bigger and bigger steps (bound by hmin and hmax) ◮ t does not necessarily advance monotonically
◮ Ok for continuous states (managed by solver) ◮ Cannot change state within f or g
SLIDE 30
Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values
SLIDE 31
Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi
SLIDE 32
Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi reset e1 every up(ez1)
SLIDE 33
Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi reset e1 every up(ez1) · · · | en every up(ezn)
SLIDE 34 Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi reset e1 every up(ez1) · · · | en every up(ezn) x = (pre h + 1) every up(e) init ei
without default
SLIDE 35 Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi reset e1 every up(ez1) · · · | en every up(ezn) x = (pre h + 1) every up(e) init ei | purely sync every event
without default
SLIDE 36 Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi reset e1 every up(ez1) · · · | en every up(ezn) x = (pre h + 1) every up(e) default ec init ei | purely sync every event
without default without default with default
SLIDE 37 Basic Hybrid Language
Start with Lucid Synchrone (subset); add first-order ODEs with reset. ˙ x (t) = f ( t , x ) x (0) = xi instantaneous derivatives variables initial values Rather than ˙ x = ed and x(0) = xi, write der x = ed init xi reset e1 every up(ez1) · · · | en every up(ezn) x = (pre h + 1) every up(e) default ec init ei | purely sync every event Very simple: no clocks, no automata, no higher-order
without default without default with default
SLIDE 38 Bouncing ball
program
h ˙ v = −g/m v(0) = v0 ˙ h = v h(0) = h0 reset v to −0.8 · v when h becomes 0
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h)
SLIDE 39
Semantics
reals non-standard reals
R
+ infinitesimals (∂)
⋆R
SLIDE 40
Semantics
reals non-standard reals
R
+ infinitesimals (∂)
⋆R
· · · < t − 3∂ < t − 2∂ < t − ∂ < t < t + ∂ < t + 2∂ < t + 3∂ < · · ·
SLIDE 41 Semantics
reals non-standard reals
R
+ infinitesimals (∂)
⋆R
· · · < t − 3∂ < t − 2∂ < t − ∂ < t < t + ∂ < t + 2∂ < t + 3∂ < · · ·
◮ dense and discrete ◮ base clock for both continuous and discrete behaviors ◮ ∀t.
- t is the previous instant, t• is the next instant
integr#(T)(s)(s0)(hs)(t) = s′(t) where s′(t) = s0(t) if t = min(T) s′(t) = s′(•t) + ∂s(•t) if handler#(T)(hs)(t) = NoEvent s′(t) = v if handler#(T)(hs)(t) = Xcrossing(v) up#(T)(s)(t) = false if t = min(T) up#(T)(s)(t•) = true if (s(•t) ≤ 0) ∧ (s(t) > 0) and (t ∈ T) up#(T)(s)(t•) = false
. . . . . . . . .
SLIDE 42 Semantics
reals non-standard reals
R
+ infinitesimals (∂)
⋆R
· · · < t − 3∂ < t − 2∂ < t − ∂ < t < t + ∂ < t + 2∂ < t + 3∂ < · · ·
◮ dense and discrete ◮ base clock for both continuous and discrete behaviors ◮ ∀t.
- t is the previous instant, t• is the next instant
integr#(T)(s)(s0)(hs)(t) = s′(t) where s′(t) = s0(t) if t = min(T) s′(t) = s′(•t) + ∂s(•t) if handler#(T)(hs)(t) = NoEvent s′(t) = v if handler#(T)(hs)(t) = Xcrossing(v) up#(T)(s)(t) = false if t = min(T) up#(T)(s)(t•) = true if (s(•t) ≤ 0) ∧ (s(t) > 0) and (t ∈ T) up#(T)(s)(t•) = false
. . . . . . . . .
SLIDE 43 Semantics
reals non-standard reals
R
+ infinitesimals (∂)
⋆R
· · · < t − 3∂ < t − 2∂ < t − ∂ < t < t + ∂ < t + 2∂ < t + 3∂ < · · ·
◮ dense and discrete ◮ base clock for both continuous and discrete behaviors ◮ ∀t.
- t is the previous instant, t• is the next instant
integr#(T)(s)(s0)(hs)(t) = s′(t) where s′(t) = s0(t) if t = min(T) s′(t) = s′(•t) + ∂s(•t) if handler#(T)(hs)(t) = NoEvent s′(t) = v if handler#(T)(hs)(t) = Xcrossing(v) up#(T)(s)(t) = false if t = min(T) up#(T)(s)(t•) = true if (s(•t) ≤ 0) ∧ (s(t) > 0) and (t ∈ T) up#(T)(s)(t•) = false
. . . . . . . . .
SLIDE 44 Semantics
reals non-standard reals
R
+ infinitesimals (∂)
⋆R
· · · < t − 3∂ < t − 2∂ < t − ∂ < t < t + ∂ < t + 2∂ < t + 3∂ < · · ·
◮ dense and discrete ◮ base clock for both continuous and discrete behaviors ◮ ∀t.
- t is the previous instant, t• is the next instant
integr#(T)(s)(s0)(hs)(t) = s′(t) where s′(t) = s0(t) if t = min(T) s′(t) = s′(•t) + ∂s(•t) if handler#(T)(hs)(t) = NoEvent s′(t) = v if handler#(T)(hs)(t) = Xcrossing(v) up#(T)(s)(t) = false if t = min(T) up#(T)(s)(t•) = true if (s(•t) ≤ 0) ∧ (s(t) > 0) and (t ∈ T) up#(T)(s)(t•) = false
. . . . . . . . .
SLIDE 45 Compilation
h
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h)
SLIDE 46 Compilation
h
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h) let node ball (z1 , ( lh , lv) , ( ) ) = let rec i = true fby false and dv = (−. g / m) and v = i f i then v0 else i f z1 then −. 0.8 *. lv else lv and dh = v and h = i f i then h0 else lh and upz1 = −. h in ( ( v , h) , upz1, (h, v ) , (dh, dv ) )
SLIDE 47 Compilation
h
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h) let node ball (z1 , ( lh , lv) , ( ) ) = let rec i = true fby false and dv = (−. g / m) and v = i f i then v0 else i f z1 then −. 0.8 *. lv else lv and dh = v and h = i f i then h0 else lh and upz1 = −. h in ( ( v , h) , upz1, (h, v ) , (dh, dv ) )
transform into discrete subset
SLIDE 48 Compilation
h
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h) let node ball (z1 , ( lh , lv) , ( ) ) = let rec i = true fby false and dv = (−. g / m) and v = i f i then v0 else i f z1 then −. 0.8 *. lv else lv and dh = v and h = i f i then h0 else lh and upz1 = −. h in ( ( v , h) , upz1, (h, v ) , (dh, dv ) )
transform continuous variables
SLIDE 49 Compilation
h
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h) let node ball (z1 , ( lh , lv) , ( ) ) = let rec i = true fby false and dv = (−. g / m) and v = i f i then v0 else i f z1 then −. 0.8 *. lv else lv and dh = v and h = i f i then h0 else lh and upz1 = −. h in ( ( v , h) , upz1, (h, v ) , (dh, dv ) )
transform zero-crossings
SLIDE 50 Compilation
h
let hybrid ball ( ) = let rec der v = (−. g / m) init v0 reset (−. 0.8 *. last v) every up(–. h) and der h = v init h0 in ( v , h) let node ball (z1 , ( lh , lv) , ( ) ) = let rec i = true fby false and dv = (−. g / m) and v = i f i then v0 else i f z1 then −. 0.8 *. lv else lv and dh = v and h = i f i then h0 else lh and upz1 = −. h in ( ( v , h) , upz1, (h, v ) , (dh, dv ) )
All continuous parts execute in 1st instant
◮ type system prevents C inside D ◮ no branching or activations
SLIDE 51 Execution (Simulation)
(upz, y, dy) = mainσ (z, y) f (t, y) = let (_, _, dy) = mainσ (false, y) in dy g (t, y) = let (upz, _, _) = mainσ (false, y) in upz d (z, y) = let (upz, y, _) = mainσ (z, y) in (upz, y) DI C D / init zc ¬ zc zc ¬ zc / reinit d f g d
◮ Only d may have side effects ◮ Neither f , nor g may change the (internal) discrete state
SLIDE 52 Typing
Motivation
This compilation/execution scheme only works for some programs!
SLIDE 53 Typing
Motivation
This compilation/execution scheme only works for some programs! We need a type system to:
◮ Reject programs that do not respect the invariant:
◮ discrete computations in
D
◮ continuous evolutions in
C
SLIDE 54 Typing
Motivation
This compilation/execution scheme only works for some programs! We need a type system to:
◮ Reject programs that do not respect the invariant:
◮ discrete computations in
D
◮ continuous evolutions in
C
◮ Reject unreasonable programs
◮ where behavior depends ‘too much’ on simulation parameters
(like the step size, or number of iterations)
SLIDE 55 Typing
Unreasonable programs der y = 1.0 init 0.0 and x = (0.0 → pre x) + y x = 0.0 → ( pre x +. 1.0) and der y = x init 0.0
◮ y is a variable that changes continuously ◮ x is discrete register ◮ The relationship between the two is ill-defined
SLIDE 56 Typing
The type language
bt
::=
float | int | bool | zero t
::=
bt | t × t | β σ
::=
∀β1, ..., βn.t
k
→ t k
::=
D | C | A A D C
SLIDE 57 Typing
The type language
bt
::=
float | int | bool | zero t
::=
bt | t × t | β σ
::=
∀β1, ..., βn.t
k
→ t k
::=
D | C | A A D C
Initial conditions
(+)
:
int × int
A
→ int (=)
:
∀β.β × β
A
→ bool if
:
∀β.bool × β × β
A
→ β pre(.)
:
∀β.β
D
→ β . fby .
:
∀β.β × β
D
→ β up(.)
:
float
C
→ zero
SLIDE 58 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
✪ ✧ ✧
SLIDE 59 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢? der y = · · · and x = · · ·
✪ ✧ ✧
SLIDE 60 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢? der y = · · · and x = · · ·
✪ ✧ ✧
SLIDE 61 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢C x′ =
(0.0 fby (x + 1)) every up(ez) init 0.0
G, H ⊢? der y = · · · and x = · · ·
✪ ✧ ✧
SLIDE 62 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢C x′ =
(0.0 fby (x + 1)) every up(ez) init 0.0
G, H ⊢? der y = · · · and x = · · ·
✪
G, H ⊢?
der y= · · · and x′ = · · ·
✧ ✧
SLIDE 63 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢C x′ =
(0.0 fby (x + 1)) every up(ez) init 0.0
G, H ⊢? der y = · · · and x = · · ·
✪
G, H ⊢C
der y= · · · and x′ = · · ·
✧ ✧
SLIDE 64 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢C x′ =
(0.0 fby (x + 1)) every up(ez) init 0.0
G, H ⊢? der y = · · · and x = · · ·
✪
G, H ⊢C
der y= · · · and x′ = · · ·
✧
G, H ⊢? x = · · ·
and x = · · ·
✧
SLIDE 65 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢C x′ =
(0.0 fby (x + 1)) every up(ez) init 0.0
G, H ⊢? der y = · · · and x = · · ·
✪
G, H ⊢C
der y= · · · and x′ = · · ·
✧
G, H ⊢D x = · · ·
and x = · · ·
✧
SLIDE 66 Typing
G, H ⊢C
der y = 1.0 init 0.0
G, H ⊢D x =
(0.0 fby (x + 1))
G, H ⊢C x′ =
(0.0 fby (x + 1)) every up(ez) init 0.0
G, H ⊢? der y = · · · and x = · · ·
✪
G, H ⊢C
der y= · · · and x′ = · · ·
✧
G, H ⊢D x = · · ·
and x = · · ·
✧
Typing of function body gives its kind k ∈ {C, D, A}: h : float × float
k
→ float × float Less expressive but simpler than ‘per-wire’ kinds, e.g. Simulink j : (floatD) × (floatC) → (floatD) × (floatC)
SLIDE 67 Conclusion
◮ Simple extension of a synchronous data-flow language
◮ Add first-order ODEs ◮ and zero-crossing events
◮ Non-standard semantics
◮ Gives a ‘continuous base clock’ ◮ Simplifies definitions, clarifies certain features
◮ Static block-based typing system
◮ Divide system into continuous and discrete parts
◮ Compilation
◮ Source-to-source transformation ◮ Recycle existing compilers
◮ Execution
◮ Simulate using Sundials CVODE solver
SLIDE 68 Conclusion
◮ Simple extension of a synchronous data-flow language
◮ Add first-order ODEs ◮ and zero-crossing events
◮ Non-standard semantics
◮ Gives a ‘continuous base clock’ ◮ Simplifies definitions, clarifies certain features
◮ Static block-based typing system
◮ Divide system into continuous and discrete parts
◮ Compilation
◮ Source-to-source transformation ◮ Recycle existing compilers
◮ Execution
◮ Simulate using Sundials CVODE solver
SLIDE 69 Conclusion
◮ Simple extension of a synchronous data-flow language
◮ Add first-order ODEs ◮ and zero-crossing events
◮ Non-standard semantics
◮ Gives a ‘continuous base clock’ ◮ Simplifies definitions, clarifies certain features
◮ Static block-based typing system
◮ Divide system into continuous and discrete parts
◮ Compilation
◮ Source-to-source transformation ◮ Recycle existing compilers
◮ Execution
◮ Simulate using Sundials CVODE solver
Ocaml Sundials CVODE interface and compiler available