Files
mercury/library/array.m
Fergus Henderson 21fd6b777d Fix NU-Prolog incompatibility: `X1 is X+1' must be written
library/array.m:
	Fix NU-Prolog incompatibility: `X1 is X+1' must be written
	as `X1 is X + 1'.
1995-05-26 05:53:31 +00:00

180 lines
6.2 KiB
Mathematica

%---------------------------------------------------------------------------%
% Copyright (C) 1995 University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%-----------------------------------------------------------------------------%
% array.m
% Main author: bromage.
% this file contains a set of predicates for generating an manipulating
% an array data structure. It is based on the original module by conway,
% which used 2-3 trees to store the array. This uses the map module
% instead, because it's less likely to contain bugs. :-)
%
% Arrays will be internal soon anyway, so it doesn't really matter how
% efficient this code is, as long as it works.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- module array.
:- interface.
:- import_module int, list.
:- type array(T).
% array__init creates an array with bounds from Low to High, with each
% element initialized to Init.
:- pred array__init(int, int, T, array(T)).
:- mode array__init(in, in, in, out) is det. % want an array_skeleton?
% array__bounds returns the upper and lower bounds of an array.
:- pred array__bounds(array(_T), int, int).
:- mode array__bounds(in, out, out) is det.
% array__lookup returns the Nth element of an array
% or aborts if the index is out of bounds.
:- pred array__lookup(array(T), int, T).
:- mode array__lookup(in, in, out) is det.
% array__semidet_lookup is like array__lookup except that
% it fails if the index is out of bounds.
:- pred array__semidet_lookup(array(T), int, T).
:- mode array__semidet_lookup(in, in, out) is semidet.
% array__set sets the nth element of an array, and returns the resulting
% array (good oppertunity for destructive update ;-). It aborts if the
% index is out of bounds.
:- pred array__set(array(T), int, T, array(T)).
:- mode array__set(in, in, in, out) is det.
% array__resize takes an array and new lower and upper bounds.
% the array is expanded or shrunk at each end to make it fit
% the new bounds.
:- pred array__resize(array(T), int, int, array(T)).
:- mode array__resize(in, in, in, out) is det.
% array__from_list takes a list (of nonzero length),
% and returns an array containing those elements in
% the same order that they occured in the list.
:- pred array__from_list(list(T), array(T)).
:- mode array__from_list(in, out) is det.
% array__to_list takes an array and returns a list containing the
% elements of the array in the same order that they
% occured in the array.
:- pred array__to_list(array(T), list(T)).
:- mode array__to_list(in, out) is det.
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module require, map.
:- type array(T) ---> array(int, int, map(int,T)).
%-----------------------------------------------------------------------------%
array__init(Low, High, Item, array(Low, High, MapOut)) :-
map__init(MapIn),
array__init_2(Low, High, Item, MapIn, MapOut).
:- pred array__init_2(int, int, T, map(int,T), map(int,T)).
:- mode array__init_2(in, in, in, in, out) is det.
array__init_2(Low, High, Item, ArrayIn, ArrayOut) :-
( Low > High ->
ArrayIn = ArrayOut
;
map__det_insert(ArrayIn, Low, Item, Array1),
Low1 is Low + 1,
array__init_2(Low1, High, Item, Array1, ArrayOut)
).
%-----------------------------------------------------------------------------%
array__bounds(array(Low, High, _), Low, High).
%-----------------------------------------------------------------------------%
array__lookup(array(Low, High, Map), Index, Item) :-
( ( Low =< Index, Index =< High ) ->
map__lookup(Map, Index, Item)
;
error("array__lookup: Array subscript out of bounds")
).
array__semidet_lookup(array(Low, High, Map), Index, Item) :-
Low =< Index, Index =< High,
map__lookup(Map, Index, Item).
%-----------------------------------------------------------------------------%
array__set(array(Low, High, MapIn), Index, Item, array(Low, High, MapOut)) :-
( ( Low =< Index, Index =< High ) ->
map__set(MapIn, Index, Item, MapOut)
;
error("array__set: Array subscript out of bounds")
).
%-----------------------------------------------------------------------------%
array__resize(Array0, L, H, Array) :-
array__bounds(Array0, L0, H0),
array__lookup(Array0, L0, Item),
int__max(L, L0, L1),
int__min(H, H0, H1),
array__fetch_items(Array0, L1, H1, Items),
array__init(L, H, Item, Array1),
array__insert_items(Array1, L1, Items, Array).
%-----------------------------------------------------------------------------%
array__from_list([], array(1, 0, Map)) :-
map__init(Map).
array__from_list(List, Array) :-
List = [ Head | Tail ],
list__length(List, Len),
array__init(1, Len, Head, Array0),
array__insert_items(Array0, 2, Tail, Array).
%-----------------------------------------------------------------------------%
:- pred array__insert_items(array(T), int, list(T), array(T)).
:- mode array__insert_items(in, in, in, out) is det.
array__insert_items(Array, _N, [], Array).
array__insert_items(Array0, N, [Head|Tail], Array) :-
array__set(Array0, N, Head, Array1),
N1 is N + 1,
array__insert_items(Array1, N1, Tail, Array).
%-----------------------------------------------------------------------------%
array__to_list(Array, List) :-
array__bounds(Array, Low, High),
array__fetch_items(Array, Low, High, List).
%-----------------------------------------------------------------------------%
:- pred array__fetch_items(array(T), int, int, list(T)).
:- mode array__fetch_items(in, in, in, out) is det.
array__fetch_items(Array, Low, High, List) :-
(
Low > High
->
List = []
;
Low1 is Low + 1,
array__fetch_items(Array, Low1, High, List0),
array__lookup(Array, Low, Item),
List = [Item|List0]
).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%