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
Introduction Context (normalized) elaboration / scheduling check parsing elaboration normalization scheduling Unannotated Lustre N-Lustre SN-Lustre Lustre dataflow translation imperative fusion optimization Obc Verified Lustre compiler generation several passes intermediary imperative language: Obc Clight Obc � → Clight compilation Assembly printing Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 2 / 19
Introduction Context (normalized) elaboration / scheduling check parsing elaboration normalization scheduling Unannotated Lustre N-Lustre SN-Lustre Lustre dataflow translation imperative fusion optimization Obc Verified Lustre compiler generation several passes intermediary imperative language: Obc Clight Obc � → Clight compilation Contribution Assembly implementation and correctness proof in Coq printing Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 2 / 19
Obc Syntax Obc: Abstract Syntax s := statement e := expression | x := e (update) | x (local variable) | state ( x ) := e (state update) | state ( x ) (state variable) | if e then s else s (conditional) | c (constant) ⇀ x := c ( i ) . m ( ⇀ | e ) (method call) | ⋄ e (unary operator) | (composition) s ; s | e ⊕ e (binary operator) | skip (do nothing) cls := declaration | class c { (class) memory ⇀ x ty instance ⇀ i c m ( ⇀ x ty ) returns ( ⇀ x ty ) [var ⇀ x ty ] { s } } Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 3 / 19
Obc Syntax Example ✞ ☎ ✞ ☎ node rect(d: int) returns (y: int) class rect { var py: int; memory py: int; let reset () { state(py) := 0 } y = py + d; step(d: int) returns (y: int) { py = 0 fby y; y := state(py) + d; tel state(py) := y } node integrator (a: int) returns (v, x: int) } let v = rect(a); class integrator { x = rect(v); instance v, x: rect; tel reset () { rect(v).reset (); node excess(max , a: int) rect(x).reset () returns (e: bool; x: int) } var v: int; step(a: int) returns (v, x: int) { let v := rect(v).step(a); (v, x) = integrator (a); x := rect(x).step(v) e = v > max; } tel } ✝ ✆ 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 State and memory model menv instances(vx) venv � ident → val � memories : ident → val menv � instances(v) instances(x) instances : ident → menv memories(py) memories(py) Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 5 / 19
Obc Semantics Statements rules 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 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 Generation function 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 Example ✞ ☎ ✞ ☎ class rect { struct rect { memory py : int; int py; [...] }; } class integrator { struct integrator { instance v, x: rect; struct rect v; [...] struct rect x; } }; class excess { struct excess { instance vx: integrator ; struct integrator vx; }; [...] [...] step(max , a: int) struct excess_step { returns (e: bool , x: int) _Bool e; var v: int int x; { }; v, x := integrator(vx).step(a); void excess_step (struct excess *self , e := v > max 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 Semantics preservation Obc : ( me , ve ) ; Clight : ( e , le , m ) me 1 , ve 1 ⊢ st s ⇓ me 2 , ve 2 match _ states e 1 , le 1 , m 1 Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 10 / 19
Generation and proof Correctness proof Semantics preservation Obc : ( me , ve ) ; Clight : ( e , le , m ) ⊢ st s ⇓ me 1 , ve 1 me 2 , ve 2 match _ states match _ states e 1 , le 1 , m 1 ⊢ Clight | s | s ⤋ e 1 , le 2 , m 2 Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 10 / 19
Generation and proof Correctness proof Separation logic 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 Separation logic 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 Separation logic in CompCert � mfoot : block → int → P , m � P ≡ ( mpred P ) m predicate P : mpred : memory → P 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 Separation logic in CompCert � mfoot : block → int → P , m � P ≡ ( mpred P ) m predicate P : mpred : memory → P conjonction m � P ∗ Q pure formula m � pure ( P ) ∗ Q ↔ P ∧ m � Q mfoot = λ b ofs . mfoot P b ofs ∨ mfoot Q b ofs P ∗ Q = 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 States correspondence 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 States correspondence Obc : ( me , ve ) ; Clight : ( e , le , m ) match_states = self pointer pure ( le ( self ) = ( b s , ofs )) ∗ pure ( le ( out ) = ( b o , 0 )) out pointer ∗ pure ( ge ( f_c ) = co out ) output structure Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof States correspondence Obc : ( me , ve ) ; Clight : ( e , le , m ) match_states = pure ( le ( self ) = ( b s , ofs )) ∗ pure ( le ( out ) = ( b o , 0 )) ∗ pure ( ge ( f_c ) = co out ) ∗ 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 States correspondence Obc : ( me , ve ) ; Clight : ( e , le , m ) match_states = pure ( le ( self ) = ( b s , ofs )) ∗ pure ( le ( out ) = ( b o , 0 )) ∗ pure ( ge ( f_c ) = co out ) ∗ pure ( wt_env ve m ) memory me ≈ ∗ pure ( wt_mem me p c ) structure pointed by self ∗ staterep p c me b s ofs Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof States correspondence Obc : ( me , ve ) ; Clight : ( e , le , m ) match_states = pure ( le ( self ) = ( b s , ofs )) ∗ pure ( le ( out ) = ( b o , 0 )) ∗ pure ( ge ( f_c ) = co out ) ∗ pure ( wt_env ve m ) ∗ pure ( wt_mem me p c ) output variables of m ∗ staterep p c me b s ofs ≈ fields of co out pointed ∗ blockrep ve co out b o by out Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Generation and proof Correctness proof States correspondence Obc : ( me , ve ) ; Clight : ( e , le , m ) match_states = pure ( le ( self ) = ( b s , ofs )) ∗ pure ( le ( out ) = ( b o , 0 )) ∗ pure ( ge ( f_c ) = co out ) ∗ pure ( wt_env ve m ) ∗ pure ( wt_mem me p c ) ∗ staterep p c me b s ofs ∗ blockrep ve co out b o parameters and local ∗ varsrep m ve le variables ≈ temporaries Lélio Brun Verifying a Lustre Compiler Part 2 December 7, 2016 13 / 19
Recommend
More recommend