<<

Introduction to SPARK 2014 How to Develop Ultra-Low Defect Software

Do setup now: www.rcs.ei.tum.de/spark2014-intro

Martin Becker

Technical University of Munich Real-Time Computer Systems

September 18th, 2017 Forum on Specification & Design Languages Verona, Italy Introduction

U 0min

U 0min Martin Becker: Introduction to SPARK 2014 page 2 of 59 satellite of Vermont Technical College powered by SPARK’05

8 satellites went missing 2 worked for < 1 week 1 worked for 4 months 1 worked until re-entry after 2 years and 293,000,000 miles

Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/-I NASA Research Center) built mini satellites launch to 500km LEO in 2013:

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 satellite of Vermont Technical College powered by SPARK’05

2 worked for < 1 week 1 worked for 4 months 1 worked until re-entry after 2 years and 293,000,000 miles

Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/Minotaur-I NASA Research Center) built mini satellites launch to 500km LEO in 2013: 8 satellites went missing

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 satellite of Vermont Technical College powered by SPARK’05

1 worked for 4 months 1 worked until re-entry after 2 years and 293,000,000 miles

Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/Minotaur-I NASA Research Center) built mini satellites launch to 500km LEO in 2013: 8 satellites went missing 2 worked for < 1 week

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 satellite of Vermont Technical College powered by SPARK’05

1 worked until re-entry after 2 years and 293,000,000 miles

Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/Minotaur-I NASA Research Center) built mini satellites launch to 500km LEO in 2013: 8 satellites went missing 2 worked for < 1 week 1 worked for 4 months

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 satellite of Vermont Technical College powered by SPARK’05

Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/Minotaur-I NASA Research Center) built mini satellites launch to 500km LEO in 2013: 8 satellites went missing 2 worked for < 1 week 1 worked for 4 months 1 worked until re-entry after 2 years and 293,000,000 miles

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 powered by SPARK’05

Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/Minotaur-I NASA Research Center) built mini satellites launch to 500km LEO in 2013: 8 satellites went missing 2 worked for < 1 week 1 worked for 4 months 1 worked until re-entry after 2 years and 293,000,000 miles satellite of Vermont Technical College

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 Motivation for SPARK 2014 NASA’s CubeSat Launch Initiative, launch ‘‘ELaNa IV’’

11 institutions (one of them from Wikipedia/Minotaur-I NASA Research Center) built mini satellites launch to 500km LEO in 2013: 8 satellites went missing 2 worked for < 1 week 1 worked for 4 months 1 worked until re-entry after 2 years and 293,000,000 miles satellite of Vermont Technical College powered by SPARK’05

from Vermont Tech U 2min Martin Becker: Introduction to SPARK 2014 page 3 of 59 principal of minimal surprise: explicit, easily readable for humans, structural analogies, not case sensitive:

1 Vmax: constant Speed := 12_512.0 * Meter/Second; difference to C(++): Getting it to compile is harder, but much less bugs after (longer development time vs. more maintenance) rated by NIST as approach with ‘‘dramatic future impact’’ (reducing vulnerabilities by two orders of magnitude)

The SPARK 2014 Language Successor to SPARK 2005. Verifiable subset of Ada language.

conceived with verification in mind imperative language with good tool and platform support object-oriented, high re-use designed for embedded and real-time systems run-time checks, strongly typed, inherent support for parallelism

U 4min Martin Becker: Introduction to SPARK 2014 page 4 of 59 difference to C(++): Getting it to compile is harder, but much less bugs after (longer development time vs. more maintenance) rated by NIST as approach with ‘‘dramatic future impact’’ (reducing vulnerabilities by two orders of magnitude)

The SPARK 2014 Language Successor to SPARK 2005. Verifiable subset of Ada language.

conceived with verification in mind imperative language with good tool and platform support object-oriented, high re-use designed for embedded and real-time systems run-time checks, strongly typed, inherent support for parallelism principal of minimal surprise: explicit, easily readable for humans, structural analogies, not case sensitive: Vmax: constant Speed := 12_512.0 * Meter/Second;

U 4min Martin Becker: Introduction to SPARK 2014 page 4 of 59 rated by NIST as approach with ‘‘dramatic future impact’’ (reducing vulnerabilities by two orders of magnitude)

The SPARK 2014 Language Successor to SPARK 2005. Verifiable subset of Ada language.

conceived with verification in mind imperative language with good tool and platform support object-oriented, high re-use designed for embedded and real-time systems run-time checks, strongly typed, inherent support for parallelism principal of minimal surprise: explicit, easily readable for humans, structural analogies, not case sensitive: Vmax: constant Speed := 12_512.0 * Meter/Second;

difference to C(++): Getting it to compile is harder, but much less bugs after (longer development time vs. more maintenance)

U 4min Martin Becker: Introduction to SPARK 2014 page 4 of 59 The SPARK 2014 Language Successor to SPARK 2005. Verifiable subset of Ada language.

conceived with verification in mind imperative language with good tool and platform support object-oriented, high re-use designed for embedded and real-time systems run-time checks, strongly typed, inherent support for parallelism principal of minimal surprise: explicit, easily readable for humans, structural analogies, not case sensitive: Vmax: constant Speed := 12_512.0 * Meter/Second;

difference to C(++): Getting it to compile is harder, but much less bugs after (longer development time vs. more maintenance) rated by NIST as approach with ‘‘dramatic future impact’’ (reducing vulnerabilities by two orders of magnitude)

U 4min Martin Becker: Introduction to SPARK 2014 page 4 of 59 Pedigree of SPARK 2014 Famous users of Ada and SPARK

Air Traffic Management: AU, CA, FR, DE, NZ, UK, USA, ... Civil Aviation: Boeing 777 (99.9%!), A330, Tu-204, ... Railway: TGV, ETCS, ... Rockets: , , ... Satellites: INMARSAT, ... Banking: Reuters, ... Medical: JEOL Nuclear MRI, LifeFlow VAD, ... Military: Eurofighter combat aircraft, ...... U 6min Martin Becker: Introduction to SPARK 2014 page 5 of 59 The next 82 minutes...

1 Hands-on Part I

2 Basic Features

3 Outsmart programmers from IBM and Bell Labs

4 Hands-on Part II

5 Proof

6 Hands-on Part III

7 Advanced Topics

8 Wrap-Up U 8min Martin Becker: Introduction to SPARK 2014 page 6 of 59 Hands-on Part I

U 8min

U 8min Martin Becker: Introduction to SPARK 2014 page 7 of 59 Setting up ‘‘Hello World’’ (10min)

Step by step: GPS IDE functions, procedures packages variables Put_Line (with, use) if-then Final result: http://tinyurl.com/yabb8ktm

U 8min Martin Becker: Introduction to SPARK 2014 page 8 of 59 Basic Features

U 18min

U 18min Martin Becker: Introduction to SPARK 2014 page 9 of 59 Weakly typed means (C++, C, Java, ...): typedefs are not real types implicit conversions from int to float weak overflow semantics/undefined behavior missing types (fixed-point) two objects of different types can be mixed, although they shouldn’t: one can add up variables representing speed and time Ada/SPARK is the opposite.

Data Types in Ada/SPARK 2014

Strong Type System: ‘‘I cannot even assign this integer to that other integer...’’

U 18min Martin Becker: Introduction to SPARK 2014 page 10 of 59 Data Types in Ada/SPARK 2014

Strong Type System: ‘‘I cannot even assign this integer to that other integer...’’

Weakly typed means (C++, C, Java, ...): typedefs are not real types implicit conversions from int to float weak overflow semantics/undefined behavior missing types (fixed-point) two objects of different types can be mixed, although they shouldn’t: one can add up variables representing speed and time Ada/SPARK is the opposite.

U 18min Martin Becker: Introduction to SPARK 2014 page 10 of 59 SPARK 2014: Built-in Types

image (modified) from Ada Wikibooks

U 20min Martin Becker: Introduction to SPARK 2014 page 11 of 59 a subtype is compatible to the base type: subtype Integer_1 is Integer range 1..10; var: Integer; var1: Integer_1; var := var1;-- no problem

way number 3: create new type without base type (nothing inherited)

1 type My_Currency is digits 6; type My_Enum is(HI,LO,Z);

User-Defined Types create a new type based on an existing one. It is incompatible to the existing one, but inherits the operations (+,-,*,/,...) type Int_1 is new Integer range 1..10;-- declare type type Int_2 is new Integer range 1..10; var1: Int_1;-- create object/instance of type 4 var2: Int_2; var1 := var2;--ERROR: type mismatch

U 20min Martin Becker: Introduction to SPARK 2014 page 12 of 59 way number 3: create new type without base type (nothing inherited)

1 type My_Currency is digits 6; type My_Enum is(HI,LO,Z);

User-Defined Types create a new type based on an existing one. It is incompatible to the existing one, but inherits the operations (+,-,*,/,...) type Int_1 is new Integer range 1..10;-- declare type type Int_2 is new Integer range 1..10; 3 var1: Int_1;-- create object/instance of type var2: Int_2; var1 := var2;--ERROR: type mismatch

a subtype is compatible to the base type: subtype Integer_1 is Integer range 1..10; var: Integer; var1: Integer_1; var := var1;-- no problem

U 20min Martin Becker: Introduction to SPARK 2014 page 12 of 59 User-Defined Types create a new type based on an existing one. It is incompatible to the existing one, but inherits the operations (+,-,*,/,...) type Int_1 is new Integer range 1..10;-- declare type type Int_2 is new Integer range 1..10; 3 var1: Int_1;-- create object/instance of type var2: Int_2; var1 := var2;--ERROR: type mismatch

a subtype is compatible to the base type: subtype Integer_1 is Integer range 1..10; var: Integer; var1: Integer_1; var := var1;-- no problem

way number 3: create new type without base type (nothing inherited)

1 type My_Currency is digits 6; type My_Enum is(HI,LO,Z);

U 20min Martin Becker: Introduction to SPARK 2014 page 12 of 59 attribute ‘‘Range’’ can be used to iterate over arrays: myArray: array(1..5) of Integer := (2,4,6,8,10); fori in myArray'Range loop 3 --... end loop;

Attributes ‘‘Succ’’ and ‘‘Pred’’ can be used to walk through discrete types (e.g., enums, where you cannot do ‘‘+1’’):

1 type My_Weekdays is(Monday, Holiday, Friday); w: My_Weekday := Monday; w := My_Weekday'Succ(w);-- now we got Holiday

For more see cheat sheet.

Attributes get/set information about an object denoted by a single quote, e.g.: myInteger'First. Attribute ‘‘First’’ returns lowest possible value in this type myInteger'Last. Returns highest possible value in this type

U 22min Martin Becker: Introduction to SPARK 2014 page 13 of 59 Attributes ‘‘Succ’’ and ‘‘Pred’’ can be used to walk through discrete types (e.g., enums, where you cannot do ‘‘+1’’):

1 type My_Weekdays is(Monday, Holiday, Friday); w: My_Weekday := Monday; w := My_Weekday'Succ(w);-- now we got Holiday

For more see cheat sheet.

Attributes get/set information about an object denoted by a single quote, e.g.: myInteger'First. Attribute ‘‘First’’ returns lowest possible value in this type myInteger'Last. Returns highest possible value in this type attribute ‘‘Range’’ can be used to iterate over arrays: myArray: array(1..5) of Integer := (2,4,6,8,10); 2 fori in myArray'Range loop --... end loop;

U 22min Martin Becker: Introduction to SPARK 2014 page 13 of 59 Attributes get/set information about an object denoted by a single quote, e.g.: myInteger'First. Attribute ‘‘First’’ returns lowest possible value in this type myInteger'Last. Returns highest possible value in this type attribute ‘‘Range’’ can be used to iterate over arrays: myArray: array(1..5) of Integer := (2,4,6,8,10); 2 fori in myArray'Range loop --... end loop;

Attributes ‘‘Succ’’ and ‘‘Pred’’ can be used to walk through discrete types (e.g., enums, where you cannot do ‘‘+1’’):

1 type My_Weekdays is(Monday, Holiday, Friday); w: My_Weekday := Monday; w := My_Weekday'Succ(w);-- now we got Holiday

For more see cheat sheet. U 22min Martin Becker: Introduction to SPARK 2014 page 13 of 59 but SPARK 2014 forbids the use of exception handlers forces the developer to handle corner cases explicitly unhandled exceptions: program terminated we must write programs that are free of exceptions

Exceptions in SPARK/Ada

notify when something is about to go wrong: reading beyond an array assigning a value beyond range of type ... many things are checked during run-time DIV/0, overflow, array access, range checks, ... unlike C language (it just continues execution) (we could disable these checks, but ...)

U 24min Martin Becker: Introduction to SPARK 2014 page 14 of 59 Exceptions in SPARK/Ada

notify when something is about to go wrong: reading beyond an array assigning a value beyond range of type ... many things are checked during run-time DIV/0, overflow, array access, range checks, ... unlike C language (it just continues execution) (we could disable these checks, but ...) but SPARK 2014 forbids the use of exception handlers forces the developer to handle corner cases explicitly unhandled exceptions: program terminated we must write programs that are free of exceptions

U 24min Martin Becker: Introduction to SPARK 2014 page 14 of 59 Exceptions in Ada (2)

The following causes an exception at line 5: procedure main is 2 type mydays is new Integer range 1 .. 31 d: mydays := 31; begin beyond type range d :=d + 1; Put_Line("day is:"& mydays'Image(d));--unreachable 7 end main;

Some exceptions are foreseen by the compiler. Others are not.

U 26min Martin Becker: Introduction to SPARK 2014 page 15 of 59 Outsmart programmers from IBM and Bell Labs

U 27min

U 27min Martin Becker: Introduction to SPARK 2014 page 16 of 59 Example: searching for key=23

1 L=first element,H=last element 2 test element in the middle of H-L: if element = key: found, terminate. if element < key: repeat search in right half (L=middle+1). if element > key: repeat search in left half (H=middle-1).

The binary search algorithm Searching for a number (‘‘key’’) in a sorted array, return position

image (modified) from http://www.geeksforgeeks.org/binary-search/

U 27min Martin Becker: Introduction to SPARK 2014 page 17 of 59 The binary search algorithm Searching for a number (‘‘key’’) in a sorted array, return position

Example: searching for key=23

1 L=first element,H=last element 2 test element in the middle of H-L: if element = key: found, terminate. if element < key: repeat search in right half (L=middle+1). if element > key: repeat search in left half (H=middle-1).

image (modified) from http://www.geeksforgeeks.org/binary-search/

U 27min Martin Becker: Introduction to SPARK 2014 page 17 of 59 Hands-on Part II

U 30min

U 30min Martin Becker: Introduction to SPARK 2014 page 18 of 59 Binary Search in SPARK (15min) Start with this skeleton (binary_search.ads): package Binary_Search is type Arr_T is array( Positive range <>) of Integer; 3 function Search (Arr: Arr_T; Key: Integer) return Natural; end Binary_Search; return zero if main.adb: key not found with Binary_Search; use Binary_Search; with Ada.Text_IO; use Ada.Text_IO; procedure main is 4 arr: constant Arr_T (1..10) := (1,2,4,5,6,7,8,9,10,11); idx: Natural; begin -- let's test one case: idx := Search(arr, 4); 9 Put_Line("Result is"& Natural'Image(idx)); end main; Write binary_search.adb yourself, and test some cases. Copy and paste from: http://tinyurl.com/yash48gs

U 30min Martin Becker: Introduction to SPARK 2014 page 19 of 59 1 mid := low+(high- low);

One more Test Case

Modify your main.adb as follows: Arr (1..Natural'Last) := (Natural'Last => 1, others => 0); --... idx := Search(arr, 1); Put_Line("Result is"& Natural'Image(idx));

One of many possible mistakes (low+high overflows). Solution?

U 45min Martin Becker: Introduction to SPARK 2014 page 20 of 59 One more Test Case

Modify your main.adb as follows: Arr (1..Natural'Last) := (Natural'Last => 1, others => 0); --... idx := Search(arr, 1); 4 Put_Line("Result is"& Natural'Image(idx)); One of many possible mistakes (low+high overflows). Solution?

1 mid := low+(high- low);

U 45min Martin Becker: Introduction to SPARK 2014 page 20 of 59 Proof

U 47min

U 47min Martin Becker: Introduction to SPARK 2014 page 21 of 59 Two possible ways forward: 1 use full Ada: handle exceptions, apply testing 2 use SPARK subset: no exception handling, find proof

Motivation for Proof

So far we are only using Ada, but without exception handling.

U 47min Martin Becker: Introduction to SPARK 2014 page 22 of 59 Motivation for Proof

So far we are only using Ada, but without exception handling.

Two possible ways forward: 1 use full Ada: handle exceptions, apply testing 2 use SPARK subset: no exception handling, find proof

U 47min Martin Becker: Introduction to SPARK 2014 page 22 of 59 SPARK 2014: Proof and AoRTE Hands-on Intermezzo

Launching the verification tool (GNATprove) 1 please add with SPARK_Mode to your search package (see cheat sheet) 2 click on menu ‘‘SPARK’’ → ‘‘Prove All Sources’’ 3 select ‘‘Multiprocessing’’, ‘‘Report checks proved’’ and ‘‘Proof level=2’’ 4 click on ‘‘Execute’’ Finds all defects that could lead to exceptions – most likely you will have a few red lines now...

Fixing all these lines would guarantee Absence of Run-time Error (AoRTE)

U 49min Martin Becker: Introduction to SPARK 2014 page 23 of 59 Verification of SPARK 2014

static analysis considers all possible inputs and interactions equivalent to exhaustive testing, but no test harness or fixture necessary usually much faster than extensive testing exhaustive testing not possible in real world some properties are over-approximated, but in a safe way: unless verifier finds a proof that bad things are impossible, properties are flagged as failing (red) e.g.: a+b is classified as overflow, if ranges of a and b are unspecified sometimes verifier needs a little help (e.g., with loops)

U 51min Martin Becker: Introduction to SPARK 2014 page 24 of 59 Verification of SPARK 2014 Beyond this tutorial...

‘‘Any sufficiently advanced technology is indistinguishable from magic.’’

Arthur C. Clarke

U 53min Martin Becker: Introduction to SPARK 2014 page 25 of 59 Verification of SPARK 2014 Beyond this tutorial...

‘‘Any sufficiently advanced technology is indistinguishable from magic.’’

Arthur C. Clarke

U 53min Martin Becker: Introduction to SPARK 2014 page 25 of 59 but it could still do the wrong thing Not searching at all search only half of the array ... we need the option to specify intended behavior and then also prove it!

Another Type of Error

Program works perfectly, for all possible inputs no crash, no silent overflows, ... already better than C++, Java, Rust et al. but . . .

U 54min Martin Becker: Introduction to SPARK 2014 page 26 of 59 but . . .

Another Type of Error

Program works perfectly, for all possible inputs no crash, no silent overflows, ... already better than C++, Java, Rust et al. but it could still do the wrong thing Not searching at all search only half of the array ... we need the option to specify intended behavior and then also prove it!

U 54min Martin Becker: Introduction to SPARK 2014 page 26 of 59 Contracts

formal agreement between the implementer and the user of a program unit (package or subprogram) assigns responsibilities a way to organize and document your code not a new idea (Floyd, Hoare, Dijkstra, Meyer)

U 56min Martin Becker: Introduction to SPARK 2014 page 27 of 59 Pre- and Postconditions

are Boolean expressions Pre is an obligation of the caller Post is an obligation of the callee are verified, just like any other potential exception

U 58min Martin Becker: Introduction to SPARK 2014 page 28 of 59 precondition is a Boolean function -- our project: 2 function Search(Arr: Arr_T; Key: Integer) return Natural with Pre => Sorted(Arr);

function Sorted(A: Arr_T) return Boolean is quantified (A'Length<2 or else expresssion 7 (for allX inA'First..A'Last-1=> (for allY inX+1..A'Last =>A(X) <=A(Y))));

Precondition Contracts

conditions that must hold true when the subprogram is called -- example: procedure Increment(X: in out Integer) precondition with Pre =>X< Integer'Last;

responsible: caller (must obey these conditions) verifier tries to prove every subprogram call

Don’t retype that...link to source is provided later! U 60min Martin Becker: Introduction to SPARK 2014 page 29 of 59 Precondition Contracts

conditions that must hold true when the subprogram is called -- example: procedure Increment(X: in out Integer) 2 precondition with Pre =>X< Integer'Last;

responsible: caller (must obey these conditions) precondition verifier tries to prove every subprogram call is a Boolean function -- our project: 2 function Search(Arr: Arr_T; Key: Integer) return Natural with Pre => Sorted(Arr);

function Sorted(A: Arr_T) return Boolean is quantified (A'Length<2 or else expresssion 7 (for allX inA'First..A'Last-1=> (for allY inX+1..A'Last =>A(X) <=A(Y))));

Don’t retype that...link to source is provided later! U 60min Martin Becker: Introduction to SPARK 2014 page 29 of 59 1 -- our project: function Search(Arr: Arr_T; Key: Integer) return Natural with Pre => Sorted(Arr), Post =>(if Search'Result=0 then True else Arr(Search'Result) = Key);

Postcondition Contracts

conditions that must hold true after subprogram finishes -- example: 2 procedure Increment(X: in out Integer) with Pre =>X< Integer'Last, Post =>X=X'Old + 1; postcondition

responsible: callee (must provide these conditions) verifier tries to prove that implementation actually produces these conditions

U 62min Martin Becker: Introduction to SPARK 2014 page 30 of 59 Postcondition Contracts

conditions that must hold true after subprogram finishes -- example: procedure Increment(X: in out Integer) with Pre =>X< Integer'Last, Post =>X=X'Old + 1; postcondition

responsible: callee (must provide these conditions) verifier tries to prove that implementation actually produces these conditions

1 -- our project: function Search(Arr: Arr_T; Key: Integer) return Natural with Pre => Sorted(Arr), Post =>(if Search'Result=0 then True else Arr(Search'Result) = Key);

U 62min Martin Becker: Introduction to SPARK 2014 page 30 of 59 Summary Pre- and Postconditions

assign responsibilities can be composed of any visible name in the scope of the subprogram any parameter of the subprogram good types simplify contracts (e.g., use Natural instead of Integer when negative numbers are not allowed)

U 64min Martin Becker: Introduction to SPARK 2014 page 31 of 59 Modular Verification of SPARK 2014 (1)

U 66min Martin Becker: Introduction to SPARK 2014 page 32 of 59 Even if proven free of errors, P may still produce errors when Q violates its postcondition!

Modular Verification of SPARK 2014 (2)

U 66min Martin Becker: Introduction to SPARK 2014 page 33 of 59 Modular Verification of SPARK 2014 (2)

Even if proven free of errors, P may still produce errors when Q violates its postcondition!

U 66min Martin Becker: Introduction to SPARK 2014 page 33 of 59 Even if proven free of errors, Q may still produce errors when P violates the precondition!

Modular Verification of SPARK 2014 (3)

U 66min Martin Becker: Introduction to SPARK 2014 page 34 of 59 Modular Verification of SPARK 2014 (3)

Even if proven free of errors, Q may still produce errors when P violates the precondition!

U 66min Martin Becker: Introduction to SPARK 2014 page 34 of 59 Hands-on Part III

U 70min

U 70min Martin Becker: Introduction to SPARK 2014 page 35 of 59 array index check might fail: Arr(mid) /= Key: loops are notoriously hard to analyze, solver needs hint add the following into loop to hint solver that low, high should always be in range: pragma Loop_Invariant(low in Arr'Range and high in Arr'Range);

solver will verify this proposition and then use this fact to get rid of warning

Perfecting binary search (10min)

make use of contracts time to fix your programs! (buggy) implementation so far: http://tinyurl.com/ycz2wk6l

U 70min Martin Becker: Introduction to SPARK 2014 page 36 of 59 Perfecting binary search (10min)

make use of contracts time to fix your programs! (buggy) implementation so far: http://tinyurl.com/ycz2wk6l array index check might fail: Arr(mid) /= Key: loops are notoriously hard to analyze, solver needs hint add the following into loop to hint solver that low, high should always be in range: pragma Loop_Invariant(low in Arr'Range and high in Arr'Range);

solver will verify this proposition and then use this fact to get rid of warning

U 70min Martin Becker: Introduction to SPARK 2014 page 36 of 59 Evaluation of Exercise

90% wrong?

Final solution: http://tinyurl.com/y8shbvoo extended postcondition: if result = 0, then key must not be in array 37 successfully discharged verification conditions in <1s no exceptions and definitely searching! all proved without testing

U 80min Martin Becker: Introduction to SPARK 2014 page 37 of 59 Advanced Topics

U 82min

U 82min Martin Becker: Introduction to SPARK 2014 page 38 of 59 divide application into pieces and apply either proof or testing to each piece contracts (and assertions) can be executed (‘‘executable semantics’’) if program is compiled with assertions on if they evaluate to False, then exception is raised contracts can be exercised in a testing environment

Combining Proof and Test

sometimes proof may be too expensive formal description of all properties may be very hard Strong postconditions say ‘‘everything’’ about the subprogram; can’t always do that

U 82min Martin Becker: Introduction to SPARK 2014 page 39 of 59 Combining Proof and Test

sometimes proof may be too expensive formal description of all properties may be very hard Strong postconditions say ‘‘everything’’ about the subprogram; can’t always do that divide application into pieces and apply either proof or testing to each piece contracts (and assertions) can be executed (‘‘executable semantics’’) if program is compiled with assertions on if they evaluate to False, then exception is raised contracts can be exercised in a testing environment

U 82min Martin Becker: Introduction to SPARK 2014 page 39 of 59 Combining Proof and Test (Example)

U 85min Martin Becker: Introduction to SPARK 2014 page 40 of 59 pragma Profile (Ravenscar) constrain tasking features to analyzable subset & patterns easier schedulability analysis, memory boundedness, full determinism memory footprint starting at 2kB ⇒ lower certification cost Annex ‘‘Safety and Security’’/’’High-Integrity Systems’’ produce reviewable object code, initialize uninitialized variables to exceptions, option to block specific language features Certifiable up to highest assurance levels, e.g., DO-178B Level A for commercial avionics (Level A: failure of software results in catastrophic consequences)

Support for Real-Time and Safety-Critical Software Many things inherited from Ada with Ada.Real_Time deterministic scheduling, priority-based interrupt handling, core assignment, preemption, resource sharing protocols

U 86min Martin Becker: Introduction to SPARK 2014 page 41 of 59 Annex ‘‘Safety and Security’’/’’High-Integrity Systems’’ produce reviewable object code, initialize uninitialized variables to exceptions, option to block specific language features Certifiable up to highest assurance levels, e.g., DO-178B Level A for commercial avionics (Level A: failure of software results in catastrophic consequences)

Support for Real-Time and Safety-Critical Software Many things inherited from Ada with Ada.Real_Time deterministic scheduling, priority-based interrupt handling, core assignment, preemption, resource sharing protocols pragma Profile (Ravenscar) constrain tasking features to analyzable subset & patterns easier schedulability analysis, memory boundedness, full determinism memory footprint starting at 2kB ⇒ lower certification cost

U 86min Martin Becker: Introduction to SPARK 2014 page 41 of 59 Certifiable up to highest assurance levels, e.g., DO-178B Level A for commercial avionics (Level A: failure of software results in catastrophic consequences)

Support for Real-Time and Safety-Critical Software Many things inherited from Ada with Ada.Real_Time deterministic scheduling, priority-based interrupt handling, core assignment, preemption, resource sharing protocols pragma Profile (Ravenscar) constrain tasking features to analyzable subset & patterns easier schedulability analysis, memory boundedness, full determinism memory footprint starting at 2kB ⇒ lower certification cost Annex ‘‘Safety and Security’’/’’High-Integrity Systems’’ produce reviewable object code, initialize uninitialized variables to exceptions, option to block specific language features

U 86min Martin Becker: Introduction to SPARK 2014 page 41 of 59 Support for Real-Time and Safety-Critical Software Many things inherited from Ada with Ada.Real_Time deterministic scheduling, priority-based interrupt handling, core assignment, preemption, resource sharing protocols pragma Profile (Ravenscar) constrain tasking features to analyzable subset & patterns easier schedulability analysis, memory boundedness, full determinism memory footprint starting at 2kB ⇒ lower certification cost Annex ‘‘Safety and Security’’/’’High-Integrity Systems’’ produce reviewable object code, initialize uninitialized variables to exceptions, option to block specific language features Certifiable up to highest assurance levels, e.g., DO-178B Level A for commercial avionics (Level A: failure of software results in catastrophic consequences)

U 86min Martin Becker: Introduction to SPARK 2014 page 41 of 59 Using SPARK 2014 in Practice

The weather balloon story Ada & SPARK can be mixed! a weather balloon that returns home gradual adoption, partial verification e.g., low-level drivers with pointers in Ada, high-level behavior in SPARK generate nightly reports statistics about coverage, success and remaining work linking legacy code use a C library from Ada or vice versa Code online: https://github.com/tum-ei-rcs/StratoX

U 90min Martin Becker: Introduction to SPARK 2014 page 42 of 59 Wrap-Up

U 93min

U 93min Martin Becker: Introduction to SPARK 2014 page 43 of 59 Conclusion

Catching bugs was never that easy, but it comes with a price.

Next version of SPARK 2014 under development (pointers!).

U 93min Martin Becker: Introduction to SPARK 2014 page 44 of 59 Many Further Topics

Cambridge University Press, 2015.

U 93min Martin Becker: Introduction to SPARK 2014 page 45 of 59 References (1)

Guides and Tutorials: SPARK User Guide, http://docs.adacore.com/spark2014-docs/html/ug/ Ada Wikibook, http://en.wikibooks.org/wiki/Ada_Programming Ada95 Lovelace tutorial, David A. Wheeler (who wrote that in his free time), http://www.adahome.com/Tutorials/Lovelace/lovelace.htm Programming Real-Time with Ada 2005, P. Rogers, http://www.embedded.com/design/prototyping-and-development/ 4025713/Programming-real-time-with-Ada-2005, 2006. Guide for the use of the Ada Ravenscar Profile in high-integrity systems, A. Burns et. al., University of York, Technical Report YCS-2003-348, 2003. Requiem for a Bug – Verifying Software: Testing and Static Analysis, Johannes Kanig, Nov 2004, http://www.electronicdesign.com/test-measurement/ requiem-bug-verifying-software-testing-and-static-analysis.

U 95min Martin Becker: Introduction to SPARK 2014 page 46 of 59 References (2)

Background: The Boeing 777 Flies on 99.9% Ada, http://archive.adaic.com/projects/atwork/boeing.html Ada 95 Eliminates Race Conditions, J.G.P. Barnes, Parallel and Distributed Real-Time Systems, 1995. Ada Glossary, Bard S. Crawford, http://www.cs.uni.edu/~mccormic/AdaEssentials/glossary.htm GNAT book, J. Miranda and E. Schonberg, https: //www2.adacore.com/gap-static/GNAT_Book/html/aarm/AA-TOC.html Concurrent and Real-Time Programming in Ada, A. Burns and A. Wellings, Cambridge Univ. Press, 2007. Ada 95 Rationale: The Language - The Standard Libraries, J. Barnes, Springer, 1995.

U 95min Martin Becker: Introduction to SPARK 2014 page 47 of 59 References (3)

Technology behind the scenes: RavenSPARK, R. Chapman, altran praxis, http://www.testandverification.com/files/Multicore_challenge_sept_ 2010/Rod_Chapman_Altran_Praxis.pdf, 2010. Static Analysis Tools Pass the Quals, AdaCore, Yannick Moy, 2014. The SPARK2014 verifying compiler, altran, Florian Schanda, 2015. Deductive Program Verification with Why3, J.-C. Filiâtre, DigiCosme Spring School, 2013. All online resources as of August 2017.

U 95min Martin Becker: Introduction to SPARK 2014 page 48 of 59 Extra Material (beyond 90’)

U 95min

U 95min Martin Becker: Introduction to SPARK 2014 page 49 of 59 The SPARK 2014 Subset

Not within SPARK: pointers exception handlers full Ada tasking (e.g., complex synchronization) various minor things (e.g., no goto) Not in Ada: certain SPARK-specific aspects (ignored by Ada compiler)

U 95min Martin Becker: Introduction to SPARK 2014 page 50 of 59 Concurrency = Ravenscar Profile

A ‘‘setting’’ that defines a deterministic subset of Ada’s tasking capabilities restrictions: only certain types of synchronization mechanisms (e.g., protected objects) scheduling policy: FIFO within priorities static core assignment on multi-core systems priority ceiling protocol memory boundedness during link-time only subset is allowed in SPARK 2014 for tasking All the details: The Guide for the use of the Ada Ravenscar Profile in high integrity systems, A. Burns, B. Dobbing and T. Vardanega, 2003.

U 95min Martin Becker: Introduction to SPARK 2014 page 51 of 59 Ravenscar Profile - Task Patterns Patterns for Tasks

Each task must follow one of two implementation patterns: 1 periodic infinite loop with single release point (delay until) 2 sporadic infinite loop which takes up on an event (interrupt, blocking read from queue, ...) Furthermore: number of tasks must be static tasks must not terminate no hierarchies of tasks ...

U 95min Martin Becker: Introduction to SPARK 2014 page 52 of 59 Ravenscar Profile - Tasks, no hierarchy

tasks are ‘‘all at same level’’ scope = package level master is always the system

U 95min Martin Becker: Introduction to SPARK 2014 page 53 of 59 Floating-Point Computations (‘‘digits’’) General Floating point types

type Temperature is digits 18 range -173.15 .. 1.41679*10**32; 3 type Mass is digits7 range 0.0 .. 1.0E35;

very weak minimum requirements for float: ideals (non-numeric values such as NaN, Inf) can be excluded unspecified behavior: Overflow, underflow, zero-divide at least 6 digits of precision (RM §3.5.7); towards better portability more digits: define own type with digits and optionally range compiler rejects type if it cannot implement requested precision semantics of user types are not required to follow IEEE 754

U 95min Martin Becker: Introduction to SPARK 2014 page 54 of 59 Floating-Point Computations (2) To get proof=reality, we must use IEEE-754 compliant FP computations

Built-in Types: Float and Long_Float floating-point hardware of target may or may not be used GNAT compiler: will use FP hardware non-GNAT: we can force the compiler to use FPU:

1 Temperature: Interfaces.IEEE_Float_32; Mass: Interfaces.IEEE_Float_64;

hardware may or may not be compliant most FPU can/must be configured to be compliant (e.g., disable flush-to-zero) GNAT: guarantees IEEE-754 semantics on x86 platforms, with flags -msse2 -mfpmath=sse to avoid extended 80bit precision complete model of Floating-Point arithmetic: RM §G.2.1.

U 95min Martin Becker: Introduction to SPARK 2014 page 55 of 59 Interval Arithmetic

Let f be a numeric operation of N arguments: f (x1,x2,..,xN). Then the corresponding interval operation F(I1,I2,..,IN) is defined as

F(I1,I2,..,IN) = [l,u], where (1)

l = inf( f (y1,y2,..,yN)) (2)

u = sup( f (y1,y2,..,yN)) (3)

yi ∈ Ii, i = 1..N (4)

⇒ preserve accuracy instead of (usually) precision Example

z = y1 + y2, with yi ∈ [li,ui]

⇒ z ∈ [l1 + l2,u1 + u2]

U 95min Martin Becker: Introduction to SPARK 2014 page 56 of 59 Interval Arithmetics (2) Ada library by Dmitry Kazakov, PhD (C.S., software architect) packages define types and overloads operations for tri-state logic, integers and floats. function ``*''(Left, Right: Interval) return Interval; function"*"(Left: Interval; Right: Number) return Interval; 3 function"*"(Left: Number; Right: Interval) return Interval;

internally using Float and Integer ⇒ implementation-defined results support rounding control (any rounding will produce intervals containing exact result) source code (GNU) available (e.g., to change to IEEE floats or fixed-point) See http://www.dmitry-kazakov.de/ada/intervals.htm

U 95min Martin Becker: Introduction to SPARK 2014 page 57 of 59 use volatile ⇒ NO. Slower for all reads and writes; not allowed for local variables in SPARK 2014 limited type (not copyable) ⇒ pass by ref enforced, solves ownership. How to wipe memory reliably in the owner?

Software with Sensitive Data

one problem: when variable with sensitive data is deallocated, memory should be wiped, e.g.: procedure Sensitive_Stuff is 2 x: String := Get_Password(); begin --... x := (others =>'');-- dead write, optimized out

7 -- at this point, memory allocated tox -- shall not hold password anymore end Sensitive_Stuff;

U 95min Martin Becker: Introduction to SPARK 2014 page 58 of 59 Software with Sensitive Data

one problem: when variable with sensitive data is deallocated, memory should be wiped, e.g.:

1 procedure Sensitive_Stuff is x: String := Get_Password(); begin --... x := (others =>'');-- dead write, optimized out 6 -- at this point, memory allocated tox -- shall not hold password anymore end Sensitive_Stuff;

use volatile ⇒ NO. Slower for all reads and writes; not allowed for local variables in SPARK 2014 limited type (not copyable) ⇒ pass by ref enforced, solves ownership. How to wipe memory reliably in the owner?

U 95min Martin Becker: Introduction to SPARK 2014 page 58 of 59 Software with Sensitive Data (2)

pragma Inspection_Point (from Annex H) ⇒ instructs compiler that object must be inspectable (i.e., not optimized out) at given program location

1 x := (others =>'');-- dead write, optimized out pragma Inspection_Point(x);

dead store cannot be optimized out allows compiler optimization for all other accesses & provides traceability to registers! Further: GNATprove detects dead stores and issues warnings ⇒ annotate code with suppression = documentation of data sanitization paper (given below) gives a practical guideline, and discusses many more of this in SPARK 2014

Roderick Chapman, Sanitizing Sensitive Data : How to Get It Right ( or at Least Less Wrong. . . ), Springer LNCS 10300, 2017.

U 95min Martin Becker: Introduction to SPARK 2014 page 59 of 59