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:- set_prolog_flag(unknown,fail). 40
41:- arithmetic_function(new/2). 42:- arithmetic_function('[|]'/2). 43:- arithmetic_function([]/1). 44:- arithmetic_function([]/2). 45:- arithmetic_function(: /2). 47:- arithmetic_function(init/2). 48:- arithmetic_function(\\ /2). 49:- arithmetic_function(flatten/1). 50:- arithmetic_function(arange/2). 51:- arithmetic_function(arange/3). 52:- arithmetic_function(arange/4). 53
58slice_parameters(B:E,Len,SBegin,SLen) :-
59 item_eval(B,Br), (var(Br) -> Br=0 ; integer(Br)),
60 item_eval(E,Er), (var(Er) -> Er=Len ; integer(Er)),
61 (Br<0 -> SBegin is Len+Br ; SBegin=Br),
62 (Er<0 -> SLen is Len+Er-SBegin ; SLen is Er-SBegin).
63
65index_parameters(Ix,Len,I) :-
66 item_eval(Ix,EIx),
67 integer(EIx),
68 (EIx < 0 -> I is Len+EIx ; I = EIx),
69 I >= 0.
70
72item_eval(X,X) :- var(X), !. 73item_eval(N,N) :- number(N), !. 74item_eval(X,R) :-
75 catch(arithmetic_expression_value(X,R), _, R=X). 76
80':'(B,E,B:E).
81
85'[|]'(X,Xs,[X|Xs]). 86
90new(list,Size,L) :- integer(Size), Size >= 0, (nonvar(L) -> is_list(L) ; true), !,
91 length(L,Size).
92
93new(list,Xs,Xs) :- is_list(Xs).
94
98[](L, L) :- is_list(L).
99[]([I1,I2|IN],T,X) :- !, 100 T1 is T[I1], 101 X is T1[I2|IN].
102[]([B:E],L,X) :- is_list(L),
103 length(L,Len),
104 slice_parameters(B:E,Len,SB,SL), !,
105 sub_list(L,SB,SL,_,X).
106[]([Ix], L, R) :- is_list(L),
107 length(L,Len),
108 index_parameters(Ix,Len,I),
109 110 (I =< 28 -> skip_N(I,L,[X|_]) ; (T=..[$|L], arg(I,T,X))),
111 item_eval(X,R). 112
114sub_list(L,Before,Length,After,SubL) :- integer(Before), integer(Length), is_list(L),
115 skip_N(Before,L,L1), 116 next_N(Length,L1,SubL,L2), 117 length(L2,After), 118 !. 119
120skip_N(0,In,In):- !.
121skip_N(1,[_|In],In):- !.
122skip_N(N,[_,_|Xs],Out) :- 123 N1 is N-2,
124 skip_N(N1,Xs,Out).
125
126next_N(0,In,[],In) :- !.
127next_N(1,[X|In],[X],In) :- !.
128next_N(N,[X1,X2|In],[X1,X2|Out],Rem) :- 129 N1 is N-2,
130 next_N(N1,In,Out,Rem).
131
135:- redefine_system_predicate(length(_,_)). 136
137length(L,N) :- is_list(L),
138 system:length(L,N).
139
140:- arithmetic_function(length/1). 141
145init(L, Value, L) :- is_list(L),
146 fill_each(L,Value).
147
148fill_each([],_).
149fill_each([X|Xs],Value) :-
150 (is_list(X)
151 -> fill_each(X,Value)
152 ; (var(X) -> X=Value ; true)
153 ),
154 fill_each(Xs,Value).
155
159\\(L1, L2, R) :- nonvar(L1), is_list(L2), 160 append_det(L1,L2,R).
161
162append_det([], L, L) :- !. 163append_det([H|T], L, [H|R]) :-
164 append_det(T, L, R).
165
169flatten(List,FList) :- is_list(List),
170 lists:flatten(List,FList).
171
172:- arithmetic_function(flatten/1). 173
177arange(list,N,L) :- number(N), N>0,
178 E is N-1,
179 arange_(0,E,1,L).
180
181arange(list,B,E,L) :- number(B), number(E),
182 B>=0, E>B,
183 arange_(B,E,1,L).
184
185arange(list,B,E,S,L) :- number(B), number(E), number(S),
186 B>=0, E>B, S>0,
187 arange_(B,E,S,L).
188
189arange_(B,E,_S,[]) :- B>E, !.
190arange_(B,E,S,[B|Vs]) :-
191 B1 is B+S,
192 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:
:- arithmetic_function(new/2). % create :- arithmetic_function('[|]'/2). % evaluate list items :- arithmetic_function([]/1). % block index :- arithmetic_function([]/2). :- arithmetic_function(: /2). % slice (used with block indexing) :- arithmetic_function(length/1). % size or length :- arithmetic_function(init/2). % fill any vars :- arithmetic_function(\\ /2). % list concat :- arithmetic_function(flatten/1). % flattened list :- arithmetic_function(arange/2). % list from range(N) :- arithmetic_function(arange/3). % list from range(B,E) :- arithmetic_function(arange/4). % list from range(B,E,S)See the ReadMe for this pack for more documentation and examples. */