ATS consists of a static component (statics), where types are formed and
reasoned about, and a dynamic component (dynamics), where programs are
constructed and evaluated.
Some Primitive Sorts and Constants
The statics of ATS is a simply typed language. The types for terms in the
statics are called sorts (so as to avoid potential confusion with
the types for terms in the dynamics) and the terms in it are called
static terms. We use sigma (or $srt) for sorts and
s (or $strm) for static terms. The primitive sorts in ATS
include
bool,
char,
int,
prop,
type,
view and
viewtype.
There are also some primitive constants c in the statics, each of which
is assigned a constant sort (or c-sort, for short) of the following form:
(sigma_1,...,sigma_n) => sigma
Intuitively, given static terms s_1,...,s_n of sorts
sigma_1,...,sigma_n, respectively, c(s_1,...,s_n) is a static
term of sort sigma if c is assigned the c-sort
(sigma_1,...,sigma_n) => sigma. For instance, each boolean value is
given the sort () => bool and each integer is given the c-sort ()
=> int. In the following table, we list some of the commonly used
constants in the statics of ATS:
|
|
|
~ |
| : |
| (int) => int |
+ |
| : |
| (int, int) => int |
- |
| : |
| (int, int) => int |
* |
| : |
| (int, int) => int |
/ |
| : |
| (int, int) => int |
< |
| : |
| (int, int) => bool |
<= |
| : |
| (int, int) => bool |
> |
| : |
| (int, int) => bool |
>= |
| : |
| (int, int) => bool |
== |
| : |
| (int, int) => bool |
<> |
| : |
| (int, int) => bool |
~ |
| : |
| (bool) => bool |
&& |
| : |
| (bool, bool) => bool |
|| |
| : |
| (bool, bool) => bool |
bool |
| : |
| () => type |
bool |
| : |
| (bool) => type |
int |
| : |
| () => type |
int |
| : |
| (int) => type |
Note that many symbols are overloaded in ATS. For instance,
~ is for negation on integers as well as on booleans;
bool and int are both sorts and static constants.
In ATS, a type refers to a static term s of sort type. For
instance, bool and bool(true) are types, and int and
int(2+3) are types, too.
Subset Sorts
A subset sort is essentially a sort constrained by a predicate. For
instance, we can define a subset sort nat as follows:
sortdef nat = {a:int | a >= 0}
It is important to note that a subset sort is not regarded as a
(regular) sort. The sole purpose of introducing subset sorts is to provide
a form of syntactic sugar (to be used together with quantifiers), which is
to be explained shortly. Following are some commonly used subset sorts:
sortdef two = {a:nat | a < 2}
sortdef sgn = {a:int | -1 <= a && a <= 1}
sortdef sgn = {a:int | a == -1 || a == 0 || a == 1} // another definition
sortdef pos = {a:int | a > 0}
sortdef neg = {a:int | a < 0}
where && and ||
stand for conjunction and disjunction, respectively.
Note that we may also use semicolon ; for conjunction. For instance,
the subset sort sgn can be defined as follows:
sortdef sgn = {a:int | -1 <= a; a <= 1}
Some Primitive Types and Values
We use the name dynamic term for a term in the dynamics of ATS and
a value is a dynamic term in a special form (which is to be made clear
later). We have primitive types
bool, char, int and string for booleans,
characters, integers and strings, respectively. Also, we have types
float and double for floating point numbers with single and
double precision, respectively.
The syntax for literal characters, literal integers, literal floats and
literal strings is the same as that specified in the ANSI C.
The use of dependent types in ATS is ubiquitous. Given a boolean b,
we can form a type bool(b) and the only value that can be assigned
this type is the boolean value b. In other words, bool(b) is
a singleton type. Similarly, we can form a type int(i) for each
integer i and the only value that can be assigned this type is the
integer value i. The dependent types Bool and Int,
which are for boolean values and integer values, respectively, can be
defined as follows in ATS:
typedef Bool = [a:bool] bool(a)
typedef Int = [a:int] int(a)
where we use [...] for existential quantification. Given an integer
i, we can form a type string(i) for strings of length
i. The type String for strings is defined as follows:
typedef String = [a:nat] string (a)
Guarded and Asserting Types
Given a proposition B, that is, a static term of sort
bool and a type T, we use the name guarded type for
a type of the form B =) T and the name asserting type for a
type of the form B /\ T. Intuitively, in order for a value of type
B =) T to be used, which is most likely a function, the guard B
needs to be discharged first. On the other hand, if an expression of type
B /\ T evaluates to a value v, then we know that the
assertion B holds (at the point where v is obtained) and
v is of type T.
Elements of Programming
We use $exp and $typ as meta-variables ranging over
expressions (dynamic terms) and types in ATS.
Comments
There are currently three forms of comments in ATS/Anairiats.
-
A line comment starts with a double slash "//" and ends with a newline
character.
-
A rest-of-file comment starts with a quadruple slash "////" and ends at the
end of the file in which this comment occurs. This style is often useful
for debugging or testing.
-
An enclosed comment starts with the symbol "(*" and ends with "*)". Such
comments can be embedded in one another.
As in C, it is also possible to comment out a piece of code in ATS as
follows:
#if 0 #then // [#then] is optional
(all the code here is commented out)
#endif
The only requirement is that the code that is commented out must represent
a list of syntactically correct declarations in ATS.
The code used for illustration is available here.