Verifying a Lustre Compiler Part 2
Lélio Brun
PARKAS (Inria - ENS) Timothy Bourke, Pierre-Évariste Dagand, Xavier Leroy, Marc Pouzet, Lionel Rieg SYNCHRON 2016
December 7, 2016
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 1 / 19
Verifying a Lustre Compiler Part 2 Llio Brun PARKAS (Inria - ENS) - - PowerPoint PPT Presentation
Verifying a Lustre Compiler Part 2 Llio Brun PARKAS (Inria - ENS) Timothy Bourke, Pierre-variste Dagand, Xavier Leroy, Marc Pouzet, Lionel Rieg SYNCHRON 2016 December 7, 2016 Llio Brun Verifying a Lustre Compiler Part 2 December 7,
Lélio Brun
PARKAS (Inria - ENS) Timothy Bourke, Pierre-Évariste Dagand, Xavier Leroy, Marc Pouzet, Lionel Rieg SYNCHRON 2016
December 7, 2016
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 1 / 19
Introduction
Unannotated Lustre parsing Lustre elaboration N-Lustre normalization SN-Lustre scheduling Obc translation Clight generation Assembly compilation printing (normalized) elaboration / scheduling check fusion optimization
dataflow imperative
Verified Lustre compiler several passes intermediary imperative language: Obc Obc → Clight
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 2 / 19
Introduction
Unannotated Lustre parsing Lustre elaboration N-Lustre normalization SN-Lustre scheduling Obc translation Clight generation Assembly compilation printing (normalized) elaboration / scheduling check fusion optimization
dataflow imperative
Verified Lustre compiler several passes intermediary imperative language: Obc Obc → Clight
Contribution
implementation and correctness proof in Coq
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 2 / 19
Obc Syntax
e := expression | x (local variable) | state(x) (state variable) | c (constant) | ⋄ e (unary operator) | e ⊕ e (binary operator) s := statement | x := e (update) | state(x) := e (state update) | if e then s else s (conditional) | ⇀ x := c(i).m(⇀ e ) (method call) | s; s (composition) | skip (do nothing) cls := declaration | class c { (class) memory ⇀ xty instance ⇀ ic m(⇀ xty) returns (⇀ xty) [var ⇀ xty] { s } }
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 3 / 19
Obc Syntax
✞ ☎
node rect(d: int) returns (y: int) var py: int; let y = py + d; py = 0 fby y; tel node integrator (a: int) returns (v, x: int) let v = rect(a); x = rect(v); tel node excess(max , a: int) returns (e: bool; x: int) var v: int; let (v, x) = integrator (a); e = v > max; tel
✝ ✆ ✞ ☎
class rect { memory py: int; reset () { state(py) := 0 } step(d: int) returns (y: int) { y := state(py) + d; state(py) := y } } class integrator { instance v, x: rect; reset () { rect(v).reset (); rect(x).reset () } step(a: int) returns (v, x: int) { v := rect(v).step(a); x := rect(x).step(v) } } class excess { instance vx: integrator ; reset () { integrator (vx).reset () } step(max , a: int) returns (e: bool , x: int) var v: int { v, x := integrator(vx).step(a); e := v > max } }
✝ ✆
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 4 / 19
Obc Semantics
venv ident → val menv
: ident → val instances : ident → menv menv instances(vx) instances(v) memories(py) instances(x) memories(py)
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 5 / 19
Obc Semantics
me, ve ⊢exp e ⇓ v p, me, ve ⊢st x := e ⇓ me, ve ∪ {x → v} me, ve ⊢exp e ⇓ v p, me, ve ⊢st state(x) := e ⇓ update_mem(me, x, v), ve . . .
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 6 / 19
Generation and proof TranslGeneration of Clight
CompCert’s frontend language block memory model 2 types of variables: local and temporaries 2 semantics variants: parameters as local variables or as temporaries 2 semantics: small and big step
◮ small step: continuations ◮ big step: state (e, le, m)
e local variables environment : ident → block ∗ int le temporaries environment : ident → val m memory : block → int → byte
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 7 / 19
Generation and proof TranslGeneration of Clight
Obc class → Clight structure Obc method → void-returning Clight function
◮ state: pointer self ◮ multiple outputs: pointer out Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 8 / 19
Generation and proof TranslGeneration of Clight
✞ ☎
class rect { memory py : int; [...] } class integrator { instance v, x: rect; [...] } class excess { instance vx: integrator ; [...] step(max , a: int) returns (e: bool , x: int) var v: int { v, x := integrator(vx).step(a); e := v > max } }
✝ ✆ ✞ ☎
struct rect { int py; }; struct integrator { struct rect v; struct rect x; }; struct excess { struct integrator vx; }; [...] struct excess_step { _Bool e; int x; }; void excess_step (struct excess *self , struct excess_step *out , int max , int a) { struct integrator_step vx_step; register int v; integrator_step (&(* self).vx , &vx_step , a); v = vx_step.v; (* out).x = sx_step.x; (* out).e = v > max; }
✝ ✆
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 9 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) me1, ve1
match_states
⊢st s ⇓ me2, ve2 e1, le1, m1
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 10 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) me1, ve1
match_states
⊢st s ⇓ me2, ve2
match_states
e1, le1, m1 ⊢Clight |s|s ⤋ e1, le2, m2
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 10 / 19
Generation and proof Correctness proof
Consequences of CompCert’s memory model: aliasing (overlapping) alignment permissions sizes
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 11 / 19
Generation and proof Correctness proof
Consequences of CompCert’s memory model: aliasing (overlapping) alignment permissions sizes
Solution
use a separation logic formalism
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 11 / 19
Generation and proof Correctness proof
predicate P :
mpred : memory → P , m P ≡ (mpred P) m conjonction m P ∗ Q pure formula m pure (P) ∗ Q ↔ P ∧ m Q
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 12 / 19
Generation and proof Correctness proof
predicate P :
mpred : memory → P , m P ≡ (mpred P) m conjonction m P ∗ Q pure formula m pure (P) ∗ Q ↔ P ∧ m Q P ∗ Q = mfoot = λ b ofs. mfoot P b ofs ∨ mfoot Q b ofs mpred = λ m. mpred P m ∧ mpred Q m ∧ disjoint(mfoot P) (mfoot Q)
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 12 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states =
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states = pure (le(self) = (bs, ofs)) ∗ pure (le(out) = (bo, 0)) ∗ pure (ge(f_c) = coout)
self pointer
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states = pure (le(self) = (bs, ofs)) ∗ pure (le(out) = (bo, 0)) ∗ pure (ge(f_c) = coout) ∗ pure (wt_env ve m) ∗ pure (wt_mem me p c)
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states = pure (le(self) = (bs, ofs)) ∗ pure (le(out) = (bo, 0)) ∗ pure (ge(f_c) = coout) ∗ pure (wt_env ve m) ∗ pure (wt_mem me p c) ∗ staterep p c me bs ofs
memory me ≈ structure pointed by self
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states = pure (le(self) = (bs, ofs)) ∗ pure (le(out) = (bo, 0)) ∗ pure (ge(f_c) = coout) ∗ pure (wt_env ve m) ∗ pure (wt_mem me p c) ∗ staterep p c me bs ofs ∗ blockrep ve coout bo
≈ fields of coout pointed by out
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states = pure (le(self) = (bs, ofs)) ∗ pure (le(out) = (bo, 0)) ∗ pure (ge(f_c) = coout) ∗ pure (wt_env ve m) ∗ pure (wt_mem me p c) ∗ staterep p c me bs ofs ∗ blockrep ve coout bo ∗ varsrep m ve le
parameters and local variables ≈ temporaries
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
Obc : (me, ve) ; Clight : (e, le, m) match_states = pure (le(self) = (bs, ofs)) ∗ pure (le(out) = (bo, 0)) ∗ pure (ge(f_c) = coout) ∗ pure (wt_env ve m) ∗ pure (wt_mem me p c) ∗ staterep p c me bs ofs ∗ blockrep ve coout bo ∗ varsrep m ve le ∗ subrep_range e
subcalls output structures allocation
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py staterep excess menv bs ofs
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py staterep integrator menv.instances(vx) bs (ofs + δexcess
vx
)
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py staterep rect menv.instances(vx).instances(v) bs (ofs + δexcess
vx
+ δintegrator
v
)
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py staterep rect menv.instances(vx).instances(x) bs (ofs + δexcess
vx
+ δintegrator
x
)
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py contains int32s bs (ofs + δexcess
vx
+ δintegrator
v
+ δrect
py )
⌈menv.instances(vx).instances(v).memories(py)⌉
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
menv instances(vx) instances(v) memories(py) instances(x) memories(py) excess integrator vx rect v int py rect x int py contains int32s bs (ofs + δexcess
vx
+ δintegrator
x
+ δrect
py )
⌈menv.instances(vx).instances(x).memories(py)⌉
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 14 / 19
Generation and proof Correctness proof
staterep [ ] c me bs ofs = ⊥
∗
staterep (class k{. . . } :: p) c me bs ofs = staterep p c me bs ofs if k = c staterep (class c{⇀ xty ⇀ ik . . . } :: p) c me bs ofs =
⇀
xty
contains ty bs (ofs + field_offset(x, ⇀ xty · ⇀ ik )) ⌈me.memories(x)⌉
⇀
ik
staterep p l me.instances(k) bs (ofs + field_offset(i, ⇀ xty · ⇀ ik ))
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 15 / 19
Generation and proof Correctness proof
frame rule “emulation”: m P ∗ F → hypotheses → ∃m′, properties ∧ m′ P ′ ∗ F proof structure : simultaneous inductions (function calls, function bodies)
; x := e ; x := C.f σ (e) ; x := e skip ; x = e ; ; C_f (σ, o, e) ; x = o.y1 x = o.y2 ; x = e Sskip
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 16 / 19
Generation and proof Correctness proof
frame rule “emulation”: m P ∗ F → hypotheses → ∃m′, properties ∧ m′ P ′ ∗ F proof structure : simultaneous inductions (function calls, function bodies)
; x := e ; x := C.f σ (e) ; x := e skip ; x = e ; ; C_f (σ, o, e) ; x = o.y1 x = o.y2 ; x = e Sskip
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 16 / 19
Generation and proof Correctness proof
frame rule “emulation”: m P ∗ F → hypotheses → ∃m′, properties ∧ m′ P ′ ∗ F proof structure : simultaneous inductions (function calls, function bodies)
; x := e ; x := C.f σ (e) ; x := e skip ; x = e ; ; C_f (σ, o, e) ; x = o.y1 x = o.y2 ; x = e Sskip
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 16 / 19
Generation and proof Correctness proof
frame rule “emulation”: m P ∗ F → hypotheses → ∃m′, properties ∧ m′ P ′ ∗ F proof structure : simultaneous inductions (function calls, function bodies)
; x := e ; x := C.f σ (e) ; x := e skip ; x = e ; ; C_f (σ, o, e) ; x = o.y1 x = o.y2 ; x = e Sskip s p e c i a l i z e d i n v a r i a n t
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 16 / 19
Generation and proof Correctness proof
frame rule “emulation”: m P ∗ F → hypotheses → ∃m′, properties ∧ m′ P ′ ∗ F proof structure : simultaneous inductions (function calls, function bodies)
; x := e ; x := C.f σ (e) ; x := e skip ; x = e ; ; C_f (σ, o, e) ; x = o.y1 x = o.y2 ; x = e Sskip i n d u c t i
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 16 / 19
Generation and proof Correctness proof
me, ve
match_states
⊢st state(x) := a ⇓ me ′, ve
match_states
e, le, m ⊢s (∗self).x = |a|e ⤋ e, le, m′
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 17 / 19
Generation and proof Correctness proof
me, ve
match_states
⊢st state(x) := a ⇓ me ′, ve
match_states
e, le, m ⊢s (∗self).x = |a|e ⤋ e, le, m′
le(self) = (bs, ofs) . . . e, le, m ⊢e
∗self ⤋ (bs, ofs)
match_states field_offset(x, . . . ) = δx
staterep_field_offset
e, le, m ⊢lv (∗self).x ⤋ bs, ofs + δx
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 17 / 19
Generation and proof Correctness proof
me, ve
match_states
⊢st state(x) := a ⇓ me ′, ve
match_states
e, le, m ⊢s (∗self).x = |a|e ⤋ e, le, m′
le(self) = (bs, ofs) . . . e, le, m ⊢e
∗self ⤋ (bs, ofs)
match_states field_offset(x, . . . ) = δx
staterep_field_offset
e, le, m ⊢lv (∗self).x ⤋ bs, ofs + δx me, ve ⊢exp a ⇓ v e, le, m ⊢e |a|e ⤋ v
expr_eval_simu
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 17 / 19
Generation and proof Correctness proof
me, ve
match_states
⊢st state(x) := a ⇓ me ′, ve
match_states
e, le, m ⊢s (∗self).x = |a|e ⤋ e, le, m′
le(self) = (bs, ofs) . . . e, le, m ⊢e
∗self ⤋ (bs, ofs)
match_states field_offset(x, . . . ) = δx
staterep_field_offset
e, le, m ⊢lv (∗self).x ⤋ bs, ofs + δx me, ve ⊢exp a ⇓ v e, le, m ⊢e |a|e ⤋ v
expr_eval_simu
match_states store(m, bs, ofs + δx, v) = m ′ match_states_assign_state
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 17 / 19
Conclusion
size:
◮ translation: 300 loc ◮ separation: 2000 loc ◮ correctness: 3300 loc
memory models correspondence: separation logic
certified Lustre compilation
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 18 / 19
Conclusion
Unannotated Lustre parsing Lustre elaboration N-Lustre normalization SN-Lustre scheduling Obc translation Clight generation Assembly compilation printing (normalized) elaboration / scheduling check fusion optimization
dataflow imperative
behavior_asm : wc_global G → wt_global G → wt_io G main ins outs → sem_node G main ins outs → compile G main = OK P → (∀ t, ¬ program_behaves (Asm.semantics P) (Diverges t)) → ∃T, program_behaves (Asm.semantics P) (Reacts T) ∧ bisim_io G main ins outs T
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 19 / 19
complete the toolchain
PhD: semantics, automata, reset
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 1 / 5
synchronous languages, Lustre [Ben+03; Cas+87; Bie+08; Aug13; Aug+14; Bou+16] certified compilation: CompCert [BDL06; Ler09a; Ler09b] automatic proof of a compiler [CG15] denotational semantics [Chl07; BKV09; BH09]
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 2 / 5
[Ben+03] Albert Benveniste, Paul Caspi, Stephen A. Edwards, Paul Le Guernic, Nicolas Halbwachs, and Robert De Simone. “The synchronous languages 12 years later.” In: proceedings of the IEEE. Vol. 91. 1. Jan. 2003,
[Cas+87] Paul Caspi, Nicolas Halbwachs, Daniel Pilaud, and John Alexander Plaice. “LUSTRE: A declarative language for programming synchronous systems.” In: POPL’87. ACM. Jan. 1987, pp. 178–188. [Bie+08] Dariusz Biernacki, Jean-Louis Colaço, Grégoire Hamon, and Marc Pouzet. “Clock-directed Modular Code Generation of Synchronous Data-flow Languages.” In: ACM International Conference on Languages, Compilers, and Tools for Embedded Systems (LCTES). Tucson, Arizona, June 2008. [Aug13] Cédric Auger. “Compilation certifiée de SCADE/LUSTRE.” PhD thesis. Orsay, France: Univ. Paris Sud 11, Apr. 2013. [Aug+14] Cédric Auger, Jean-Louis Colaço, Grégoire Hamon, and Marc Pouzet. “A Formalization and Proof of a Modular Lustre Code Generator.” En préparation. 2014.
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 3 / 5
[Bou+16] Timothy Bourke, Pierre-Évariste Dagand, Marc Pouzet, and Lionel Rieg. “Verifying Clock-Directed Modular Code Generation for Lustre.” En préparation. 2016. [BDL06] Sandrine Blazy, Zaynah Dargaye, and Xavier Leroy. “Formal verification of a C compiler front-end.” In: FM 2006: Int. Symp. on Formal Methods volume 4085 de LNCS (2006), pp. 460–475. [Ler09a] Xavier Leroy. “A formally verified compiler back-end.” In: Journal of Automated Reasoning 43.4 (2009), pp. 363–446. [Ler09b] Xavier Leroy. “Formal verification of a realistic compiler.” In: Comms. ACM 52.7 (2009), pp. 107–115. [CG15] Martin Clochard and Léon Gondelman. “Double WP : Vers une preuve automatique d’un compilateur.” In: Journées Francophones des Langages
[Chl07] Adam Chlipala. “A certified type-preserving compiler from lambda calculus to assembly language.” In: Programming Language Design and
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 4 / 5
[BKV09] Nick Benton, Andrew Kennedy, and Carsten Varming. “Some domain theory and denotational semantics in Coq.” In: Theorem Proving in Higher Order Logics. volume 5674 de LNCS. 2009, pp. 115–130. [BH09] Nick Benton and Chung-Kil Hur. “Biorthogonality, step-indexing and compiler correctness.” In: International Conference on Functional
Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 5 / 5