1:- module(type_list,
2 [
3 op(100, yf, []), 4 op(500, yfx, \\), 5 slice_parameters/4, 6 index_parameters/3 7 ]).
32:- use_module(library(arithmetic_types)). 34
38
39:- arithmetic_function(new/2). 40:- arithmetic_function('[|]'/2). 41:- arithmetic_function([]/1). 42:- arithmetic_function([]/2). 43:- arithmetic_function(: /2). 45:- arithmetic_function(init/2). 46:- arithmetic_function(\\ /2). 48:- arithmetic_function(arange/2). 49:- arithmetic_function(arange/3). 50:- arithmetic_function(arange/4). 51
56slice_parameters(B:E,Len,SBegin,SLen) :-
57 item_eval(B,Br), (var(Br) -> Br=0 ; integer(Br)),
58 item_eval(E,Er), (var(Er) -> Er=Len ; integer(Er)),
59 (Br<0 -> SBegin is Len+Br ; SBegin=Br),
60 (Er<0 -> SLen is Len+Er-SBegin ; SLen is Er-SBegin).
61
63index_parameters(Ix,Len,I) :-
64 item_eval(Ix,EIx),
65 integer(EIx),
66 (EIx < 0 -> I is Len+EIx ; I = EIx),
67 I >= 0.
68
70item_eval(X,X) :- var(X), !. 71item_eval(N,N) :- number(N), !. 72item_eval(X,R) :-
73 catch(arithmetic_expression_value(X,R), _, R=X). 74
78':'(B,E,B:E).
79
83'[|]'(X,Xs,[X|Xs]). 84
88new(list,Size,L) :- integer(Size), Size >= 0, (nonvar(L) -> is_list(L) ; true), !,
89 length(L,Size).
90
91new(list,Xs,Xs) :- is_list(Xs).
92
96[](L, L) :- is_list(L).
97[]([I1,I2|IN],T,X) :- !, 98 T1 is T[I1], 99 X is T1[I2|IN].
100[]([B:E],L,X) :- is_list(L),
101 length(L,Len),
102 slice_parameters(B:E,Len,SB,SL), !,
103 sub_list(L,SB,SL,_,X).
104[]([Ix], L, R) :- is_list(L),
105 length(L,Len),
106 index_parameters(Ix,Len,I),
107 108 (I =< 28 -> skip_N(I,L,[X|_]) ; (T=..[$|L], arg(I,T,X))),
109 item_eval(X,R). 110
112sub_list(L,Before,Length,After,SubL) :- integer(Before), integer(Length), is_list(L),
113 skip_N(Before,L,L1), 114 next_N(Length,L1,SubL,L2), 115 length(L2,After), 116 !. 117
118skip_N(0,In,In):- !.
119skip_N(1,[_|In],In):- !.
120skip_N(N,[_,_|Xs],Out) :- 121 N1 is N-2,
122 skip_N(N1,Xs,Out).
123
124next_N(0,In,[],In) :- !.
125next_N(1,[X|In],[X],In) :- !.
126next_N(N,[X1,X2|In],[X1,X2|Out],Rem) :- 127 N1 is N-2,
128 next_N(N1,In,Out,Rem).
129
133:- redefine_system_predicate(length(_,_)). 134
135length(L,N) :- is_list(L),
136 system:length(L,N).
137
138:- arithmetic_function(length/1). 139
143init(L, Value, L) :- is_list(L),
144 fill_each(L,Value).
145
146fill_each([],_).
147fill_each([X|Xs],Value) :-
148 (is_list(X)
149 -> fill_each(X,Value)
150 ; (var(X) -> X=Value ; true)
151 ),
152 fill_each(Xs,Value).
153
157\\(L1, L2, R) :- nonvar(L1), is_list(L2), 158 append_det(L1,L2,R).
159
160append_det([], L, L) :- !. 161append_det([H|T], L, [H|R]) :-
162 append_det(T, L, R).
163
167flatten(List,FList) :- is_list(List),
168 lists:flatten(List,FList).
169
170:- arithmetic_function(flatten/1). 171
175arange(list,N,L) :- number(N), N>0,
176 arange_(0,N,1,L).
177
178arange(list,B,E,L) :- number(B), number(E),
179 B>=0, E>B,
180 arange_(B,E,1,L).
181
182arange(list,B,E,S,L) :- number(B), number(E), number(S),
183 B>=0, E>B, S>0,
184 arange_(B,E,S,L).
185
186arange_(B,E,_S,[]) :- B>=E, !.
187arange_(B,E,S,[B|Vs]) :-
188 B1 is B+S,
189 arange_(B1,E,S,Vs)
arithmetic type support for lists
This module implements a set of functions on lists which can be used in standard arithmetic expressions, including block indexing and slicing (using
[]
as a postfix operator), concatenation, flatten, fill from a range, etc. It also exports a couple of predicates to support indexing and slicing on other "sequence" types.The set of list arithmetic functions defined by this module include:
See the ReadMe for this pack for more documentation and examples. */