SPARK (programming language)
![]() | This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these messages)
|
![]() | |
Paradigm | Multi-paradigm |
---|---|
Developer | Altran and AdaCore |
Stable release | 15.0.1
/ February 17, 2015 |
Typing discipline | static, strong, safe, nominative |
OS | Cross-platform: Linux, Microsoft Windows, Mac OS X |
License | GPLv3 |
Website | SPARK Pro Toolset "Libre" SPARK GPL Edition |
Major implementations | |
SPARK Pro, SPARK GPL Edition | |
Influenced by | |
Ada, Eiffel |
SPARK is a formally defined computer programming language based on the Ada programming language, intended for the development of high integrity software used in systems where predictable and highly reliable operation is essential. It facilitates the development of applications that demand safety, security, or business integrity.
Originally, there were three versions of the SPARK language (SPARK83, SPARK95, SPARK2005) based on Ada 83, Ada 95 and Ada 2005 respectively.
A fourth version of the SPARK language, SPARK 2014, based on Ada 2012, was released on April 30, 2014. SPARK 2014 is a complete re-design of the language and supporting verification tools.
The SPARK language consists of a well-defined subset of the Ada language that uses contracts to describe the specification of components in a form that is suitable for both static and dynamic verification.
In SPARK83/95/2005, the contracts are encoded in Ada comments (and so are ignored by any standard Ada compiler), but are processed by the SPARK "Examiner" and its associated tools.
SPARK 2014, in contrast, uses Ada 2012's built-in "aspect" syntax to express contracts, bringing them into the core of the language. The main tool for SPARK 2014 (GNATprove) is based on the GNAT/GCC infrastructure, and re-uses almost the entirety of the GNAT Ada 2012 front-end.
Technical overview
SPARK aims to exploit the strengths of Ada while trying to eliminate all its potential ambiguities and insecurities. SPARK programs are by design meant to be unambiguous, and their behavior is required to be unaffected by the choice of Ada compiler. These goals are achieved partly by omitting some of Ada's more problematic features (such as unrestricted parallel tasking) and partly by introducing contracts which encode the application designer's intentions and requirements for certain components of a program.
The combination of these approaches is meant to allow SPARK to meet its design objectives, which are:
- logical soundness
- rigorous formal definition
- simple semantics
- security
- expressive power
- verifiability
- bounded resource (space and time) requirements.
- minimal runtime system requirements
Contract examples
Consider the Ada subprogram specification below:
procedure Increment (X : in out Counter_Type);
What does this subprogram actually do? In pure Ada, it could do virtually anything – it might increment the X
by one or one thousand; or it might set some global counter to X
and return the original value of the counter in X
; or it might do absolutely nothing with X
at all.
With SPARK 2014, contracts are added to the code to provide additional information regarding what a subprogram actually does. For example, we may alter the above specification to say:
procedure Increment (X : in out Counter_Type) with Global => null, Depends => (X => X);
This specification tells us that the Increment procedure does not update or read from any global variables and that the only data item used in calculating the new value of X is X itself.
Alternatively, the designer might specify:
procedure Increment (X : in out Counter_Type) with Global => (In_Out => Count), Depends => (Count => (Count, X), X => null);
The second specification tells us that Increment
will use some global variable called "Count
" in the same package as Increment
and that the exported value of Count
is dependent on the imported values of Count
and X
, but that exported value of X
does not depend on any variables at all – it will be derived simply from constant data.
If GNATprove is then run on the specification and corresponding body of a subprogram, it will analyse the body of the subprogram to build up a model of the information flow. This model is then compared against that which has been specified by the annotations and any discrepancies reported to the user.
We can further extend these specifications by asserting various properties that either need to hold when a subprogram is called (preconditions) or that will hold once execution of the subprogram has completed (postconditions). For example, we could say the following:
procedure Increment (X : in out Counter_Type) with Global => null, Depends => (X => X), Pre => X < Counter_Type'Last, Post => X = X'Old + 1;
This specification now says that not only is X
only derived from itself, but that before Increment
is called X
must be strictly less than the last possible value of its type and that afterwards X
will be equal to the initial value of X
plus one – no more and no less.
Verification Conditions
GNATprove can also generate a set of Verification Conditions or VCs. VCs are used to attempt to establish certain properties hold for a given subprogram. At a minimum, the GNATprove will generate VCs attempting to establish that all run-time errors cannot occur within a subprogram, such as
- array index out of range
- type range violation
- division by zero
- numerical overflow.
If a postcondition or other assertions are added to a subprogram, GNATprove will also generate VCs that require the user to show that these properties hold for all possible paths through the subprogram.
Under the hood, GNATprove uses the Why3 intermediate language and VC Generator, and the Alt-Ergo theorem prover to discharge VCs. Use of other provers (including interactive proof checkers) is also possible through other components of the Why3 toolset.
History
The first version of SPARK (based on Ada 83) was produced at the University of Southampton (with UK Ministry of Defence sponsorship) by Bernard Carré and Trevor Jennings. Subsequently the language was progressively extended and refined, first by Program Validation Limited and then by Praxis Critical Systems Limited. In 2004, Praxis Critical Systems Limited changed its name to Praxis High Integrity Systems Limited. In January 2010, the company became Altran Praxis.
In early 2009, Praxis formed a partnership with AdaCore, and released "SPARK Pro" under the terms of the GPL. This was followed in June 2009 by the SPARK GPL Edition 2009, aimed at the FLOSS and academic communities.
In June 2010, Altran-Praxis announced that the SPARK programming language would be used in the software of US Lunar project CubeSat, expected to be completed in 2015.
In January 2013, Altran-Praxis changed its name to Altran.
The first Pro release of SPARK 2014 was announced on April 30, 2014, and was quickly followed by the SPARK 2014 GPL edition, aimed at the FLOSS and academic communities.
Industrial applications
Safety related systems
SPARK has been used in several high profile safety-critical systems, covering commercial aviation (Rolls-Royce Trent series jet engines, the ARINC ACAMS system, the Lockheed Martin C130J), military aviation (EuroFighter Typhoon, Harrier GR9, AerMacchi M346), air-traffic management (UK NATS iFACTS system), rail (numerous signalling applications), medical (the LifeFlow ventricular assist device), and space applications (the Vermont Technical College CubeSat project).
Security related systems
SPARK has also been used in secure systems development. Users include Rockwell Collins (Turnstile and SecureOne cross-domain solutions), the development of the original MULTOS CA, the NSA Tokeneer demonstrator, the secunet multi-level workstation, and the Muen separation kernel.
In August 2010, Rod Chapman, principal engineer of Altran Praxis, implemented Skein, one of candidates for SHA-3, in SPARK. He wanted to compare the performance of the SPARK and C implementations. After careful optimization, he managed to have the SPARK version only about 5 to 10% slower than C. Later improvement to the Ada middle-end in GCC (implemented by Eric Botcazou of AdaCore) closed the gap, with the SPARK code matching the C in performance exactly.[1]
See also
- Z notation
- Java Modeling Language
- Extended static checking
- Static code analysis
- List of tools for static code analysis
Notes
- ^ Handy, Alex (August 24, 2010). "Ada-derived Skein crypto shows SPARK". SD Times. BZ Media LLC. Retrieved 2010-08-31.
References
- John Barnes (June 15, 1997). High Integrity Ada: The SPARK Approach. Addison-Wesley. ISBN 0-201-17517-7.
- John Barnes (April 25, 2003). High Integrity Software: The SPARK Approach to Safety and Security. Addison-Wesley. ISBN 0-321-13616-0.
- John Barnes (2012). SPARK: The Proven Approach to High Integrity Software. Altran Praxis. ISBN 978-0-9572905-1-8.
- Philip E. Ross (September 2005). "The Exterminators". IEEE Spectrum. 42 (9): 36–41. doi:10.1109/MSPEC.2005.1502527. ISSN 0018-9235.
External links
- SPARK 2014
- SPARK Pro website
- SPARK Libre Edition website
- Altran
- Correctness by Construction: A Manifesto for High-Integrity Software
- UK's Safety-Critical Systems Club
- Comparison with a C specification language (Frama C)
- Tokeneer Project Page
- Muen Kernel Public Release
- LifeFlow LVAD Project
- VTU CubeSat Project