## 9.6 Non-logical Arrays

Non-logical arrays are a generalisation of the non-logical variable, capable of storing
multiple values.
Arrays have to be declared in advance.
They have a fixed number of dimensions and a fixed size in each dimension.
Arrays in ECL^{i}PS^{e} are managed solely by special predicates.
In these predicates, arrays are represented by compound terms, e.g.
**matrix(5, 8)**
where **matrix** is the name of the array, the arity of 2 specifies
the number of dimensions, and the integers 5 and 8 specify the size
in each dimension. The number of elements this array can hold is
thus 5*8 = 40.
The elements of this array can be addressed from **matrix(0,0)**
up to **matrix(4,7)**.

An array must be explicitly created using a
**local/1**
**array/1**
declaration, e.g.
:- local array(matrix(5, 8)).

The array is only accessible from within the module where it was declared.
The declaration will create a two-dimensional, 5-by-8 array with 40 elements
matrix(0,0) to matrix(4, 7).
Arrays can be erased using the predicate
**erase_array/1**, e.g.
erase_array(matrix/2).

The value of an element of the array is set using the **setval/2**
predicate. The first argument of **setval/2** specifies the element which is
to be set, the second specifies the value to assign to it.
The goal
setval(matrix(3, 2), plato)

sets the value
of element (3, 2) of array `matrix` to the atom `plato`.
Similarly, values of array elements are retrieved by use of the **getval/2**
predicate. The first argument of **getval/2** specifies the element to be
referenced, the second is unified with the value of that element.
Thus if the value of matrix(3, 2) had been set as above, the goal
getval(matrix(3, 2), Val)

would unify `Val` with the atom `plato`.
Similarly to non-logical variables, the value of integer array elements
can be updated using **incval/1** and **decval/1**.

It is possible to declare arrays whose elements are
constrained to belong to certain types. This allows ECL^{i}PS^{e} to increase
time and space efficiency of array element manipulation.
Such an array is created for instance by the predicate
:- local array(primes(100),integer).

The second argument specifies the type of the elements of the array.
It takes as value an atom from the
list `float` (for floating point numbers),
`integer` (for integers), `byte` (an integer modulo 256),
or `prolog` (any Prolog term - the resulting array is the
same as if no type was specified).
When a typed array is created, the value of each element is initialised to zero
in the case of `byte`, `integer` and `float`, and to
an uninstantiated variable in the case of `prolog`.
Whenever a typed array element is set, type checking is carried out.

As an example of the use of a typed array, consider the following goal, which
creates a 3-by-3 matrix describing a 90 degree rotation about the x-axis of
a Cartesian coordinate system.
:- local array(rotate(3, 3), integer).
:- setval(rotate(0, 0), 1),
setval(rotate(1, 2), -1),
setval(rotate(2, 1), 1).

(The other elements of the above array are automatically initialised to zero).

The predicate **current_array/2**
is provided to find the size, type and visibility of defined arrays.
of the array and its type to be found:
**current_array(Array, Props)**

where *Array* is the array specification as in the declaration (but it
may be uninstantiated or partially instantiated), and *Props* is
a list indicating the array's type and visibility.
Non-logical variables are also returned, with *Array* being an atom and their
type is `prolog`.
[eclipse 1]: local(array(pair(2))),
setval(count, 3),
local(array(count(3,4,5), integer)).
yes.
[eclipse 2]: current_array(Array, Props).
Array = pair(2)
Props = [prolog, local] More? (;)
Array = count
Props = [prolog, local] More? (;)
Array = count(3, 4, 5)
Props = [integer, local] More? (;)
no (more) solution.
[eclipse 3]: current_array(count(X,Y,Z), _).
X = 3
Y = 4
Z = 5
yes.