The KeY Platform for Verification and Analysis of Java Programs Reiner H¨ ahnle Technische Universit¨ at Darmstadt Department of Computer Science, Software Engineering Group Dagstuhl Seminar 16131: Language Based Verification Tools for Functional Programs
Joint Work with. . . Wolfgang Ahrendt, Bernhard Beckert, Richard Bubel, Christoph Gladisch, Daniel Grahl, Sarah Grebing, Martin Hentschel, Mihai Herda, Vladimir Klebanov, Wojciech Mostowski, Christoph Scheben, Peter H. Schmitt, Mattias Ulbrich, Nathan Wasser and many others over the last 12 years
The KeY Platform
The KeY Platform Target Languages ◮ sequential Java ◮ without floats, reflexion, lambdas
The KeY Platform Properties ◮ functional correctness ◮ framing ◮ information flow ◮ resource consumption
The KeY Platform Threorem Proving Test Cases Symbolic Execution Engine for Debugging Dynamic Logic Counter Examples Visualization
Deductive Verification of OO-Programs The Ke Y Approach Program Theorem Prover File.java Proof Obligation DL Formula Generator Specification ?
Deductive Verification of OO-Programs The Ke Y Approach Program Theorem Prover File.java Proof Obligation DL Formula Generator Specification ?
Formal Specification of OO-Programs Program Specification Follows design-by-contract methodology ◮ Behavior of programs specified on level of classes and methods ◮ Contracts are used to specify methods ◮ precondition must be established by caller ◮ postcondition guaranteed by callee if precondition holds at invocation time ◮ Invariants attached to classes to specify ◮ global system properties ◮ data consistency properties
The Java Modeling Language (JML) A Specification Language for Java Sum and Maximum (VSComp 2010) ◮ Description: Given an N -element array of natural numbers, write a program to compute the sum and the maximum of the elements in the array. ◮ Properties: Given that N ≥ 0 and a [ i ] ≥ 0 for 0 ≤ i < N , prove the post-condition that sum ≤ N · max . ❝❧❛ss SumAndMax { ✐♥t sum; ✐♥t max; /*@ normal_behaviour @ r❡q✉✐r❡s ( ❭❢♦r❛❧❧ ✐♥t i; 0 <= i && i < a.length; 0 <= a[i]); @ ❛ss✐❣♥❛❜❧❡ sum, max; @ ❡♥s✉r❡s ( ❭❢♦r❛❧❧ ✐♥t i; 0 <= i && i < a.length; a[i] <= max); @ ❡♥s✉r❡s ( ❭❡①✐sts ✐♥t i; 0 <= i && i < a.length; max == a[i]); @ ❡♥s✉r❡s sum == ( ❭s✉♠ ✐♥t i; 0 <= i && i < a.length; a[i]); @ ❡♥s✉r❡s sum <= a.length * max; @*/ ✈♦✐❞ sumAndMax( ✐♥t [] a) { ... } }
Deductive Verification of OO-Programs The Ke Y Approach Program Theorem Prover File.java Proof Obligation DL Formula Generator Specification ?
Java Dynamic Logic
Java Dynamic Logic FOL ∃ x .φ
Java Dynamic Logic Modal logic ∃ x . ♦� φ
Java Dynamic Logic Multi-modal logic ∃ x . ♦ ∗ � ♥ φ
Java Dynamic Logic Dynamic logic ∃ x . � x < 0? y := − x ; x ≥ 0? y := x � y ≥ 0
Java Dynamic Logic Java DL � for (Integer i: c) y+= i*i; � y ≥ 0
Java Dynamic Logic Java DL with updates ∃ s : java . util . Set . { c := s } � for (Integer i: c) y+= i*i; � y ≥ 0
Java Dynamic Logic Java DL with updates ∃ s : java . util . Set . { c := s } � for (Integer i: c) y+= i*i; � y ≥ 0 ◮ � p � φ : Program p terminates and formula φ holds in its final state. ◮ [ p ] φ : If program p terminates then formula φ holds in the final state.
Java DL
Java DL Hoare logic vs. DL { φ } P { ψ } can be represented as φ → [ P ] ψ
Java DL Hoare logic vs. DL { φ } P { ψ } can be represented as φ → [ P ] ψ Multiple programs: Noninterference “Self composition” (Darvas, H¨ ahnle, Sands 2003) ∀ sec 1 , sec 2 , in , out 1 , out 2 . ( { x := sec 1 � y := in } [ P ] res = out 1 ∧ { x := sec 2 � y := in } [ P ] res = out 2 → out 1 = out 2 )
Deductive Verification of OO-Programs The Ke Y Approach Program Theorem Prover File.java Proof Obligation DL Formula Generator Specification ?
Dynamic Logic Calculus Analysis Technique: Sequent Calculus realizes symbolic interpreter
Dynamic Logic Calculus Analysis Technique: Sequent Calculus realizes symbolic interpreter ifStatement Γ , b . Γ , b . = true = ⇒ [ p; rest ] φ, ∆ = false = ⇒ [ q; rest ] φ, ∆ Γ = ⇒ [ if (b) { p } else { q }; rest ] φ, ∆ Γ , { x := e } = ⇒ [ rest ] φ, ∆ simpleAssigment Γ = ⇒ [ x = e; rest ] φ, ∆ Γ = ⇒ [ if(b) {p; while(b) p} rest ] φ, ∆ unwindLoop Γ = ⇒ [ while(b) p rest ] φ, ∆
Proof Construction x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ { y := y + x || x := y } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ { y := y + x || x := y }{ y := y − x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ { x := y || y := x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y }{ y := y − x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ { x := y || y := x } ( y > x ) x > y = ⇒ { x := y || y := x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y }{ y := y − x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ x > y x > y = ⇒ { x := y || y := x } ( y > x ) x > y = ⇒ { x := y || y := x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y }{ y := y − x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x )
Proof Construction x > y = ⇒ x > y x > y = ⇒ { x := y || y := x } ( y > x ) x > y = ⇒ { x := y || y := x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y }{ y := y − x } [ ]( y > x ) x > y = ⇒ { y := y + x || x := y } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x }{ x := y − x } [ y-=x; ]( y > x ) x > y = ⇒ { y := y + x } [ x=y-x; y-=x; ]( y > x ) x > y = ⇒ [ y+=x; x=y-x; y-=x; ]( y > x ) Updates facilitate forward symbolic execution
Symbolic Execution public static int sum( int [] a) throws Exception { if (a == null ) { throw new Exception(); } else { int sum = 0; for ( int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }
Symbolic Execution public static int sum( int [] a) if (a == null ) throws Exception { a: a0 if (a == null ) { throw new Exception(); } else { int sum = 0; for ( int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }
Symbolic Execution public static int sum( int [] a) if (a == null ) throws Exception { a: a0 if (a == null ) { a0 = null throw throw new new Exception(); Exception(); } else { a: a0 { a0 = null } int sum = 0; for ( int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }
Symbolic Execution public static int sum( int [] a) if (a == null ) throws Exception { a: a0 if (a == null ) { a0 = null a0 ≠ null throw throw new int sum = 0; new Exception(); Exception(); } a: a0 { a0 ≠ null } else { a: a0 { a0 = null } int sum = 0; for ( int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }
Symbolic Execution public static int sum( int [] a) if (a == null ) throws Exception { a: a0 if (a == null ) { a0 = null a0 ≠ null throw throw new int sum = 0; new Exception(); Exception(); } a: a0 { a0 ≠ null } else { a: a0 { a0 = null } int sum = 0; int i = 0; for ( int i = 0; sum: 0 i < a.length; i++) { sum += a[i]; } return sum; } }
Symbolic Execution public static int sum( int [] a) if (a == null ) throws Exception { a: a0 if (a == null ) { a0 = null a0 ≠ null throw throw new int sum = 0; new Exception(); Exception(); } a: a0 { a0 ≠ null } else { a: a0 { a0 = null } int sum = 0; int i = 0; for ( int i = 0; sum: 0 i < a.length; i++) { i < a.length; sum += a[i]; i: 0 } return sum; } }
Recommend
More recommend