ATS (Applied Type System) is a programming language designed to unify programming with formal specification. ATS has support for combining theorem proving with practical programming through the use of advanced
type system
In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a type to every "term" (a word, phrase, or other set of symbols). Usually the terms are various constructs of a computer progra ...
s.
[Combining Programming with Theorem Proving](_blank)
/ref> A past version of The Computer Language Benchmarks Game
The Computer Language Benchmarks Game (formerly called The Great Computer Language Shootout) is a free software project for comparing how a given subset of simple algorithms can be implemented in various popular programming languages.
The project ...
has demonstrated that the performance of ATS is comparable to that of the C and C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
programming languages. By using theorem proving and strict type checking, the compiler can detect and prove that its implemented functions are not susceptible to bugs such as division by zero
In mathematics, division by zero is division (mathematics), division where the divisor (denominator) is 0, zero. Such a division can be formally expression (mathematics), expressed as \tfrac, where is the dividend (numerator). In ordinary ari ...
, memory leak
In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in a way that Computer memory, memory which is no longer needed is not released. A memory leak may also happe ...
s, buffer overflow
In information security and programming, a buffer overflow, or buffer overrun, is an anomaly whereby a program, while writing data to a buffer, overruns the buffer's boundary and overwrites adjacent memory locations.
Buffers are areas of memory ...
, and other forms of memory corruption
Memory corruption occurs in a computer program when the contents of a memory location are modified due to programmatic behavior that exceeds the intention of the original programmer or program/language constructs; this is termed as violation of ...
by verifying pointer arithmetic
In computer science, a pointer is an object in many programming languages that stores a memory address. This can be that of another value located in computer memory, or in some cases, that of memory-mapped computer hardware. A pointer ''refe ...
and reference counting
In computer science, reference counting is a programming technique of storing the number of references, pointers, or handles to a resource, such as an object, a block of memory, disk space, and others.
In garbage collection algorithms, referenc ...
before the program compiles. Additionally, by using the integrated theorem-proving system of ATS (ATS/LF), the programmer may make use of static constructs that are intertwined with the operative code to prove that a function attains its specification.
History
ATS is derived mostly from the ML and OCaml
OCaml ( , formerly Objective Caml) is a general-purpose programming language, general-purpose, multi-paradigm programming language which extends the Caml dialect of ML (programming language), ML with object-oriented programming, object-oriented ...
programming languages. An earlier language, Dependent ML
Dependent ML is an experimental functional programming language proposed by Hongwei Xi and Frank Pfenning. Dependent ML extends ML by a restricted notion of dependent types: types may be dependent on static indices of type Nat (natural numbers). ...
, by the same author has been incorporated by the language.
The latest version of ATS1 (Anairiats) was released as v0.2.12 on 2015-01-20. The first version of ATS2 (Postiats) was released in September 2013.
Theorem proving
The primary focus of ATS is to support theorem proving
Automated theorem proving (also known as ATP or automated deduction) is a subfield of automated reasoning and mathematical logic dealing with proving mathematical theorems by computer programs. Automated reasoning over mathematical proof was a maj ...
in combination with practical programming. With theorem proving one can prove, for instance, that an implemented function does not produce memory leaks. It also prevents other bugs that might otherwise only be found during testing. It incorporates a system similar to those of proof assistant
In computer science and mathematical logic, a proof assistant or interactive theorem prover is a software tool to assist with the development of formal proofs by human-machine collaboration. This involves some sort of interactive proof editor ...
s which usually only aim to verify mathematical proofs—except ATS uses this ability to prove that the implementations of its functions operate correctly, and produce the expected output.
As a simple example, in a function using division, the programmer may prove that the divisor will never equal zero, preventing a division by zero
In mathematics, division by zero is division (mathematics), division where the divisor (denominator) is 0, zero. Such a division can be formally expression (mathematics), expressed as \tfrac, where is the dividend (numerator). In ordinary ari ...
error. Let's say, the divisor 'X' was computed as 5 times the length of list 'A'. One can prove, that in the case of a non-empty list, 'X' is non-zero, since 'X' is the product of two non-zero numbers (5 and the length of 'A'). A more practical example would be proving through reference counting
In computer science, reference counting is a programming technique of storing the number of references, pointers, or handles to a resource, such as an object, a block of memory, disk space, and others.
In garbage collection algorithms, referenc ...
that the retain count on an allocated block of memory is being counted correctly for each pointer. Then one can know, and quite literally prove, that the object will not be deallocated prematurely, and that memory leak
In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in a way that Computer memory, memory which is no longer needed is not released. A memory leak may also happe ...
s will not occur.
The benefit of the ATS system is that since all theorem proving occurs strictly within the compiler, it has no effect on the speed of the executable program. ATS code is often harder to compile than standard C code, but once it compiles the programmer can be certain that it is running correctly to the degree specified by their proofs (assuming the compiler and runtime system are correct).
In ATS proofs are separate from implementation, so it is possible to implement a function without proving it if the programmer so desires.
Data representation
According to the author (Hongwei Xi), ATS's efficiency is largely due to the way that data is represented in the language and tail-call optimizations (which are generally important for the efficiency of functional programming languages). Data can be stored in a flat or unboxed representation rather than a boxed representation.
Theorem Proving: An introductory case
Propositions
dataprop
expresses ''predicates
Predicate or predication may refer to:
* Predicate (grammar), in linguistics
* Predication (philosophy)
* several closely related uses in mathematics and formal logic:
**Predicate (mathematical logic)
**Propositional function
**Finitary relation, ...
'' as algebraic type
In computer programming, especially functional programming and type theory, an algebraic data type (ADT) is a kind of composite type, i.e., a type formed by combining other types.
Two common classes of algebraic types are product types (i.e., t ...
s.
Predicates in pseudo‑code somewhat similar to ATS source (see below for valid ATS source):
FACT(n, r) iff
In logic and related fields such as mathematics and philosophy, "if and only if" (shortened as "iff") is a biconditional logical connective between statements, where either both statements are true or both are false.
The connective is bicon ...
fact(n) = r
MUL(n, m, prod) iff
In logic and related fields such as mathematics and philosophy, "if and only if" (shortened as "iff") is a biconditional logical connective between statements, where either both statements are true or both are false.
The connective is bicon ...
n * m = prod
FACT(n, r) =
FACT(0, 1)
, FACT(n, r) iff FACT(n-1, r1) and MUL(n, r1, r) // for n > 0
''// expresses fact(n) = r iff
In logic and related fields such as mathematics and philosophy, "if and only if" (shortened as "iff") is a biconditional logical connective between statements, where either both statements are true or both are false.
The connective is bicon ...
r = n * r1 and r1 = fact(n-1)''
In ATS code:
dataprop FACT (int, int) =
, FACTbas (0, 1) // basic case: FACT(0, 1)
, // inductive case
FACTind (n, r) of (FACT (n-1, r1), MUL (n, r1, r))
where FACT (int, int) is a proof type
Example
Non tail-recursive factorial with proposition or "Theorem
In mathematics, a theorem is a statement that has been proved, or can be proved. The ''proof'' of a theorem is a logical argument that uses the inference rules of a deductive system to establish that the theorem is a logical consequence of th ...
" proving through the construction ''dataprop''.
The evaluation of returns a pair (proof_n_minus_1 , result_of_n_minus_1)
which is used in the calculation of . The proofs express the predicates of the proposition.
Part 1 (algorithm and propositions)
ACT (n, r)implies act (n) = r UL (n, m, prod)implies * m = prod
FACT (0, 1)
FACT (n, r) iff FACT (n-1, r1) and MUL (n, r1, r) forall n > 0
To remember:
universal quantification
..existential quantification
(... , ...) (proof , value)
@(...) flat tuple or variadic function parameters tuple
.<...>. termination metric
#include "share/atspre_staload.hats"
dataprop FACT (int, int) =
, FACTbas (0, 1) of () // basic case
, // inductive case
FACTind (n+1, (n+1)*r) of (FACT (n, r))
(* note that int(x) , also int x, is the monovalued type of the int x value.
The function signature below says:
forall n:nat, exists r:int where fact( num: int(n)) returns (FACT (n, r) , int(r)) *)
fun fact .. (n: int (n)) : :int(FACT (n, r) , int(r)) =
(
ifcase
, n > 0 => ((FACTind(pf1) , n * r1)) where
, _(*else*) => (FACTbas() , 1)
)
Part 2 (routines and test)
implement main0 (argc, argv) =
This can all be added to a single file and compiled as follows. Compilation should work with various back end C compilers, e.g. gcc. Garbage collection
Waste collection is a part of the process of waste management. It is the transfer of solid waste from the point of use and disposal to the point of treatment or landfill. Waste collection also includes the curbside collection of recyclable m ...
is not used unless explicitly stated with )
$ patscc fact1.dats -o fact1
$ ./fact1 4
compiles and gives the expected result
Features
Basic types
* bool (true, false)
* int (literals: 255, 0377, 0xFF), unary minus as ~ (as in ML)
* double
* char 'a'
* string "abc"
Tuples and records
; prefix @ or none means direct, ''flat'' or unboxed allocation
val x : @(int, char) = @(15, 'c') // x.0 = 15 ; x.1 = 'c'
val @(a, b) = x // pattern matching binding, a= 15, b='c'
val x = @ // x.first = 15
val @ = x // a= 15, b='c'
val @ = x // with omission, b='c'
; prefix ' means indirect or boxed allocation
val x : '(int, char) = '(15, 'c') // x.0 = 15 ; x.1 = 'c'
val '(a, b) = x // a= 15, b='c'
val x = ' // x.first = 15
val ' = x // a= 15, b='c'
val ' = x // b='c'
; special
With ', ' as separator, some functions return wrapped the result value with an evaluation of predicates
val ( predicate_proofs , values) = myfunct params
Common
universal quantification
..existential quantification
(...) parenthetical expression or tuple
(... , ...) (proofs , values)
.<...>. termination metric
@(...) flat tuple or variadic function
In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.
The term ''varia ...
parameters tuple (see example's ''printf'')
@ yteBUFLEN] type of an array of BUFLEN values of type ''byte''
@ yteBUFLEN]() array instance
@ yteBUFLEN](0) array initialized to 0
Dictionary
sortdef nat = // from prelude: ∀ ''a'' ∈ int ...
typedef String =
:natstring(a) //
. ∃ ''a'' ∈ nat ...
generic ''sort'' for elements with the length of a pointer word, to be used in type parameterized polymorphic functions. Also "boxed types"
// : ∀ a,b ∈ type ...
fun swap_type_type (xy: @(a, b)): @(b, a) = (xy.1, xy.0)
relation of a Type and a memory location. The infix is its most common constructor
: asserts that there is a view of type T at location L
fun ptr_get0 (pf: a @ l , p: ptr l): @(a @ l , a)
fun ptr_set0 (pf: a? @ l , p: ptr l, x: a): @(a @ l , void)
:the type of ptr_get0 (T)
is ∀ l : addr . ( T @ l , ptr( l ) ) -> ( T @ l , T) // see manual, section 7.1. Safe Memory Access through Pointers
viewdef array_v (a:viewt@ype, n:int, l: addr) = @
n] @ l
pattern matching exhaustivity
as in case+, val+, type+, viewtype+, ...
* with suffix '+' the compiler issues an error in case of non exhaustive alternatives
* without suffix the compiler issues a warning
* with '-' as suffix, avoids exhaustivity control
modules
staload "foo.sats" // foo.sats is loaded and then opened into the current namespace
staload F = "foo.sats" // to use identifiers qualified as $F.bar
dynload "foo.dats" // loaded dynamically at run-time
dataview
Dataviews are often declared to encode recursively defined relations on linear resources.
dataview array_v (a: viewt@ype+, int, addr) =
, array_v_none (a, 0, l)
,
array_v_some (a, n+1, l)
of (a @ l, array_v (a, n, l+sizeof a))
datatype / dataviewtype
Datatypes
datatype workday = Mon , Tue , Wed , Thu , Fri
lists
datatype list0 (a:t@ype) = list0_cons (a) of (a, list0 a) , list0_nil (a)
dataviewtype
A dataviewtype is similar to a datatype, but it is linear. With a dataviewtype, the programmer is allowed to explicitly free (or deallocate) in a safe manner the memory used for storing constructors associated with the dataviewtype.
variables
local variables
var res: int with pf_res = 1 // introduces pf_res as an alias of ''view @ (res)''
''on stack'' array allocation:
#define BUFLEN 10
var !p_buf with pf_buf = @ yteBUFLEN](0) // pf_buf = @ yteBUFLEN](0) @ p_buf
See ''val'' and ''var '' declarationsVal and Var declarations
(outdated)
References
External links
{{Wikibooks, ATS: Programming with Theorem-Proving
ATS home pageDocumentation for ATS2
The ATS Programming LanguageOld documentation for ATS1
ManualDraft (outdated). Some examples refer to features or routines not present in the release (Anairiats-0.1.6) (e.g.: print overload for strbuf, and using its array examples gives errmsgs like "use of array subscription is not supported".)
ATS for ML programmersLearning examples and short use‑cases of ATS
Multi-paradigm programming languages
Declarative programming languages
Functional languages
Dependently typed languages
Systems programming languages
Programming languages created in 2004