1 | // $Id: List2.rf 4029 2008-11-10 14:15:41Z yura $ |
---|
2 | |
---|
3 | $module "refal.plus.List2"; |
---|
4 | |
---|
5 | $use Apply Access Arithm Box Compare Table; |
---|
6 | |
---|
7 | $func SimplifyFunction t.func e.arg = s.func e.arg; |
---|
8 | SimplifyFunction t.func e.arg = |
---|
9 | t.func e.arg $iter { |
---|
10 | t.func : (t.func1 e.arg1) = t.func1 e.arg1 e.arg; |
---|
11 | } :: t.func e.arg, t.func : s.funcRef = |
---|
12 | s.funcRef e.arg; |
---|
13 | |
---|
14 | $public $func TryFunc t.func e.res = e.res; |
---|
15 | TryFunc t.func e.res = { <Apply t.func>; e.res; }; |
---|
16 | |
---|
17 | $public $func? Apply t.func e.arg = e.res; |
---|
18 | Apply t.func e.arg = <Apply.Apply <SimplifyFunction t.func e.arg>>; |
---|
19 | |
---|
20 | $public $func PApply t.func e.arg = t.func; |
---|
21 | PApply t.func e.arg = <SimplifyFunction t.func e.arg> :: s.func e.arg, |
---|
22 | { |
---|
23 | e.arg : /* empty */ = s.func; |
---|
24 | = (s.func e.arg); |
---|
25 | }; |
---|
26 | |
---|
27 | $public $func Ints s.start s.end = e.list; |
---|
28 | Ints s.start s.end = |
---|
29 | { |
---|
30 | <Le (s.start) (s.end)> = |
---|
31 | s.start $iter e.list s.start <Add s.start 1> :: e.list s.start, |
---|
32 | s.start : s.end = |
---|
33 | e.list; |
---|
34 | = s.start $iter e.list s.start <Sub s.start 1> :: e.list s.start, |
---|
35 | s.start : s.end = |
---|
36 | e.list; |
---|
37 | }; |
---|
38 | |
---|
39 | $public $func MapWithContext t.func e.list = e.list; |
---|
40 | MapWithContext t.func e.list = |
---|
41 | <Box> :: s.box, |
---|
42 | { |
---|
43 | e.list : e.left t.term e.right, |
---|
44 | <Put s.box <Apply t.func (e.left) t.term (e.right)>>, |
---|
45 | $fail; |
---|
46 | <Get s.box>; |
---|
47 | }; |
---|
48 | |
---|
49 | $public $func? Head e.list = t.elem; |
---|
50 | Head t.elem e.tail = t.elem; |
---|
51 | |
---|
52 | $public $func? Tail e.list = e.list; |
---|
53 | Tail t.elem e.tail = e.tail; |
---|
54 | |
---|
55 | $public $func? Init e.list = e.list; |
---|
56 | Init e.init t.last = e.init; |
---|
57 | |
---|
58 | $public $func? Last e.list = t.elem; |
---|
59 | Last e.init t.last = t.last; |
---|
60 | |
---|
61 | $public $func SwapR e.list = e.list; |
---|
62 | SwapR { |
---|
63 | e.init t.last = t.last e.init; |
---|
64 | e.list = e.list; |
---|
65 | }; |
---|
66 | |
---|
67 | $public $func SwapL e.list = e.list; |
---|
68 | SwapL { |
---|
69 | t.head e.tail = e.tail t.head; |
---|
70 | e.list = e.list; |
---|
71 | }; |
---|
72 | |
---|
73 | $public $func? Map t.func e.list = e.list; |
---|
74 | Map t.func e.list = |
---|
75 | () e.list $iter { |
---|
76 | e.list : t.head e.tail = (e.new_list <Apply t.func t.head>) e.tail; |
---|
77 | } :: (e.new_list) e.list, e.list : /*empty*/ = |
---|
78 | e.new_list; |
---|
79 | |
---|
80 | $func? MapInHelp t.func t.term = t.term; |
---|
81 | MapInHelp t.func (e.expr) = (<Apply t.func e.expr>); |
---|
82 | |
---|
83 | $public $func? MapIn t.func e.list = e.list; |
---|
84 | MapIn t.func e.list = <Map (&MapInHelp t.func) e.list>; |
---|
85 | |
---|
86 | $func? ConcatMapInHelp t.func t.term = e.list; |
---|
87 | ConcatMapInHelp t.func (e.expr) = <Apply t.func e.expr>; |
---|
88 | |
---|
89 | $public $func? ConcatMapIn t.func e.list = e.list; |
---|
90 | ConcatMapIn t.func e.list = <Map (&ConcatMapInHelp t.func) e.list>; |
---|
91 | |
---|
92 | $func FilterHelp t.func t.term = e.term_or_empty; |
---|
93 | FilterHelp t.func t.term = { <Apply t.func t.term> :: e = t.term; ; }; |
---|
94 | |
---|
95 | $public $func Filter t.func e.list = e.list; |
---|
96 | Filter t.func e.list = <Map (&FilterHelp t.func) e.list>; |
---|
97 | |
---|
98 | $func? FilterInHelp t.func t.term = e.term_or_empty; |
---|
99 | FilterInHelp t.func t.term = t.term : (e.expr), { <Apply t.func e.expr> :: e = t.term; ; }; |
---|
100 | |
---|
101 | $public $func FilterIn t.func e.list = e.list; |
---|
102 | FilterIn t.func e.list = <Map (&FilterInHelp t.func) e.list>; |
---|
103 | |
---|
104 | $func FilterWithContextHelp t.func (e.left) t.term (e.right) = e.term_or_empty; |
---|
105 | FilterWithContextHelp t.func (e.left) t.term (e.right) = { <Apply t.func (e.left) t.term (e.right)> :: e = t.term; ; }; |
---|
106 | |
---|
107 | $public $func FilterWithContext t.func e.list = e.list; |
---|
108 | FilterWithContext t.func e.list = <MapWithContext (&FilterWithContextHelp t.func) e.list>; |
---|
109 | |
---|
110 | $public $func Split t.func e.list = (e.true_list) (e.false_list); |
---|
111 | Split t.func e.list = |
---|
112 | () () e.list $iter { |
---|
113 | e.list : t.head e.tail, { |
---|
114 | <Apply t.func t.head> :: e = (e.true_list t.head) (e.false_list) e.tail; |
---|
115 | = (e.true_list) (e.false_list t.head) e.tail; |
---|
116 | }; |
---|
117 | } :: (e.true_list) (e.false_list) e.list, e.list : /*empty*/ = |
---|
118 | (e.true_list) (e.false_list); |
---|
119 | |
---|
120 | |
---|
121 | $public $func Paren e.expr = t.expr_with_paren; |
---|
122 | Paren e.expr = (e.expr); |
---|
123 | |
---|
124 | $public $func Zip (e.list1) (e.list2) = e.list; |
---|
125 | Zip (e.list1) (e.list2) = <ZipWith &Paren (e.list1) (e.list2)>; |
---|
126 | |
---|
127 | $public $func? ZipWith t.func (e.list1) (e.list2) = e.list; |
---|
128 | ZipWith t.func (e.list1) (e.list2) = |
---|
129 | /*empty*/ (e.list1) (e.list2) $iter { |
---|
130 | e.list1 : t.first1 e.rest1, |
---|
131 | e.list2 : t.first2 e.rest2 = |
---|
132 | e.new_list <Apply t.func t.first1 t.first2> (e.rest1) (e.rest2); |
---|
133 | } :: e.new_list (e.list1) (e.list2), # \{ e.list1 : v, e.list2 : v; } = |
---|
134 | e.new_list; |
---|
135 | |
---|
136 | $public $func Transpose e.lists = e.lists; |
---|
137 | Transpose e.lists = <TransposeWith &Paren e.lists>; |
---|
138 | |
---|
139 | $func? TransposeWithHelp e.lists = (e.heads) e.tails; |
---|
140 | TransposeWithHelp e.lists = |
---|
141 | () () e.lists $iter { |
---|
142 | e.lists : (e.listsHead) e.listsTail = |
---|
143 | e.listsHead : t.head e.tail, |
---|
144 | (e.heads t.head) (e.tails (e.tail)) e.listsTail; |
---|
145 | } :: (e.heads) (e.tails) e.lists, e.lists : /* empty */ = |
---|
146 | (e.heads) e.tails; |
---|
147 | |
---|
148 | $public $func? TransposeWith t.func e.lists = e.list; |
---|
149 | TransposeWith t.func e.lists = |
---|
150 | (e.lists) $iter { |
---|
151 | <TransposeWithHelp e.lists> :: (e.heads) e.lists = |
---|
152 | e.out <Apply t.func e.heads> (e.lists); |
---|
153 | e.out (); |
---|
154 | } :: e.out (e.lists), e.lists : /* empty */ = |
---|
155 | e.out; |
---|
156 | |
---|
157 | $public $func Product (e.list1) (e.list2) = e.list; |
---|
158 | Product (e.list1) (e.list2) = <ProductWith &Paren (e.list1) (e.list2)>; |
---|
159 | |
---|
160 | $public $func? ProductWith t.func (e.list1) (e.list2) = e.list; |
---|
161 | ProductWith t.func (e.list1) (e.list2) = |
---|
162 | <Box> :: s.box, { |
---|
163 | e.list1 : e t.term1 e, |
---|
164 | e.list2 : e t.term2 e, |
---|
165 | <Put s.box <Apply t.func t.term1 t.term2>>, |
---|
166 | $fail; |
---|
167 | <Get s.box>; |
---|
168 | }; |
---|
169 | |
---|
170 | $public $func Products e.lists = e.lists; |
---|
171 | Products { |
---|
172 | /* empty */ = /* empty */; |
---|
173 | (e.list) = <Map &Paren e.list>; |
---|
174 | (e.list) e.lists = <Product (e.list) (<Products e.lists>)>; |
---|
175 | }; |
---|
176 | |
---|
177 | $func? DirectProductWithHelp s.box t.func (e.args) e.lists = ; |
---|
178 | DirectProductWithHelp s.box t.func (e.args) e.lists = e.lists : { |
---|
179 | /* empty */ = <Put s.box <Apply t.func e.args>>; |
---|
180 | (e.head) e.tail = |
---|
181 | { |
---|
182 | e.head : e t.term e, |
---|
183 | <DirectProductWithHelp s.box t.func (e.args t.term) e.tail>, |
---|
184 | $fail;; |
---|
185 | }; |
---|
186 | }; |
---|
187 | |
---|
188 | $public $func? DirectProductWith t.func e.lists = e.list; |
---|
189 | DirectProductWith t.func e.lists = { |
---|
190 | e.lists : /* empty */ = /* empty */; |
---|
191 | = <Box> :: s.box, <DirectProductWithHelp s.box t.func () e.lists>, <Get s.box>; |
---|
192 | }; |
---|
193 | |
---|
194 | $public $func? IsElem e.list t.item = ; |
---|
195 | IsElem e t.item e t.item; |
---|
196 | |
---|
197 | $public $func Foldl t.func (e.value) e.list = e.value; |
---|
198 | Foldl t.func (e.value) e.list = |
---|
199 | (e.value) e.list $iter { |
---|
200 | e.list : t.head e.tail = (<Apply t.func e.value t.head>) e.tail; |
---|
201 | } :: (e.value) e.list, e.list : /*empty*/ = |
---|
202 | e.value; |
---|
203 | |
---|
204 | $public $func Foldl1 t.func v.list = e.value; |
---|
205 | Foldl1 t.func t.head e.tail = <Foldr t.func (t.head) e.tail>; |
---|
206 | |
---|
207 | $public $func Foldr t.func (e.value) e.list = e.value; |
---|
208 | Foldr t.func (e.value) e.list = |
---|
209 | (e.value) e.list $iter { |
---|
210 | e.list : e.init t.last = (<Apply t.func t.last e.value>) e.init; |
---|
211 | } :: (e.value) e.list, e.list : /*empty*/ = |
---|
212 | e.value; |
---|
213 | |
---|
214 | $public $func Foldr1 t.func v.list = e.value; |
---|
215 | Foldr1 t.func e.init t.last = <Foldr t.func (t.last) e.init>; |
---|
216 | |
---|
217 | $public $func? All t.func e.list = ; |
---|
218 | All t.func e.list = |
---|
219 | e.list $iter { |
---|
220 | e.list : t.head e.tail = <Apply t.func t.head> :: e, e.tail; |
---|
221 | } :: e.list, e.list : /*empty*/; |
---|
222 | |
---|
223 | $public $func? Any t.func e.list = ; |
---|
224 | Any t.func e.list = # \{ |
---|
225 | e.list $iter { |
---|
226 | e.list : t.head e.tail = # \{ <Apply t.func t.head > :: e; }, e.tail; |
---|
227 | } :: e.list, e.list : /*empty*/; |
---|
228 | }; |
---|
229 | |
---|
230 | $public $func Subtract (e.list1) (e.list2) = e.list; |
---|
231 | Subtract (e.list1) (e.list2) = |
---|
232 | /*empty*/ (e.list1) $iter { |
---|
233 | e.list1 : term e.rest, |
---|
234 | { |
---|
235 | e.list2 : e term e = e.not (e.rest); |
---|
236 | = e.not term (e.rest); |
---|
237 | }; |
---|
238 | } :: e.not (e.list1), e.list1 : /*empty*/ = |
---|
239 | e.not; |
---|
240 | |
---|
241 | //$const Concat = (&Map &Deparen_Term); |
---|
242 | // |
---|
243 | //<Const e.list> ~~~ <Apply &Concat e.list>; |
---|
244 | |
---|
245 | //Paren expr = <Map &Paren_Term (expr)>; |
---|
246 | // |
---|
247 | //Reverse { |
---|
248 | // term e.list = <Reverse e.list> term; |
---|
249 | // /*empty*/ = /*empty*/; |
---|
250 | //}; |
---|
251 | |
---|
252 | $public $func Intersperse (e.sep) e.list = e.list; |
---|
253 | Intersperse { |
---|
254 | (e.sep) /*empty*/ = /*empty*/; |
---|
255 | (e.sep) t.head0 = t.head0; |
---|
256 | (e.sep) t.head0 e.tail0 = |
---|
257 | (t.head0 e.sep) e.tail0 $iter { |
---|
258 | e.list : t.head e.tail = (e.new_list t.head e.sep) e.tail; |
---|
259 | } :: (e.new_list) e.list, e.list : t.last = |
---|
260 | e.new_list t.last; |
---|
261 | }; |
---|
262 | |
---|
263 | $public $func Separate (e.sep) e.list = e.listOfLists; |
---|
264 | Separate (e.sep) e.list = |
---|
265 | () e.list $iter { |
---|
266 | e.list : e.before e.sep e.after = (e.ll (e.before)) e.after; |
---|
267 | = (e.ll (e.list)); |
---|
268 | } :: (e.ll) e.list, e.list : /*empty*/ = |
---|
269 | e.ll; |
---|
270 | |
---|
271 | $func ConcatHelp t.term = e.expr; |
---|
272 | ConcatHelp { |
---|
273 | (e.expr) = e.expr; |
---|
274 | t.term = t.term; |
---|
275 | }; |
---|
276 | |
---|
277 | $public $func Id e.expr = e.expr; |
---|
278 | Id e.expr = e.expr; |
---|
279 | |
---|
280 | $public $func Concat e.lists = e.list; |
---|
281 | Concat e.lists = <Map &ConcatHelp e.lists>; |
---|
282 | |
---|
283 | $public $func? EqTerms t.term t.term = ; |
---|
284 | EqTerms t1 t1; |
---|
285 | |
---|
286 | $public $func Nub e.list = e.list; |
---|
287 | Nub e.list = <NubBy &EqTerms e.list>; |
---|
288 | |
---|
289 | $public $func NubBy t.eqTerms e.list = e.list; |
---|
290 | NubBy t.eqTerms e.list = |
---|
291 | () e.list $iter { |
---|
292 | e.list : t.head e.tail, { |
---|
293 | <Any (t.eqTerms t.head) e.new_list> = (e.new_list) e.tail; |
---|
294 | = (e.new_list t.head) e.tail; |
---|
295 | }; |
---|
296 | } :: (e.new_list) e.list, e.list : /*empty*/ = |
---|
297 | e.new_list; |
---|
298 | |
---|
299 | $func FrequenciesHelp (e.expr) (s.num) = s.num e.expr; |
---|
300 | FrequenciesHelp (e.expr) (s.num) = s.num e.expr; |
---|
301 | |
---|
302 | $public $func Frequencies e.list = e.list; |
---|
303 | Frequencies e.list = |
---|
304 | <Table> :: s.table, |
---|
305 | { |
---|
306 | e.list : e t.term e, |
---|
307 | { <Lookup s.table t.term>; 0; } : s.num, |
---|
308 | <Bind s.table (t.term) (<Add s.num 1>)>, |
---|
309 | $fail; |
---|
310 | <Sort <MapIn &FrequenciesHelp <Entries s.table>>>; |
---|
311 | }; |
---|
312 | |
---|
313 | $public $func SumNumbers e.list = e.list; |
---|
314 | SumNumbers e.list = |
---|
315 | <Table> :: s.table, |
---|
316 | { |
---|
317 | e.list : e (s.n e.expr) e, |
---|
318 | { <Lookup s.table e.expr>; 0; } : s.num, |
---|
319 | <Bind s.table (e.expr) (<Add s.num s.n>)>, |
---|
320 | $fail; |
---|
321 | <Sort <MapIn &FrequenciesHelp <Entries s.table>>>; |
---|
322 | }; |
---|
323 | |
---|
324 | //Replicate s.n e.expr = |
---|
325 | // s.n /*e.list*/ $iter |
---|
326 | // <Arithm.Sub s.n 1> e.list e.expr |
---|
327 | // :: s.n e.list, |
---|
328 | // <Le (s.n) (0)> = |
---|
329 | // e.list; |
---|
330 | |
---|
331 | $public $func CompareTerms t.term t.term = s.cmp; |
---|
332 | CompareTerms t.term1 t.term2 = <Compare (t.term1) (t.term2)>; |
---|
333 | |
---|
334 | $func QSort_Split t.cmpTerm e.list = (e.smaller) (e.equal) (e.greater); |
---|
335 | QSort_Split t.cmpTerm e.list, |
---|
336 | () () () e.list $iter { |
---|
337 | e.list : t.head e.tail, |
---|
338 | <Apply t.cmpTerm t.head> : { |
---|
339 | '<' = (e.smaller) (e.equal) (e.greater t.head) e.tail; |
---|
340 | '=' = (e.smaller) (e.equal t.head) (e.greater) e.tail; |
---|
341 | '>' = (e.smaller t.head) (e.equal) (e.greater) e.tail; |
---|
342 | }; |
---|
343 | } :: (e.smaller) (e.equal) (e.greater) e.list, e.list : /*empty*/ = |
---|
344 | (e.smaller) (e.equal) (e.greater); |
---|
345 | |
---|
346 | $public $func QSortBy t.cmpTerms e.list = e.list; |
---|
347 | QSortBy t.cmpTerms e.list = e.list : { |
---|
348 | /* empty */ = /* empty */; |
---|
349 | t.head e.tail = <QSort_Split (t.cmpTerms t.head) e.tail> :: (e.smaller) (e.equal) (e.greater), |
---|
350 | <QSort e.smaller> t.head e.equal <QSort e.greater>; |
---|
351 | }; |
---|
352 | |
---|
353 | $public $func QSort e.list = e.list; |
---|
354 | QSort e.list = <QSortBy &CompareTerms e.list>; |
---|
355 | |
---|
356 | $public $func QSortAndNubBy t.cmpTerms e.list = e.list; |
---|
357 | QSortAndNubBy t.cmpTerms e.list = e.list : { |
---|
358 | /* empty */ = /* empty */; |
---|
359 | t.head e.tail = <QSort_Split (t.cmpTerms t.head) e.tail> :: (e.smaller) t (e.greater), |
---|
360 | <QSortAndNubBy t.cmpTerms e.smaller> t.head <QSortAndNubBy t.cmpTerms e.greater>; |
---|
361 | }; |
---|
362 | |
---|
363 | $public $func QSortAndNub e.list = e.list; |
---|
364 | QSortAndNub e.list = <QSortAndNubBy &CompareTerms e.list>; |
---|
365 | |
---|
366 | $public $func Sort e.list = e.list; |
---|
367 | Sort e.list = <SortBy &CompareTerms e.list>; |
---|
368 | |
---|
369 | $public $func SortBy t.cmpTerms e.list = e.list; |
---|
370 | SortBy t.cmpTerms e.list = |
---|
371 | <Div <Length e.list> 2> : { |
---|
372 | 0 = e.list; |
---|
373 | s.k = <Merge t.cmpTerms (<SortBy t.cmpTerms <Left 0 s.k e.list>>) (<SortBy t.cmpTerms <Middle s.k 0 e.list>>)>; |
---|
374 | }; |
---|
375 | |
---|
376 | $func Merge t.cmpTerms (e.left) (e.right) = e.merged_list; |
---|
377 | Merge t.cmpTerms (e.left) (e.right) = |
---|
378 | (e.left) (e.right) $iter { |
---|
379 | e.left : t.l e.left_rest, e.right : t.r e.right_rest = { |
---|
380 | <Apply t.cmpTerms t.l t.r> : '<' = e.merged t.l (e.left_rest) (e.right); |
---|
381 | = e.merged t.r (e.left) (e.right_rest); |
---|
382 | }; |
---|
383 | } :: e.merged (e.left) (e.right), |
---|
384 | \{ |
---|
385 | e.left : /*empty*/ = e.merged e.right; |
---|
386 | e.right : /*empty*/ = e.merged e.left; |
---|
387 | }; |
---|
388 | |
---|
389 | $public $func SortAndNub e.list = e.list; |
---|
390 | SortAndNub e.list = <SortBy &CompareTerms e.list>; |
---|
391 | |
---|
392 | $public $func SortAndNubBy t.cmpTerms e.list = e.list; |
---|
393 | SortAndNubBy t.cmpTerms e.list = |
---|
394 | <Div <Length e.list> 2> : { |
---|
395 | 0 = e.list; |
---|
396 | s.k = <MergeAndNub t.cmpTerms (<SortAndNubBy t.cmpTerms <Left 0 s.k e.list>>) (<SortAndNubBy t.cmpTerms <Middle s.k 0 e.list>>)>; |
---|
397 | }; |
---|
398 | |
---|
399 | $func MergeAndNub t.cmpTerms (e.left) (e.right) = e.merged_list; |
---|
400 | MergeAndNub t.cmpTerms (e.left) (e.right) = |
---|
401 | (e.left) (e.right) $iter { |
---|
402 | e.left : t.l e.left_rest, e.right : t.r e.right_rest = <Apply t.cmpTerms t.l t.r> : { |
---|
403 | '<' = e.merged t.l (e.left_rest) (e.right); |
---|
404 | '>' = e.merged t.r (e.left) (e.right_rest); |
---|
405 | '=' = e.merged (e.left) (e.right_rest); |
---|
406 | }; |
---|
407 | } :: e.merged (e.left) (e.right), |
---|
408 | \{ |
---|
409 | e.left : /*empty*/ = e.merged e.right; |
---|
410 | e.right : /*empty*/ = e.merged e.left; |
---|
411 | }; |
---|