the correctness of a code generator for a functional
play

The Correctness of a Code Generator for a Functional Language - PowerPoint PPT Presentation

The Correctness of a Code Generator for a Functional Language Nathana el Courant September 8, 2017 Nathana el Courant Verified code generation September 8, 2017 1 / 21 Context PVS: interactive proof assistant Specification language


  1. The Correctness of a Code Generator for a Functional Language Nathana¨ el Courant September 8, 2017 Nathana¨ el Courant Verified code generation September 8, 2017 1 / 21

  2. Context PVS: interactive proof assistant Specification language almost completely executable Can be used to write and formally verify programs Slow → generate efficient executable code (PVS2C) Objective: formally verify PVS2C Idealized version Related work: CompCert, CakeML Nathana¨ el Courant Verified code generation September 8, 2017 2 / 21

  3. A Small Functional Language Evaluation with Reference Counting A Small Imperative Language Formalization in PVS Nathana¨ el Courant Verified code generation September 8, 2017 2 / 21

  4. Expressions and contexts let a = t [ i ] in let b = t [ j ] in let t ′ = t [ i �→ b ] in t ′ [ j �→ a ] K ::= | � | pop ( K 1 ) n ) = K 1 in e 1 e ::= | n | let ( x : int* | x v ::= | n | nil | ref ( k ) | nil r ::= | x | f ( x 1 , . . . , x n ) | f ( x 1 , . . . , x n ) n ) = e 1 in e 2 | let ( x : int* | x [ y ] | ifnz x then e 1 else e 2 | x [ y �→ z ] | x [ y ] | newint ( n ) | x [ y �→ z ] | newref ( n ) | newint ( n ) | newref ( n ) | ifnz x then e 1 else e 2 | pop ( e 1 ) | ref ( k ) | let x = v in e | pop ( v ) Nathana¨ el Courant Verified code generation September 8, 2017 3 / 21

  5. Decomposition theorem Fill context with expression: replace hole � by expression, denoted Ke K = let x = � in f ( x ) , e = 42 → Ke = let x = 42 in f ( x ) Theorem (Decomposition theorem) If e is not a value, there exists a unique decomposition e = Kr with K a context, r a redex. Nathana¨ el Courant Verified code generation September 8, 2017 4 / 21

  6. Evaluation state ( e, S, M ) e an expression, S the stack: maps variables → values, M the store: maps references → arrays of values. Nathana¨ el Courant Verified code generation September 8, 2017 5 / 21

  7. Reduction of FL Defined on redexes Context-preserving: if ( e, S, M ) → ( e ′ , S ′ , M ′ ) , then ( Ke, S, M ) → ( Ke ′ , S ′ , M ′ ) Deterministic Exemples: ( x, S, M ) → ( S ( x ) , S, M ) ( x [ y �→ z ] , S, M ) → ( new ( M ) , S, M [ new ( M ) �→ M ( S ( x ))[ S ( y ) �→ S ( z )]]) ( let x = v in e, S, M ) → ( pop ( e ) , push ( x, v, S ) , M ) Nathana¨ el Courant Verified code generation September 8, 2017 6 / 21

  8. A Small Functional Language Evaluation with Reference Counting A Small Imperative Language Formalization in PVS Nathana¨ el Courant Verified code generation September 8, 2017 6 / 21

  9. Reference counts Count number of times each reference appears #( S, x ) : number of times x appears in S Invariant: C ( ref ( k )) = 1 ref ( k ) ∈ e + #( S, ref ( k )) � + #( M ( ref ( s )) , ref ( k )) ref ( s ) ∈M Keep track of reference counts Free memory when count becomes 0 Destructive updates when possible Nathana¨ el Courant Verified code generation September 8, 2017 7 / 21

  10. Marked variables Variables can be marked + new constructor release Mark last occurrence of variables in each execution path Done statically: mark ( X, e ) marks each variable in e that is not in X mark ( X, x ) = � x if x ∈ X otherwise x mark ( X, let x = e 1 in e 2 ) =  let x = mark ( X ∪ vars ( e 2 ) , e 1 )     in mark ( X, e 2 ) if x ∈ vars ( e 2 )  let x = mark ( X ∪ vars ( e 2 ) , e 1 )     in release ( x, mark ( X, e 2 )) otherwise  Example: let x = f ( y ) in ifnz z then g ( x, y ) else release ( y, f ( x )) Nathana¨ el Courant Verified code generation September 8, 2017 8 / 21

  11. Correctness Invariants preserved, with states ( e, S, M ) and ( e ′ , S ′ , M ′ , C ′ ) : Reference count is accurate A variable no longer live in e ′ is not bound to a reference in S ′ The expression e ′ is correctly marked All subterms release ( x, e 2 ) of e ′ have x marked There is a function f that maps the references in M ′ with count > 0 to references in M so that: e is obtained by removing release and unmarking variables in f ( e ′ ) , For each variable x live in e ′ , S ( x ) = f ( S ′ ( x )) , For each reference s in M ′ with C ′ ( s ) > 0 , M ( f ( s )) = f ( M ′ ( s )) Nathana¨ el Courant Verified code generation September 8, 2017 9 / 21

  12. A Small Functional Language Evaluation with Reference Counting A Small Imperative Language Formalization in PVS Nathana¨ el Courant Verified code generation September 8, 2017 9 / 21

  13. Syntax { int z ; { z := x [ y ]; result := x [ z ] }} s ::= | x := e | ifnz x then s 1 else s 2 e ::= | n | skip | x | { s 1 ; s 2 } | nil | release x | f ( x 1 , . . . , x n ) n x ; s } | { int* | x [ y ] | x [ y �→ z ] n x | newint ( n ) decl ::= int* function ::= (name , decl ∗ , s ) | newref ( n ) program ::= function ∗ Nathana¨ el Courant Verified code generation September 8, 2017 10 / 21

  14. Evaluation state Fixed program ( R , S, M , C ) S is the stack, M is the store, C is the reference count, R is the call stack: stack of ( function , program counter , local depth ) Nathana¨ el Courant Verified code generation September 8, 2017 11 / 21

  15. Reduction of IL Extract statement at current program counter Reduce statement For assignments, except calls: like RL but store result Nathana¨ el Courant Verified code generation September 8, 2017 12 / 21

  16. IL code generation Return variable: translate ( e, x ) sets x to result of e translate ( y [ z �→ w ] , x ) = x := y [ z �→ w ] translate ( ifnz y then e 1 else e 2 , x ) = ifnz y then translate ( e 1 , x ) else translate ( e 2 , x ) n ) = e 1 in e 2 , x ) = translate ( let ( y : int* { int* n y ; { translate ( e 1 , y ); { skip ; translate ( e 2 , x ) }}} Nathana¨ el Courant Verified code generation September 8, 2017 13 / 21

  17. Correctness Reconstruct redex and context from call stack, Reconstruct mapping for the stack variables, Store and counts the same Nathana¨ el Courant Verified code generation September 8, 2017 14 / 21

  18. Stack Program swap ( t, i, j ) ( b �→ 1 , a �→ 0 , 0 { int a ; 1 a := t [ i ]; 2 skip ; j �→ 1 , i �→ 0 , t �→ r, 3 { int b ; 4 b := t [ j ]; 5 skip ; result �→ undef , � 6 { int* t ′ ; 7 t ′ := t [ i �→ b ]; 8 skip ; z �→ 1 , y �→ 0 , x �→ r, 9 result := t ′ [ j �→ a ] 10 } 11 } 12 } 13 result �→ undef , � → ( pop 4 ( � ) , let b = 1 in result �→ undef ) let t ′ = t [ i �→ b ] in t ′ [ j �→ a ])) Store main () ( r �→ � 0 , 1 � ) 0 { int z ; 1 z := +( y, 1); 2 skip ; Count 3 result := swap ( x, y, z ) 4 } 5 → pop ( � ) ( r �→ 2) Nathana¨ el Courant Verified code generation September 8, 2017 15 / 21

  19. Stack ( b �→ 1 ,a �→ 0 , j �→ 1 , i �→ 0 , t �→ r, result �→ undef , � Expression z �→ 1 , y �→ 0 , x �→ r, pop 5 ( result �→ undef , � let b = 1 in result �→ undef ) let t ′ = t [ i �→ b ] in t ′ [ j �→ a ]) Store ( r �→ � 0 , 1 � ) Count ( r �→ 2) Nathana¨ el Courant Verified code generation September 8, 2017 15 / 21

  20. Stack ( a �→ 0 , j �→ 1 , i �→ 0 , t �→ r, z �→ 1 , y �→ 0 , x �→ r ) Expression pop 5 ( let b = 1 in let t ′ = t [ i �→ b ] in t ′ [ j �→ a ]) Store ( r �→ � 0 , 1 � ) Count ( r �→ 2) Nathana¨ el Courant Verified code generation September 8, 2017 15 / 21

  21. A Small Functional Language Evaluation with Reference Counting A Small Imperative Language Formalization in PVS Nathana¨ el Courant Verified code generation September 8, 2017 15 / 21

  22. PVS formalization Proof FL → RL translation both with and without typing Actually a 4 th language: RL with several steps at once ≈ 7k lines definitions or theorems, proof files ≈ 310k lines long Code available at https://github.com/SRI-CSL/PVSCodegen Done before my internship: most definitions of FL , without proofs Nathana¨ el Courant Verified code generation September 8, 2017 16 / 21

  23. Problems caused by PVS PVS is slow: proofs take a long time to check PVS has bugs: could prove false Proofs of TCCs get misplaced after typechecking again → but allowed to detect those bugs Nathana¨ el Courant Verified code generation September 8, 2017 17 / 21

  24. The proved theorems bisimulation_lemma: THEOREM NOT tS‘state‘error AND NOT trS‘state‘error AND defs_well_typed(D, tS‘def_types) AND state_matches?(typed_to_topstate(tS), typed_to_topstate(trS)) IMPLIES state_matches?(typed_reduce(D)(tS), typed_reduce_n(D)( top_releases_ct(trS‘state‘redex) + 1, trS)) Nathana¨ el Courant Verified code generation September 8, 2017 18 / 21

  25. The proved theorems bisimulation_lemma_i: THEOREM NOT trS1‘state‘error AND NOT trS2‘state‘error AND defs_well_typed(D, trS1‘def_types) AND iastate_matches(trS1, trS2) IMPLIES EXISTS (n: posnat): iastate_matches(typed_reduce_n(D)(n, trS1), typed_iareduce(D)(trS2)) Nathana¨ el Courant Verified code generation September 8, 2017 19 / 21

  26. The proved theorems bisimulation_lemma: LEMMA FORALL (D, (trS | defs_well_typed(D, trS‘def_types)), iS): NOT iS‘error AND state_matches(D, trS, iS) IMPLIES (state_matches(D, trS, reduce(iS)) AND max_inst_steps(reduce(iS)) < max_inst_steps(iS)) OR state_matches(D, typed_iareduce(D)(trS), reduce(iS)) Nathana¨ el Courant Verified code generation September 8, 2017 20 / 21

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend