2. Research Outline
Goal: Software Development with Verification
Specification: What is correct anyway?
Verification: Will the program behave correctly?
Our Work: Put them together in one language.
3. What is ATS (statically)?
http://www.ats-lang.org
Statically typed programming language that unifies
implementation, formal specification, and proof.
ML like syntax
Dependent Types
Linear Types
Compiled to C, JavaScript, Erlang
4. What is ATS (dynamically)?
As efficient as C/C++ (see The Computer Language
Benchmarks Game for concrete evidence).
Supports a variety of programming paradigm
(Functional, Imperative, Concurrent, and Modular
programming).
Feature-Rich practical PL: closure, pattern match,
unboxed data representation, polymorphism
(overloading, template).
Optional Runtime and GC.
5. What is ATS good for?
Building safety critical software without losing
efficiency.
Direct manipulating native unboxed data representation.
Tracking resources (e.g. memory) with linear types.
Integrating with C seamlessly.
Building program without runtime / gc (good for kernel
development)
Enforcing correctness via theorem proving.
6. What has been built using ATS?
ATS itself, and ATS website (JavaScript)
Scientific Computing
Linux Device Driver
Kernel
Terrier: OS in development for Panda and Beagle Boards.
Model Checker for ATS (under construction)
7. Helloworld in ATS
$ vi helloworld.dats
#include “share/atspre_staload.hats”
val () = println! (“Hello, World!”)
implement main0 () = let
val x = 1 + 3
in
println! (“x = “, x)
end
$ patscc helloworld.dats –o helloworld
$ ./helloworld
Hello, World!
x = 4
8. ATS Compile Process
ATS source code
Dynamics
Business Logic Proof
Statics
Types integer boolean ……
ATS compiler
Type Check
C source code
Binary
Compile
GCC compiler Compile
9. Dependent Types (Singleton Type)
#include “share/atspre_staload.hats”
val x = 2 / (1 – 1) // type error
fun mydiv {x,y:int} (a: int x, b: int y): [z:int] int z =
if b != 0 then a / b
else $raise div_by_0_exception
val y = mydiv (2, 1 – 1) // no type error
fun foo {x,y:int} (a:int x, b: int y): int (3 * (x + y)) = let
val v1 = 3 * a
val v2 = 3 * b
in
(v1 + v2)
end
1: int 1
/: {x,y: int | y != 0}
(int x, int y): [z:int] int z
Blue: type indices in the statics
Red: Entities in the dynamics
some types
10. Dependent Types (array)
// arrayref (a, n) is a type.
// It depends on two indices: type of element, length of array
fun{a:t@ype} array_make_elt{n:int}
(asz: size_t n, elt: a): arrayref (a, n)
fun{a:t@ype} arrayref_get_at {n:int}{i:nat | i < n}
(A: arrayref (a, n), pos: size_t i): a
overload [] with arrayref_get_at
fun{a:t@ype} arrayref_set_at {n:int}{i:nat | i < n}
(A: arrayref (a, n), pos: size_t i, x: a): void
overload [] with arrayref_set_at
typedef Int = [x:int] int x
val arr: arrayref (Int, 3) = arrayref_make_elt<Int> (i2sz(3), 0)
val v = arr[2]
val () = arr[i2sz(v)] := 99
val () = assertloc (v < 3)
val () = assertloc (v >= 0)
prfun fun pure_assert {b:bool}
(bool b): [b == true] void
prval () = pure_assert (v < 3)
prval () = pure_assert (v >= 0)
11. Specification:
What should a function do?
• SUM (x) = 0 + 1 + 2 + … + x
• relation: y = SUM (x)
y = SUM (x) = 0 if x = 0
y= SUM (x) = x + y1 if SUM (x - 1) = y1
fun sum (x: int): int =
if x = 0 then 0
else x + sum (x – 1)
)(.int:)0.(int: xSUMyyoutputyxinputxx
No Connection
between two worlds!
Implementation
12. Specification: Encoding via types
dataprop SUM (int, int) =
| SUMbas (0, 0) of ()
| {x,y1:int} SUMind (x+1, y1+x+1) of SUM (x, y1)
fun sum {x:int | x >= 0} (a: int x):
[y:int] (SUM (x, y) | int y) =
if a = 0 then (SUMbase () | 0)
else let
val (pf1 | s) = sum(a - 1)
prval pf = SUMind (pf1)
in
(pf | s + a)
end
13. Verification: Theorem Proving
dataprop SUM (int, int) =
| SUMbas (0, 0) of ()
| {x,y1:int} SUMind (x+1, y1+x+1) of SUM (x, y1)
fun sum_mul{x: int | x >= 0} (a: int x):
[s: int] (MUL (x, x+1, s) | int (s/2)) = let
val sum = a * (a + 1)
prval pf = mul_make ()
in
(pf | sum / 2)
end
extern prfun mul2sum {x,s:int | x >= 0}
(pf: MUL (x, x+1,s)): SUM (x, s / 2)
fun sum {x:int | x >= 0} (a: int x):
[y:int] (SUM (x, y) | int y) = let
val (pf_mul | sum) = sum_mul(a)
prval pf_sum = mul2sum (pf_mul)
in
(pf_sum | sum)
end
14. Linear Type (Intuition)
Program Entities of linear types can be consumed once
and exactly once.
Creation of
Linear Object
Passing on
Linear Object
Destruction of
Linear Object
15. Linear Type (viewtype)
Resource Management: lock, memory, interrupt, …
absviewt@ype lock
extern fun lock_acquire (): lock
extern fun lock_release (l: lock >> _): void
fun foo (): void = let
val l = lock_acquire ()
// ... process
val () = lock_release (l) // must release only once
in
end
16. Linear Type (View)
fun{a:vt0p} ptr_alloc ()
:<> [l:addr | l > 0]
(
a? @ l, mfree_gc_v (l) | ptr l
)
fun ptr_free {a:t@ype}{l:addr}
(
pfgc: mfree_gc_v (l)
, pfat: a @ l
| p: ptr l
):<> void
a? @ l
mfree_gc_v (l)
ptr l
view
(linear
proof)
Concrete
Code
Can Deference
Can NOT Deference
18. Combining Type Checking and
Model Checking
Modeling concurrent software system using ATS
Eliminate bugs in models as much as possible by type
checking
Verify models by model checking against temporal
properties (e.g. deadlock freeness, atomicity,
specification in linear temporal logic, and etc)