ats programming
TRANSCRIPT
Programming with Applied Type System
Zhiqiang RenBoston University
Research OutlineGoal: Software Development with
VerificationSpecification: What is correct anyway?Verification: Will the program behave
correctly?Our Work: Put them together in one
language.
What is ATS (statically)?http://www.ats-lang.orgStatically typed programming language that
unifies implementation, formal specification, and proof.
ML like syntaxDependent TypesLinear TypesCompiled to C, JavaScript, Erlang
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.
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.
What has been built using ATS? ATS itself, and ATS website (JavaScript)Scientific ComputingLinux Device DriverKernel
Terrier: OS in development for Panda and Beagle Boards.
Model Checker for ATS (under construction)
Helloworld in ATS$ vi helloworld.dats#include “share/atspre_staload.hats”val () = println! (“Hello, World!”)
implement main0 () = let val x = 1 + 3in println! (“x = “, x)end$ patscc helloworld.dats –o helloworld$ ./helloworldHello, World!x = 4
ATS Compile ProcessATS source code
DynamicsBusiness
Logic ProofStaticsTypes intege
rboolea
n ……
ATS compiler Type Check
C source code
Binary
Compile
GCC compilerCompile
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 * bin (v1 + v2)end
1: int 1/: {x,y: int | y != 0} (int x, int y): [z:int] int z
Blue: type indices in the staticsRed: Entities in the dynamics
some types
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 xval 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] voidprval () = pure_assert (v < 3)prval () = pure_assert (v >= 0)
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
Specification: Encoding via typesdataprop 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
Verification: Theorem Provingdataprop 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
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
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 onceinend
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)Concre
te Code
Can Deference
Can NOT Deference
Program VerificationProve that the implementation meets the specificationTheorem ProvingModel Checking
Combining Type Checking and Model CheckingModeling concurrent software system using
ATSEliminate bugs in models as much as possible
by type checkingVerify models by model checking against
temporal properties (e.g. deadlock freeness, atomicity, specification in linear temporal logic, and etc)
Q & AThank You.Questions?