Non-logical Arrays

## 10.7 Non-logical Arrays

Non-logical arrays are a generalisation of the non-logical variable, capable of storing multiple values. An array has to be declared in advance. It has a fixed number of dimensions and a fixed size in each dimension. Arrays in ECLiPSe 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 ECLiPSe 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 initialized 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 initialized 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: Array is then an atom, and the 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.