mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-30 16:54:41 +00:00
library/array.m: Fix NU-Prolog incompatibility: `X1 is X+1' must be written as `X1 is X + 1'.
180 lines
6.2 KiB
Mathematica
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]
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|