Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 89.7% 700 / 0 / 780
Functions: -% 0 / 1 / 1
Branches: 74.5% 968 / 0 / 1300

OMCompiler/Compiler/Util/List.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package List
37 " file: List.mo
38 package: List
39 description: List functions
40
41
42 This package contains all functions that operate on the List type, such as
43 mapping and filtering functions.
44
45 Most of the functions in this package follows a naming convention that looks
46 like (? means zero or one, + means one or more, * means zero or more):
47
48 (operation(n)?(_m)?(prefix)*)+
49
50 operation: The operation that the function does, i.e. mapping, folding, etc.
51 n: The number of extra arguments that the function takes.
52 m: The number of lists created.
53 prefix: One of the following prefixes:
54 AllValue: Checks that all elements of the list matches a given value.
55 Bool: Returns true or false, instead of succeeding or failing.
56 Elt: Takes a single element instead of a list.
57 F: Will fail instead of returning the input list when
58 appropriate.
59 Flat: An operator function that would normally return an
60 element, such as in map, will return a list instead. The
61 returned lists are flattened into a single list.
62 IntN: A special version for integers between 1 and N.
63 Last: Operates on the tail of the list.
64 List: Operates on a list of lists.
65 N: Returns a list of N elements.
66 OnBool: Decides which operation to do based on a given boolean value.
67 OnSuccess: Takes an operation function that succeeds or fails.
68 OnTrue: Takes an operation function that returns true or false.
69 Option: Operates on options.
70 r: Takes an operation function with the arguments reversed.
71 Reverse: Returns the processed list in reverse order.
72 Sorted: Expects the given list(s) to be sorted.
73 Tuple: Operates on tuples, either by expecting tuple types as
74 input or by returning tuples instead of multiple lists.
75
76 All operator functions has the same parameter order as the types defined
77 below, i.e. ValueType before ElementType, and so on. Some types are
78 bidirectional, in which case they appear commented out in the outputs list
79 below just to show the order. The r prefix changes this order by either moving
80 FoldType to the top if FoldType is used, otherwise moving the ElementType to the
81 bottom.
82
83 The n and m numbers define the number of extra arguments or lists created, and
84 is only used when they deviate from the expected values. I.e. map should be
85 called map_1 according to the convention, since it creates one list. But this
86 is the expected number of lists, so the _1 is omitted.
87
88 An example of this convention:
89
90 fold2 is a fold function, and as such it takes at least a list, a fold
91 function and a fold argument, and returns the updated fold argument. The 2
92 after it's name means that it also takes two extra arguments. Following the
93 ordering of the types below we get that the order of it's signature is:
94
95 (elementlist, fold function, extra arg 1, extra arg 2, fold arg) -> fold arg
96
97 and the signature of the fold function that it takes is:
98
99 (element, extra arg 1, extra arg 2, fold arg) -> fold arg
100 "
101
102 public
103 // these styles can be used with List.toString() to get predefined behaviour. Use List.toStringCustom for full control.
104 type Style = enumeration(NONE, FLAT, FLAT_BRACKETS, FLAT_CURLY, FLAT_CURLY_SHORT, NEWLINE, NEWLINE_INDENT, NEWLINE_TAB);
105
106 protected
107 import Array;
108 import DoubleEnded;
109 import GCExt;
110 import MetaModelica.Dangerous.{listReverseInPlace, arrayGetNoBoundsChecking, arrayUpdateNoBoundsChecking, arrayCreateNoInit};
111 import MetaModelica.Dangerous;
112
113 public function create<T>
114 "Creates a list from an element."
115 input T inElement;
116 output list<T> outList = {inElement};
117 end create;
118
119 public function fill<T>
120 "Returns a list of n element.
121 Example: fill(2, 3) => {2, 2, 2}"
122 input T inElement;
123 input Integer inCount;
124 output list<T> outList = {};
125 protected
126 Integer i = 0;
127 algorithm
128
2/2
✓ Branch 0 taken 733530 times.
✓ Branch 1 taken 6147434 times.
6880964 while i < inCount loop
129 outList := inElement :: outList;
130 733530 i := i + 1;
131 end while;
132 end fill;
133
134 public function repeat<T>
135 "Returns a list of n replications of input lst.
136 Example: fill({2, 1}, 3) => {2, 1, 2, 1, 2, 1}"
137 input list<T> inElement;
138 input Integer inCount;
139 output list<T> outList = {};
140 protected
141 Integer i = 0;
142 algorithm
143 ✗ while i < inCount loop
144 ✗ outList := listAppend(inElement, outList);
145 ✗ i := i + 1;
146 end while;
147 end repeat;
148
149 public function intRange
150 "Returns a list of n integers from 1 to inStop.
151 Example: listIntRange(3) => {1,2,3}"
152 input Integer inStop;
153 output list<Integer> outRange = {};
154 protected
155 Integer i = inStop;
156 algorithm
157
2/2
✓ Branch 0 taken 766658 times.
✓ Branch 1 taken 105060 times.
871718 while i > 0 loop
158 outRange := i :: outRange;
159 766658 i := i - 1;
160 end while;
161 end intRange;
162
163 public function intRange2
164 "Returns a list of integers from inStart to inStop.
165 Example listIntRange2(3,5) => {3,4,5}"
166 input Integer inStart;
167 input Integer inStop;
168 output list<Integer> outRange = {};
169 protected
170 Integer i = inStop;
171 algorithm
172
2/2
✓ Branch 0 taken 1407263 times.
✓ Branch 1 taken 17068 times.
1424331 if inStart < inStop then
173
2/2
✓ Branch 0 taken 156978 times.
✓ Branch 1 taken 17068 times.
174046 while i >= inStart loop
174 outRange := i :: outRange;
175 156978 i := i - 1;
176 end while;
177 else
178
2/2
✓ Branch 0 taken 1407281 times.
✓ Branch 1 taken 1407263 times.
2814544 while i <= inStart loop
179 outRange := i :: outRange;
180 1407281 i := i + 1;
181 end while;
182 end if;
183 end intRange2;
184
185 public function intRange3
186 "Returns a list of integers from inStart to inStop with step inStep.
187 Example: listIntRange2(3,2,9) => {3,5,7,9}"
188 input Integer inStart;
189 input Integer inStep;
190 input Integer inStop;
191 output list<Integer> outRange;
192 algorithm
193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45239 times.
45239 if inStep == 0 then fail(); end if;
194
4/4
✓ Branch 0 taken 184812 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 139617 times.
✓ Branch 3 taken 45239 times.
184856 outRange := list(i for i in inStart:inStep:inStop);
195 end intRange3;
196
197 public function fromOption<T>
198 "Returns an empty list for NONE() and a list containing the element for
199 SOME(element)."
200 input Option<T> inElement;
201 output list<T> outList;
202 algorithm
203 outList := match inElement
204 local
205 T e;
206
207 case SOME(e) then {e};
208 else {};
209 end match;
210 end fromOption;
211
212 public function isEqual<T>
213 "Checks if two lists are equal. If inEqualLength is true the lists are assumed
214 to be of equal length, and if it is false they can be of different lengths (in
215 which case only the overlapping parts of the lists are checked)."
216 input list<T> inList1;
217 input list<T> inList2;
218 input Boolean inEqualLength;
219 output Boolean outIsEqual;
220 protected
221 list<T> rest1 = inList1, rest2 = inList2;
222 T e1, e2;
223 algorithm
224
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
20 while not (listEmpty(rest1) or listEmpty(rest2)) loop
225 16 e1 :: rest1 := rest1;
226 16 e2 :: rest2 := rest2;
227
228
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 if not valueEq(e1, e2) then
229 outIsEqual := false;
230 ✗ return;
231 end if;
232 end while;
233
234
2/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 outIsEqual := if listEmpty(rest1) and listEmpty(rest2) then true else not inEqualLength;
235 end isEqual;
236
237 public function isEqualOnTrue<T1, T2>
238 "Takes two lists and an equality function, and returns whether the lists are
239 equal or not."
240 input list<T1> inList1;
241 input list<T2> inList2;
242 input CompFunc inCompFunc;
243 output Boolean outIsEqual;
244
245 partial function CompFunc
246 input T1 inElement1;
247 input T2 inElement2;
248 output Boolean outIsEqual;
249 end CompFunc;
250 protected
251 list<T1> rest1 = inList1;
252 list<T2> rest2 = inList2;
253 T1 e1;
254 T2 e2;
255 algorithm
256
4/4
✓ Branch 0 taken 380342 times.
✓ Branch 1 taken 741113 times.
✓ Branch 2 taken 380307 times.
✓ Branch 3 taken 35 times.
1121455 while not (listEmpty(rest1) or listEmpty(rest2)) loop
257 380307 e1 :: rest1 := rest1;
258 380307 e2 :: rest2 := rest2;
259
260
4/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 380306 times.
✓ Branch 4 taken 367248 times.
✓ Branch 5 taken 13059 times.
380307 if not inCompFunc(e1, e2) then
261 outIsEqual := false;
262 13059 return;
263 end if;
264 end while;
265
266
4/4
✓ Branch 0 taken 741113 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 741096 times.
741148 outIsEqual := listEmpty(rest1) and listEmpty(rest2);
267 end isEqualOnTrue;
268
269 public function allEqual<T>
270 "Takes a list and an equality function, and returns whether all elements in the list are equal."
271 input list<T> inList;
272 input CompFunc inCompFunc;
273 output Boolean outAllEqual = true;
274
275 partial function CompFunc
276 "Returns true if e1 = e2, otherwise false."
277 input T e1;
278 input T e2;
279 output Boolean res;
280 end CompFunc;
281
282 protected
283 T e1;
284 list<T> rest;
285 algorithm
286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
81 if not listEmpty(inList) then
287 81 e1 :: rest := inList;
288
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 80 times.
126 for e in rest loop
289
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 45 times.
46 if not inCompFunc(e1, e) then
290 outAllEqual := false;
291 1 return;
292 end if;
293 end for;
294 end if;
295 end allEqual;
296
297 public function compareLength<T1, T2>
298 "Returns -1 if list1 is shorter than list2 or 1 if list1 is longer than list2.
299 If both lists are of equal length it returns 0."
300 input list<T1> list1;
301 input list<T2> list2;
302 output Integer res;
303 protected
304 list<T1> rest1 = list1;
305 list<T2> rest2 = list2;
306 algorithm
307
4/4
✓ Branch 0 taken 51550 times.
✓ Branch 1 taken 29366 times.
✓ Branch 2 taken 50865 times.
✓ Branch 3 taken 685 times.
80916 while not (listEmpty(rest1) or listEmpty(rest2)) loop
308 50865 rest1 := listRest(rest1);
309 50865 rest2 := listRest(rest2);
310 end while;
311
312
4/4
✓ Branch 0 taken 29366 times.
✓ Branch 1 taken 685 times.
✓ Branch 2 taken 506 times.
✓ Branch 3 taken 28860 times.
30051 res := if listEmpty(rest1) then (if listEmpty(rest2) then 0 else -1) else 1;
313 end compareLength;
314
315 public function compare<T1, T2>
316 "Returns -1 if list1 is shorter than list2 or 1 if list1 is longer than list2.
317 If both lists are of equal length it applies the given compare function to
318 each pair of list elements and returns the first nonzero value, or 0 if no
319 nonzero value is received."
320 input list<T1> list1;
321 input list<T2> list2;
322 input CompFunc compareFn;
323 output Integer res;
324
325 partial function CompFunc
326 input T1 e1;
327 input T2 e2;
328 output Integer res;
329 end CompFunc;
330 protected
331 T2 e2;
332 list<T2> rest_e2;
333 algorithm
334 17712 res := compareLength(list1, list2);
335
2/2
✓ Branch 0 taken 17700 times.
✓ Branch 1 taken 12 times.
17712 if res <> 0 then
336 12 return;
337 end if;
338
339 rest_e2 := list2;
340
2/2
✓ Branch 0 taken 18723 times.
✓ Branch 1 taken 17230 times.
35953 for e1 in list1 loop
341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18723 times.
18723 e2 :: rest_e2 := rest_e2;
342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18723 times.
18723 res := compareFn(e1, e2);
343
344
2/2
✓ Branch 0 taken 470 times.
✓ Branch 1 taken 18253 times.
18723 if res <> 0 then
345 470 return;
346 end if;
347 end for;
348 end compare;
349
350 public function isPrefixOnTrue<T1, T2>
351 "Checks if the first list is a prefix of the second list, i.e. that all
352 elements in the first list is equal to the corresponding elements in the
353 second list."
354 input list<T1> inList1;
355 input list<T2> inList2;
356 input CompFunc inCompFunc;
357 output Boolean outIsPrefix;
358
359 partial function CompFunc
360 input T1 inElement1;
361 input T2 inElement2;
362 output Boolean outIsEqual;
363 end CompFunc;
364 protected
365 list<T1> rest1 = inList1;
366 list<T2> rest2 = inList2;
367 T1 e1;
368 T2 e2;
369 algorithm
370 ✗ while not listEmpty(rest1) loop
371 ✗ if listEmpty(rest2) then
372 outIsPrefix := false;
373 ✗ return;
374 end if;
375
376 ✗ e1 :: rest1 := rest1;
377 ✗ e2 :: rest2 := rest2;
378
379 ✗ if not inCompFunc(e1, e2) then
380 outIsPrefix := false;
381 ✗ return;
382 end if;
383 end while;
384
385 outIsPrefix := true;
386 end isPrefixOnTrue;
387
388 public function consr<T>
389 "The same as the builtin cons operator, but with the order of the arguments
390 swapped."
391 input list<T> inList;
392 input T inElement;
393 output list<T> outList;
394 algorithm
395 outList := inElement :: inList;
396 end consr;
397
398 public function consOnTrue<T>
399 "Adds the element to the front of the list if the condition is true."
400 input Boolean inCondition;
401 input T inElement;
402 input list<T> inList;
403 output list<T> outList;
404 algorithm
405
2/2
✓ Branch 0 taken 3027982 times.
✓ Branch 1 taken 2152566 times.
5180548 outList := if inCondition then inElement :: inList else inList;
406 end consOnTrue;
407
408 public function consOption<T>
409 "Adds an optional element to the front of the list, or returns the list if the
410 element is none."
411 input Option<T> inElement;
412 input list<T> inList;
413 output list<T> outList;
414 algorithm
415 outList := match inElement
416 local
417 T e;
418
419 case SOME(e) then e :: inList;
420 else inList;
421 end match;
422 end consOption;
423
424 public function consN<T>
425 "concate n time inElement to the list:
426 n = 5, inElement=1, list={1,2} -> list={1,1,1,1,1,1,2}"
427 input Integer size;
428 input T inElement;
429 input output list<T> inList;
430 algorithm
431
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2549222 times.
5343005 for i in 1:size loop
432 inList := inElement :: inList;
433 end for;
434 end consN;
435
436 public function append_reverse<T>
437 "Appends the elements from list1 in reverse order to list2."
438 input list<T> inList1;
439 input list<T> inList2;
440 output list<T> outList=inList2;
441 algorithm
442 // Do not optimize the case listEmpty(inList2) and listLength(inList1)==1
443 // since we use listReverseInPlace together with this function.
444 // An alternative would be to keep both (and rename this append_reverse_always_copy)
445
2/2
✓ Branch 1 taken 98352182 times.
✓ Branch 2 taken 54856746 times.
153208928 for e in inList1 loop
446 outList := e::outList;
447 end for;
448 end append_reverse;
449
450 public function appendElt<T>
451 "Appends an element to the end of the list. Note that this is very
452 inefficient, so try to avoid using this function."
453 input T inElement;
454 input list<T> inList;
455 output list<T> outList;
456 algorithm
457 537271 outList := listAppend(inList, {inElement});
458 end appendElt;
459
460 public function appendLastList<T>
461 "Appends a list to the last list in a list of lists."
462 input list<list<T>> inListList;
463 input list<T> inList;
464 output list<list<T>> outListList;
465 algorithm
466 outListList := match inListList
467 local
468 list<T> l;
469 list<list<T>> ll;
470 list<list<T>> ol = {};
471
472 case {} then {inList};
473
474 case {l}
475 80116 then {listAppend(l, inList)};
476
477 case l :: ll
478 algorithm
479
2/2
✓ Branch 0 taken 356840 times.
✓ Branch 1 taken 183137 times.
539977 while not listEmpty(ll) loop
480 ol := l::ol;
481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 356840 times.
356840 l::ll := ll;
482 end while;
483 183137 ol := listAppend(l, inList) :: ol;
484 183137 ol := listReverseInPlace(ol);
485 then ol;
486
487 end match;
488 end appendLastList;
489
490 public function insert<T>
491 "Inserts an element at a position
492 example: insert({2,1,4,2},2,3) => {2,3,1,4,2} "
493 input list<T> inList;
494 input Integer inN;
495 input T inElement;
496 output list<T> outList;
497 protected
498 list<T> lst1, lst2;
499 algorithm
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
106 true := (inN > 0);
501 106 (lst1, lst2) := splitr(inList, inN-1);
502 106 outList := append_reverse(lst1,inElement::lst2);
503 end insert;
504
505 public function insertListSorted<T>
506 "Inserts an sorted list into another sorted list. O(n)
507 example: insertListSorted({1,2,4,5},{3,4,8},intGt) => {1,2,3,4,4,5,8}"
508 input list<T> inList;
509 input list<T> inList2;
510 input CompareFunc inCompFunc;
511 output list<T> outList;
512
513 partial function CompareFunc
514 input T inElement1;
515 input T inElement2;
516 output Boolean inRes;
517 end CompareFunc;
518 algorithm
519 1154 outList := listReverseInPlace(insertListSorted1(inList, inList2, inCompFunc, {}));
520 end insertListSorted;
521
522 protected function insertListSorted1<T>
523 "Iterate over the first given list and add it to the result list if the comparison function with the head of the second list returns true.
524 The result is a sorted list in reverse order."
525 input list<T> inList;
526 input list<T> inList2;
527 input CompareFunc inCompFunc;
528 input list<T> inResultList;
529 output list<T> outResultList;
530
531 partial function CompareFunc
532 input T inElement1;
533 input T inElement2;
534 output Boolean inRes;
535 end CompareFunc;
536 protected
537 list<T> listRest, listRest2, tmpResultList;
538 T listHead, listHead2;
539 algorithm
540 outResultList := match(inList, inList2)
541 case({}, {})
542 then inResultList;
543 case({}, _)
544 1154 then append_reverse(inList2, inResultList);
545 case(_, {})
546 ✗ then append_reverse(inList, inResultList);
547 case(listHead::listRest, listHead2::listRest2)
548 algorithm
549
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2620 times.
✓ Branch 4 taken 2019 times.
✓ Branch 5 taken 601 times.
2620 if(inCompFunc(listHead, listHead2)) then
550 tmpResultList := listHead::inResultList;
551 tmpResultList := insertListSorted1(listRest, inList2, inCompFunc, tmpResultList);
552 else
553 tmpResultList := listHead2::inResultList;
554 tmpResultList := insertListSorted1(inList, listRest2, inCompFunc, tmpResultList);
555 end if;
556 then tmpResultList;
557 end match;
558 end insertListSorted1;
559
560 public function set<T>
561 "set an element at a position
562 example: set({2,1,4,2},2,3) => {2,3,4,2} "
563 input list<T> inList;
564 input Integer inN;
565 input T inElement;
566 output list<T> outList;
567 protected
568 list<T> lst1, lst2;
569 algorithm
570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47629 times.
47629 true := (inN > 0);
571 47629 (lst1, lst2) := splitr(inList, inN-1);
572 47629 lst2 := restOrEmpty(lst2);
573 47629 outList := append_reverse(lst1,inElement::lst2);
574 end set;
575
576 public function firstOrEmpty<T>
577 "Returns the first element of a list as a list, or an empty list if the given
578 list is empty."
579 input list<T> inList;
580 output list<T> outList;
581 algorithm
582 outList := match inList
583 local
584 T e;
585
586 case e :: _ then {e};
587 else {};
588 end match;
589 end firstOrEmpty;
590
591 public function second<T>
592 "Returns the second element of a list. Fails if the list is empty."
593 input list<T> inList;
594 output T outSecond;
595 algorithm
596
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11351 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11351 times.
11351 _ :: outSecond :: _ := inList;
597 end second;
598
599 public function last<T>
600 "Returns the last element of a list. Fails if the list is empty."
601 input list<T> inList;
602 output T outLast;
603 protected
604 list<T> rest;
605 algorithm
606
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 937733 times.
937764 outLast::rest := inList;
607
2/2
✓ Branch 0 taken 839940 times.
✓ Branch 1 taken 937733 times.
1777673 for e in rest loop
608 outLast := e;
609 end for;
610 end last;
611
612 public function lastListOrEmpty<T>
613 "Returns the last element(list) of a list of lists. Returns empty list
614 if the outer list is empty."
615 input list<list<T>> inListList;
616 output list<T> outLastList = {};
617 algorithm
618
2/2
✓ Branch 0 taken 905379 times.
✓ Branch 1 taken 526658 times.
1432037 for e in inListList loop
619 outLastList := e;
620 end for;
621 end lastListOrEmpty;
622
623 public function lastN<T>
624 "Returns the last N elements of a list."
625 input list<T> inList;
626 input Integer inN;
627 output list<T> outList;
628 protected
629 Integer len;
630 algorithm
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6011 times.
6011 true := inN >= 0;
632 6011 len := listLength(inList);
633 6011 outList := stripN(inList, len - inN);
634 end lastN;
635
636 public function trimToLength<T>
637 "Removes elements from the head of the list until it contains n elements or fewer."
638 input output list<T> lst;
639 input Integer n;
640 protected
641 Integer len;
642 algorithm
643 179275 len := listLength(lst);
644
645
2/2
✓ Branch 0 taken 179274 times.
✓ Branch 1 taken 1 time.
179276 for i in 1:(len-n) loop
646 1 lst := listRest(lst);
647 end for;
648 end trimToLength;
649
650 public function restOrEmpty<T>
651 "Returns all elements except for the first in a list, or the empty list if the
652 list is empty."
653 input list<T> inList;
654 output list<T> outList;
655 algorithm
656
2/2
✓ Branch 0 taken 85515 times.
✓ Branch 1 taken 13964 times.
99479 outList := if listEmpty(inList) then inList else listRest(inList);
657 end restOrEmpty;
658
659 public function getIndexFirst<T>
660 input Integer index;
661 input list<T> inList;
662 output T element;
663 algorithm
664 19819 element := listGet(inList, index);
665 end getIndexFirst;
666
667 public function getAtIndexLst<T>
668 "zero based"
669 input list<T> lst;
670 input list<Integer> positions;
671 input Boolean zeroBased = false;
672 output list<T> olst;
673 protected
674 array<T> arr = listArray(lst);
675 Integer shift = if zeroBased then 1 else 0;
676 algorithm
677 ✗ olst := list(arr[pos+shift] for pos in positions);
678 end getAtIndexLst;
679
680 public function firstN<T>
681 "Returns the first N elements of a list, or fails if there are not enough
682 elements in the list."
683 input list<T> inList;
684 input Integer N;
685 output list<T> outList;
686 algorithm
687 11114 outList := firstN_reverse(inList, N);
688 11114 outList := listReverseInPlace(outList);
689 end firstN;
690
691 public function firstN_reverse<T>
692 "Returns the first N element of a list in reverse order, or fails if there are
693 not enough elements in the list."
694 input list<T> inList;
695 input Integer N;
696 output list<T> outList = {};
697 protected
698 T e;
699 list<T> rest;
700 algorithm
701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11114 times.
11114 true := N >= 0;
702 rest := inList;
703
704
2/2
✓ Branch 0 taken 9328 times.
✓ Branch 1 taken 1786 times.
14911 for i in 1:N loop
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3797 times.
3797 e :: rest := rest;
706 outList := e :: outList;
707 end for;
708 end firstN_reverse;
709
710 public function stripLast<T>
711 "Removes the last element of a list. If the list is the empty list, the
712 function returns the empty list."
713 input list<T> inList;
714 output list<T> outList;
715 algorithm
716
1/2
✓ Branch 0 taken 3128 times.
✗ Branch 1 not taken.
3128 if listEmpty(inList) then
717 outList := {};
718 else
719
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3128 times.
3128 _ :: outList := listReverse(inList);
720 3128 outList := listReverseInPlace(outList);
721 end if;
722 end stripLast;
723
724 public function stripN<T>
725 "Strips the N first elements from a list. Fails if the list contains less than
726 N elements, or if N is negative."
727 input list<T> inList;
728 input Integer inN;
729 output list<T> outList = inList;
730 algorithm
731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10613 times.
10613 true := inN >= 0;
732
733
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 6166 times.
10613 for i in 1:inN loop
734
2/2
✓ Branch 0 taken 1452 times.
✓ Branch 1 taken 8173 times.
9625 _ :: outList := outList;
735 end for;
736 end stripN;
737
738 public function heapSortIntList
739 input output list<Integer> lst;
740 algorithm
741 lst := match lst
742 case {} then lst;
743 case {_} then lst;
744 135998 else arrayList(Array.heapSort(listArray(lst)));
745 end match;
746 end heapSortIntList;
747
748 public function sort<T>
749 "Sorts a list given an ordering function with the mergesort algorithm.
750 Example:
751 sort({2, 1, 3}, intGt) => {1, 2, 3}
752 sort({2, 1, 3}, intLt) => {3, 2, 1}"
753 input list<T> inList;
754 input CompareFunc inCompFunc;
755 output list<T> outList= {};
756
757 partial function CompareFunc
758 input T inElement1;
759 input T inElement2;
760 output Boolean inRes;
761 end CompareFunc;
762 protected
763 list<T> rest = inList;
764 T e1, e2;
765 list<T> left, right;
766 Integer middle;
767 algorithm
768
2/2
✓ Branch 0 taken 259534 times.
✓ Branch 1 taken 21180472 times.
21440006 if not listEmpty(rest) then
769 21180472 e1 :: rest := rest;
770
2/2
✓ Branch 0 taken 17611224 times.
✓ Branch 1 taken 3569248 times.
21180472 if listEmpty(rest) then
771 outList := inList;
772 else
773 17611224 e2 :: rest := rest;
774
2/2
✓ Branch 0 taken 8779883 times.
✓ Branch 1 taken 8831341 times.
17611224 if listEmpty(rest) then
775
4/4
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 8779733 times.
✓ Branch 4 taken 6546346 times.
✓ Branch 5 taken 2233537 times.
8779883 outList := if inCompFunc(e2, e1) then inList else {e2,e1};
776 else
777 8831341 middle := intDiv(listLength(inList), 2);
778 8831341 (left, right) := split(inList, middle);
779 8831341 left := sort(left, inCompFunc);
780 8831341 right := sort(right, inCompFunc);
781 8831341 outList := merge(left, right, inCompFunc, {});
782 end if;
783 end if;
784 end if;
785 end sort;
786
787 public function sortedDuplicates<T>
788 "Returns a list of all duplicates in a sorted list, using the given comparison
789 function to check for equality."
790 input list<T> inList;
791 input CompareFunc inCompFunc "Equality comparator";
792 output list<T> outDuplicates = {};
793
794 partial function CompareFunc
795 input T inElement1;
796 input T inElement2;
797 output Boolean outEqual;
798 end CompareFunc;
799 protected
800 T e;
801 list<T> rest = inList;
802 algorithm
803
2/2
✓ Branch 0 taken 10093027 times.
✓ Branch 1 taken 454561 times.
10547588 while not listEmpty(rest) loop
804 10093027 e :: rest := rest;
805
806
5/6
✓ Branch 0 taken 409461 times.
✓ Branch 1 taken 9683566 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9683566 times.
✓ Branch 8 taken 9683521 times.
✓ Branch 9 taken 45 times.
10093027 if not listEmpty(rest) and inCompFunc(e, listHead(rest)) then
807 outDuplicates := e :: outDuplicates;
808 end if;
809 end while;
810
811 454561 outDuplicates := listReverseInPlace(outDuplicates);
812 end sortedDuplicates;
813
814 public function sortedListAllUnique<T>
815 "The input is a sorted list. The functions checks if all elements are unique."
816 input list<T> lst;
817 input CompareFunc compareFn;
818 output Boolean allUnique = false;
819
820 partial function CompareFunc
821 input T inElement1;
822 input T inElement2;
823 output Boolean outEqual;
824 end CompareFunc;
825 protected
826 list<T> rest = lst;
827 algorithm
828
2/2
✓ Branch 0 taken 24936 times.
✓ Branch 1 taken 4512 times.
29448 while not listEmpty(rest) loop
829 rest := match rest
830 local
831 T e1,e2;
832 case {_} then {};
833 case e1::(rest as e2::_)
834 algorithm
835
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 20424 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20424 times.
20424 if compareFn(e1,e2) then
836 ✗ return;
837 end if;
838 then rest;
839 end match;
840 end while;
841 allUnique := true;
842 end sortedListAllUnique;
843
844 public function sortedUnique<T>
845 "Returns a list of unique elements in a sorted list, using the given
846 comparison function to check for equality."
847 input list<T> inList;
848 input CompareFunc inCompFunc;
849 output list<T> outUniqueElements = {};
850
851 partial function CompareFunc
852 input T inElement1;
853 input T inElement2;
854 output Boolean outEqual;
855 end CompareFunc;
856 protected
857 T e;
858 list<T> rest = inList;
859 algorithm
860
2/2
✓ Branch 0 taken 9925689 times.
✓ Branch 1 taken 3208270 times.
13133959 while not listEmpty(rest) loop
861 9925689 e :: rest := rest;
862
863
5/8
✓ Branch 0 taken 6874559 times.
✓ Branch 1 taken 3051130 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6874559 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 10 taken 1532764 times.
✓ Branch 11 taken 5341795 times.
9925689 if listEmpty(rest) or not inCompFunc(e, listHead(rest)) then
864 outUniqueElements := e :: outUniqueElements;
865 end if;
866 end while;
867
868 3208270 outUniqueElements := listReverseInPlace(outUniqueElements);
869 end sortedUnique;
870
871 public function sortedUniqueAndDuplicates<T>
872 "Returns a list with all duplicate elements removed, as well as a list of the
873 removed elements, using the given comparison function to check for equality."
874 input list<T> inList;
875 input CompareFunc inCompFunc;
876 output list<T> outUniqueElements = {};
877 output list<T> outDuplicateElements = {};
878
879 partial function CompareFunc
880 input T inElement1;
881 input T inElement2;
882 output Boolean outEqual;
883 end CompareFunc;
884 protected
885 T e;
886 list<T> rest = inList;
887 algorithm
888 ✗ while not listEmpty(rest) loop
889 ✗ e :: rest := rest;
890
891 ✗ if not listEmpty(rest) and inCompFunc(e, listHead(rest)) then
892 ✗ outDuplicateElements := e :: outDuplicateElements;
893 else
894 outUniqueElements := e :: outUniqueElements;
895 end if;
896 end while;
897
898 ✗ outUniqueElements := listReverseInPlace(outUniqueElements);
899 ✗ outDuplicateElements := listReverseInPlace(outDuplicateElements);
900 end sortedUniqueAndDuplicates;
901
902 public function sortedUniqueOnlyDuplicates<T>
903 "Returns a list with all duplicate elements removed, as well as a list of the
904 removed elements, using the given comparison function to check for equality."
905 input list<T> inList;
906 input CompareFunc inCompFunc;
907 output list<T> outDuplicateElements = {};
908
909 partial function CompareFunc
910 input T inElement1;
911 input T inElement2;
912 output Boolean outEqual;
913 end CompareFunc;
914 protected
915 T e;
916 list<T> rest = inList;
917 algorithm
918
2/2
✓ Branch 0 taken 8110 times.
✓ Branch 1 taken 5836 times.
13946 while not listEmpty(rest) loop
919 8110 e :: rest := rest;
920
921
5/6
✓ Branch 0 taken 3807 times.
✓ Branch 1 taken 4303 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4303 times.
✓ Branch 8 taken 4298 times.
✓ Branch 9 taken 5 times.
8110 if not listEmpty(rest) and inCompFunc(e, listHead(rest)) then
922 outDuplicateElements := e :: outDuplicateElements;
923 end if;
924 end while;
925
926 5836 outDuplicateElements := listReverseInPlace(outDuplicateElements);
927 end sortedUniqueOnlyDuplicates;
928
929 protected function merge<T>
930 "Helper function to sort, merges two sorted lists."
931 input list<T> inLeft;
932 input list<T> inRight;
933 input CompareFunc inCompFunc;
934 input list<T> acc;
935 output list<T> outList;
936
937 partial function CompareFunc
938 input T inElement1;
939 input T inElement2;
940 output Boolean outRes;
941 end CompareFunc;
942 protected
943 list<T> left = inLeft, right = inRight, res = acc;
944 T el;
945 algorithm
946
4/4
✓ Branch 0 taken 59462320 times.
✓ Branch 1 taken 2497692 times.
✓ Branch 2 taken 53128671 times.
✓ Branch 3 taken 6333649 times.
61960012 while not (listEmpty(left) or listEmpty(right)) loop
947
4/4
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 53128142 times.
✓ Branch 8 taken 10191646 times.
✓ Branch 9 taken 42937025 times.
53128671 if inCompFunc(listHead(right), listHead(left)) then
948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10191646 times.
10191646 el :: left := left;
949 else
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42937025 times.
42937025 el :: right := right;
951 end if;
952
953 res := el :: res;
954 end while;
955
956
3/4
✓ Branch 0 taken 2497692 times.
✓ Branch 1 taken 6333649 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2497692 times.
8831341 outList := if listEmpty(left) then
957 (if listEmpty(right) then listReverseInPlace(res) else append_reverse(res, right))
958 else append_reverse(res, left);
959 end merge;
960
961 public function mergeSorted<T>
962 "This function merges two sorted lists into one sorted list. It takes a
963 comparison function that defines a strict weak ordering of the elements, i.e.
964 that returns true if the first element should be placed before the second
965 element in the sorted list."
966 input list<T> inList1;
967 input list<T> inList2;
968 input CompFunc inCompFunc;
969 output list<T> outList = {};
970
971 partial function CompFunc
972 input T inElement1;
973 input T inElement2;
974 output Boolean outIsEqual;
975 end CompFunc;
976 protected
977 list<T> l1, l2;
978 T e1, e2;
979 algorithm
980 l1 := inList1;
981 l2 := inList2;
982
983 // While both lists contain elements.
984
4/4
✓ Branch 0 taken 50011 times.
✓ Branch 1 taken 6283 times.
✓ Branch 2 taken 24755 times.
✓ Branch 3 taken 25256 times.
56294 while not listEmpty(l1) and not listEmpty(l2) loop
985 24755 e1 :: _ := l1;
986 24755 e2 :: _ := l2;
987
988 // Move the smallest head from either list to accumulator.
989
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24755 times.
✓ Branch 4 taken 6283 times.
✓ Branch 5 taken 18472 times.
24755 if inCompFunc(e1, e2) then
990 outList := e1 :: outList;
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6283 times.
6283 _ :: l1 := l1;
992 else
993 outList := e2 :: outList;
994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18472 times.
18472 _ :: l2 := l2;
995 end if;
996 end while;
997
998 // Reverse accumulator and append the remaining elements.
999
2/2
✓ Branch 0 taken 25256 times.
✓ Branch 1 taken 6283 times.
31539 l1 := if listEmpty(l1) then l2 else l1;
1000 31539 outList := append_reverse(outList, l1);
1001 end mergeSorted;
1002
1003 public function countingSort
1004 "Provides same functionality as sort, but for integer values between 1
1005 and N. The complexity in this case is O(N + n).
1006 This will terminate if the list contains an element > N."
1007 input list<Integer> inList;
1008 input Integer N;
1009 output list<Integer> outSorted = {};
1010 protected
1011 array<Integer> a1;
1012 algorithm
1013 ✗ if not hasSeveralElements(inList) then
1014 outSorted := inList;
1015 ✗ return;
1016 end if;
1017
1018 ✗ a1 := arrayCreate(N, 0);
1019 ✗ for v in inList loop
1020 ✗ a1[v] := intAdd(a1[v], 1);
1021 end for;
1022
1023 ✗ for v in N:-1:1 loop
1024 ✗ for c in 1:a1[v] loop
1025 outSorted := v :: outSorted;
1026 end for;
1027 end for;
1028 ✗ GCExt.free(a1);
1029 end countingSort;
1030
1031 public function unique<T>
1032 "Takes a list of elements and returns a list with duplicates removed, so that
1033 each element in the new list is unique."
1034 input list<T> inList;
1035 output list<T> outList = {};
1036 algorithm
1037
2/2
✓ Branch 0 taken 574814 times.
✓ Branch 1 taken 145603 times.
720417 for e in inList loop
1038
2/2
✓ Branch 1 taken 460695 times.
✓ Branch 2 taken 114119 times.
574814 if not listMember(e, outList) then
1039 outList := e :: outList;
1040 end if;
1041 end for;
1042 145603 outList := listReverseInPlace(outList);
1043 end unique;
1044
1045 public function uniqueIntN
1046 "Takes a list of integers and returns a list with duplicates removed, so that
1047 each element in the new list is unique. O(listLength(inList))"
1048 input list<Integer> inList;
1049 input Integer inN;
1050 output list<Integer> outList = {};
1051 protected
1052 array<Boolean> arr;
1053 algorithm
1054 6938 arr := arrayCreate(inN, true);
1055
1056
2/2
✓ Branch 0 taken 52287 times.
✓ Branch 1 taken 6938 times.
59225 for i in inList loop
1057
2/2
✓ Branch 1 taken 33485 times.
✓ Branch 2 taken 18802 times.
52287 if arrayGet(arr, i) then
1058 outList := i :: outList;
1059 end if;
1060
1061 52287 arrayUpdate(arr, i, false);
1062 end for;
1063 6938 GCExt.free(arr);
1064 end uniqueIntN;
1065
1066 public function uniqueOnTrue<T>
1067 "Takes a list of elements and a comparison function over two elements of the
1068 list and returns a list with duplicates removed, so that each element in the
1069 new list is unique."
1070 input list<T> inList;
1071 input CompFunc inCompFunc;
1072 output list<T> outList = {};
1073
1074 partial function CompFunc
1075 input T inElement1;
1076 input T inElement2;
1077 output Boolean outIsEqual;
1078 end CompFunc;
1079 algorithm
1080
2/2
✓ Branch 0 taken 42262 times.
✓ Branch 1 taken 24522 times.
66784 for e in inList loop
1081
2/2
✓ Branch 1 taken 21973 times.
✓ Branch 2 taken 20289 times.
42262 if not isMemberOnTrue(e, outList, inCompFunc) then
1082 outList := e :: outList;
1083 end if;
1084 end for;
1085 24522 outList := listReverseInPlace(outList);
1086 end uniqueOnTrue;
1087
1088 public function split<T>
1089 "Takes a list and a position, and splits the list at the position given.
1090 Example: split({1, 2, 5, 7}, 2) => ({1, 2}, {5, 7})"
1091 input list<T> inList;
1092 input Integer inPosition;
1093 output list<T> outList1;
1094 output list<T> outList2;
1095 protected
1096 Integer pos;
1097 list<T> l1 = {}, l2 = inList;
1098 T e;
1099 algorithm
1100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8941801 times.
8941801 true := inPosition >= 0;
1101 pos := inPosition;
1102
1103 // Move elements from l2 to l1 until we reach the split position.
1104
2/2
✓ Branch 0 taken 8848592 times.
✓ Branch 1 taken 93209 times.
53273218 for i in 1:pos loop
1105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44331417 times.
44331417 e :: l2 := l2;
1106 l1 := e :: l1;
1107 end for;
1108
1109 8941801 outList1 := listReverseInPlace(l1);
1110 outList2 := l2;
1111 end split;
1112
1113 public function splitr<T>
1114 "Takes a list and a position, and splits the list at the position given. The first list is returned in reverse order.
1115 Example: split({1, 2, 5, 7}, 2) => ({2, 1}, {5, 7})"
1116 input list<T> inList;
1117 input Integer inPosition;
1118 output list<T> outList1;
1119 output list<T> outList2;
1120 protected
1121 Integer pos;
1122 list<T> l1 = {}, l2 = inList;
1123 T e;
1124 algorithm
1125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47740 times.
47740 true := inPosition >= 0;
1126 pos := inPosition;
1127
1128 // Move elements from l2 to l1 until we reach the split position.
1129
2/2
✓ Branch 0 taken 22562 times.
✓ Branch 1 taken 25178 times.
79739 for i in 1:pos loop
1130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31999 times.
31999 e :: l2 := l2;
1131 l1 := e :: l1;
1132 end for;
1133
1134 outList1 := l1;
1135 outList2 := l2;
1136 end splitr;
1137
1138 public function splitOnTrue<T>
1139 "Splits a list into two sublists depending on predicate function."
1140 input list<T> inList;
1141 input PredicateFunc inFunc;
1142 output list<T> outTrueList = {};
1143 output list<T> outFalseList = {};
1144
1145 partial function PredicateFunc
1146 input T inElement;
1147 output Boolean outResult;
1148 end PredicateFunc;
1149 algorithm
1150
2/2
✓ Branch 0 taken 16880829 times.
✓ Branch 1 taken 7278181 times.
24159010 for e in inList loop
1151
4/4
✓ Branch 0 taken 140243 times.
✓ Branch 1 taken 16740586 times.
✓ Branch 4 taken 3334776 times.
✓ Branch 5 taken 13546053 times.
16880829 if inFunc(e) then
1152 outTrueList := e :: outTrueList;
1153 else
1154 outFalseList := e :: outFalseList;
1155 end if;
1156 end for;
1157
1158 7278181 outTrueList := listReverseInPlace(outTrueList);
1159 7278181 outFalseList := listReverseInPlace(outFalseList);
1160 end splitOnTrue;
1161
1162 public function split1OnTrue<T, ArgT1>
1163 "Splits a list into two sublists depending on predicate function."
1164 input list<T> inList;
1165 input PredicateFunc inFunc;
1166 input ArgT1 inArg1;
1167 output list<T> outTrueList = {};
1168 output list<T> outFalseList = {};
1169
1170 partial function PredicateFunc
1171 input T inElement;
1172 input ArgT1 inArg1;
1173 output Boolean outResult;
1174 end PredicateFunc;
1175 algorithm
1176
2/2
✓ Branch 0 taken 1384286 times.
✓ Branch 1 taken 1116457 times.
2500743 for e in inList loop
1177
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1384286 times.
✓ Branch 4 taken 588755 times.
✓ Branch 5 taken 795531 times.
1384286 if inFunc(e, inArg1) then
1178 outTrueList := e :: outTrueList;
1179 else
1180 outFalseList := e :: outFalseList;
1181 end if;
1182 end for;
1183
1184 1116457 outTrueList := listReverseInPlace(outTrueList);
1185 1116457 outFalseList := listReverseInPlace(outFalseList);
1186 end split1OnTrue;
1187
1188 public function split2OnTrue<T, ArgT1, ArgT2>
1189 "Splits a list into two sublists depending on predicate function."
1190 input list<T> inList;
1191 input PredicateFunc inFunc;
1192 input ArgT1 inArg1;
1193 input ArgT2 inArg2;
1194 output list<T> outTrueList = {};
1195 output list<T> outFalseList = {};
1196
1197 partial function PredicateFunc
1198 input T inElement;
1199 input ArgT1 inArg1;
1200 input ArgT2 inArg2;
1201 output Boolean outResult;
1202 end PredicateFunc;
1203 algorithm
1204 ✗ for e in inList loop
1205 ✗ if inFunc(e, inArg1, inArg2) then
1206 outTrueList := e :: outTrueList;
1207 else
1208 outFalseList := e :: outFalseList;
1209 end if;
1210 end for;
1211
1212 ✗ outTrueList := listReverseInPlace(outTrueList);
1213 ✗ outFalseList := listReverseInPlace(outFalseList);
1214 end split2OnTrue;
1215
1216 public function splitOnFirstMatch<T>
1217 "Splits a list when the given function first finds a matching element.
1218 Example: splitOnFirstMatch({1, 2, 3, 4, 5}, isThree) => ({1, 2}, {3, 4, 5})"
1219 input list<T> inList;
1220 input CompFunc inFunc;
1221 output list<T> outList1 = {};
1222 output list<T> outList2 = inList;
1223
1224 partial function CompFunc
1225 input T inElement;
1226 output Boolean outMatch;
1227 end CompFunc;
1228 protected
1229 T e;
1230 algorithm
1231 // Shuffle elements from outList2 to outList1 until we find a match.
1232
2/2
✓ Branch 0 taken 137724 times.
✓ Branch 1 taken 79 times.
137803 while not listEmpty(outList2) loop
1233 137724 e :: outList2 := outList2;
1234
1235
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 137724 times.
✓ Branch 4 taken 38098 times.
✓ Branch 5 taken 99626 times.
137724 if inFunc(e) then
1236 outList2 := e :: outList2;
1237 38098 break;
1238 end if;
1239
1240 outList1 := e :: outList1;
1241 end while;
1242 38177 outList1 := listReverseInPlace(outList1);
1243 end splitOnFirstMatch;
1244
1245 public function splitLast<T>
1246 "Returns the last element of a list and a list of all previous elements. If
1247 the list is the empty list, the function fails.
1248 Example: splitLast({3, 5, 7, 11, 13}) => (13, {3, 5, 7, 11})"
1249 input list<T> inList;
1250 output T outLast;
1251 output list<T> outRest;
1252 algorithm
1253
2/2
✓ Branch 1 taken 889 times.
✓ Branch 2 taken 3744 times.
4633 outLast :: outRest := listReverse(inList);
1254 3744 outRest := listReverseInPlace(outRest);
1255 end splitLast;
1256
1257 public function splitEqualParts<T>
1258 "Splits a list into n equally sized parts.
1259 Example: splitEqualParts({1, 2, 3, 4, 5, 6, 7, 8}, 4) =>
1260 {{1, 2}, {3, 4}, {5, 6}, {7, 8}}"
1261 input list<T> inList;
1262 input Integer inParts;
1263 output list<list<T>> outParts;
1264 protected
1265 Integer length;
1266 algorithm
1267
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if inParts == 0 then
1268 outParts := {};
1269 else
1270 2 length := listLength(inList);
1271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 0 := intMod(length, inParts);
1272 2 outParts := partition(inList, intDiv(length, inParts));
1273 end if;
1274 end splitEqualParts;
1275
1276 public function splitOnBoolList<T>
1277 "Splits a list into two sublists depending on a second list of bools."
1278 input list<T> inList;
1279 input list<Boolean> inBools;
1280 output list<T> outTrueList = {};
1281 output list<T> outFalseList = {};
1282 protected
1283 T e;
1284 list<T> rest_e = inList;
1285 Boolean b;
1286 list<Boolean> rest_b = inBools;
1287 algorithm
1288
2/2
✓ Branch 0 taken 32198 times.
✓ Branch 1 taken 13459 times.
45657 while not listEmpty(rest_e) loop
1289 32198 e :: rest_e := rest_e;
1290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32198 times.
32198 b :: rest_b := rest_b;
1291
1292
2/2
✓ Branch 0 taken 21414 times.
✓ Branch 1 taken 10784 times.
32198 if b then
1293 outTrueList := e :: outTrueList;
1294 elseif isPresent(outFalseList) then
1295 outFalseList := e :: outFalseList;
1296 end if;
1297 end while;
1298
1299 13459 outTrueList := listReverseInPlace(outTrueList);
1300 13459 outFalseList := listReverseInPlace(outFalseList);
1301 end splitOnBoolList;
1302
1303 public function partition<T>
1304 "Partitions a list of elements into sublists of length n.
1305 Example: partition({1, 2, 3, 4, 5}, 2) => {{1, 2}, {3, 4}, {5}}"
1306 input list<T> inList;
1307 input Integer inPartitionLength;
1308 output list<list<T>> outPartitions = {};
1309 protected
1310 list<T> lst = inList, part;
1311 Integer length;
1312 algorithm
1313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16148 times.
16148 true := inPartitionLength > 0;
1314
2/2
✓ Branch 0 taken 767 times.
✓ Branch 1 taken 15381 times.
16148 if listEmpty(inList) then
1315 767 return;
1316 end if;
1317
1318 15381 length := listLength(inList);
1319
2/2
✓ Branch 0 taken 15072 times.
✓ Branch 1 taken 309 times.
15381 if inPartitionLength >= length then
1320 outPartitions := {inList};
1321 15072 return;
1322 end if;
1323
1324 // Split the list into partitions.
1325
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
1316 for i in 1:div(length, inPartitionLength) loop
1326 1007 (part, lst) := split(lst, inPartitionLength);
1327 outPartitions := part :: outPartitions;
1328 end for;
1329
1330 // Append the remainder of the list.
1331
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 141 times.
309 if not listEmpty(lst) then
1332 outPartitions := lst :: outPartitions;
1333 end if;
1334
1335 309 outPartitions := listReverseInPlace(outPartitions);
1336 end partition;
1337
1338 public function balancedPartition<T>
1339 "Partitions a list of elements into even sublists of maximum length n.
1340 Example: partition({1, 2, 3, 4, 5}, 2) => {{1, 2}, {3, 4}, {5}}
1341 The number of partitions is the same as partition(), but chosen to be
1342 as balanced in length as possible.
1343 "
1344 input list<T> lst;
1345 input Integer maxLength;
1346 output list<list<T>> outPartitions;
1347 protected
1348 Integer length, n;
1349 algorithm
1350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2420 times.
2420 true := maxLength > 0;
1351
2/2
✓ Branch 0 taken 713 times.
✓ Branch 1 taken 1707 times.
2420 if listEmpty(lst) then
1352 outPartitions := {};
1353 713 return;
1354 end if;
1355 1707 length := listLength(lst);
1356 1707 n := intDiv(length-1, maxLength)+1;
1357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1707 times.
1707 outPartitions := partition(lst, intDiv(length-1, n)+1);
1358 end balancedPartition;
1359
1360 public function sublist<T>
1361 "Returns a sublist determined by an offset and length.
1362 Example: sublist({1,2,3,4,5}, 2, 3) => {2,3,4}"
1363 input list<T> inList;
1364 input Integer inOffset;
1365 input Integer inLength;
1366 output list<T> outList = {};
1367 protected
1368 T e;
1369 list<T> rest = inList;
1370 algorithm
1371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 true := inOffset > 0;
1372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 true := inLength >= 0;
1373
1374 // Remove elements until we reach the offset position.
1375
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36 times.
38 for i in 2:inOffset loop
1376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 _ :: rest := rest;
1377 end for;
1378
1379 // Accumulate the given number of elements.
1380
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
150 for i in 1:inLength loop
1381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 e :: rest := rest;
1382 outList := e :: outList;
1383 end for;
1384
1385 38 outList := listReverseInPlace(outList);
1386 end sublist;
1387
1388 public function transposeList<T>
1389 "Transposes a list of lists. Example:
1390 transposeList({{1, 2, 3}, {4, 5, 6}}) => {{1, 4}, {2, 5}, {3, 6}}"
1391 input list<list<T>> inList;
1392 output list<list<T>> outList = {};
1393 protected
1394 array<array<T>> arr;
1395 list<T> new_row;
1396 Integer c_len, r_len;
1397 algorithm
1398
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3434 times.
3447 if listEmpty(inList) then
1399 13 return;
1400 end if;
1401
1402 // Convert the list into an array, it's a lot more efficient than fiddling
1403 // around with lists.
1404
4/4
✓ Branch 0 taken 14976 times.
✓ Branch 1 taken 3434 times.
✓ Branch 2 taken 14976 times.
✓ Branch 3 taken 3434 times.
18410 arr := listArray(list(listArray(lst) for lst in inList));
1405
1406 // Get the dimensions of the array.
1407 c_len := arrayLength(arr);
1408 r_len := arrayLength(arrayGet(arr, 1));
1409
1410 // Loop through the array in reverse order so we can create the new lists
1411 // in the correct order without having to reverse them.
1412
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 3411 times.
9921 for i in r_len:-1:1 loop
1413 new_row := {};
1414
1415
1/2
✓ Branch 0 taken 6487 times.
✗ Branch 1 not taken.
34544 for j in c_len:-1:1 loop
1416 28057 new_row := arrayGetNoBoundsChecking(arrayGet(arr, j), i) :: new_row;
1417 end for;
1418
1419 outList := new_row :: outList;
1420 end for;
1421 end transposeList;
1422
1423 public function listArrayReverse<T>
1424 input list<T> inLst;
1425 output array<T> outArr;
1426 protected
1427 Integer len;
1428 T defaultValue;
1429 algorithm
1430
2/2
✓ Branch 0 taken 96540 times.
✓ Branch 1 taken 383965 times.
480505 if listEmpty(inLst) then
1431 96540 outArr := listArray(inLst);
1432 96540 return;
1433 end if;
1434 383965 len := listLength(inLst);
1435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 383965 times.
383965 defaultValue::_ := inLst;
1436 383965 outArr := arrayCreateNoInit(len,defaultValue);
1437
2/2
✓ Branch 0 taken 3005975 times.
✓ Branch 1 taken 383965 times.
3389940 for e in inLst loop
1438 arrayUpdateNoBoundsChecking(outArr, len, e);
1439 3005975 len := len-1;
1440 end for;
1441 end listArrayReverse;
1442
1443 public function setEqualOnTrue<T>
1444 "Takes two lists and a comparison function over two elements of the lists.
1445 It returns true if the two sets are equal, false otherwise."
1446 input list<T> inList1;
1447 input list<T> inList2;
1448 input CompFunc inCompFunc;
1449 output Boolean outIsEqual;
1450
1451 partial function CompFunc
1452 input T inElement1;
1453 input T inElement2;
1454 output Boolean outIsEqual;
1455 end CompFunc;
1456 protected
1457 list<T> lst;
1458 Integer lst_size;
1459 algorithm
1460 ✗ lst := intersectionOnTrue(inList1, inList2, inCompFunc);
1461 ✗ lst_size := listLength(lst);
1462 ✗ outIsEqual := intEq(lst_size, listLength(inList1)) and
1463 intEq(lst_size, listLength(inList2));
1464 end setEqualOnTrue;
1465
1466 protected function addPos
1467 "Helper function to intersectionIntN."
1468 input list<Integer> inList;
1469 input array<Integer> inArray;
1470 input Integer inIndex;
1471 output array<Integer> outArray;
1472 algorithm
1473 ✗ for i in inList loop
1474 ✗ arrayUpdate(inArray, i, intAdd(arrayGet(inArray, i), inIndex));
1475 end for;
1476
1477 outArray := inArray;
1478 end addPos;
1479
1480 public function intersectionOnTrue<T>
1481 "Takes two lists and a comparison function over two elements of the lists. It
1482 returns the intersection of the two lists, using the comparison function
1483 passed as argument to determine identity between two elements.
1484 Example:
1485 intersectionOnTrue({1, 4, 2}, {5, 2, 4, 6}, intEq) => {4, 2}"
1486 input list<T> inList1;
1487 input list<T> inList2;
1488 input CompFunc inCompFunc;
1489 output list<T> outIntersection = {};
1490
1491 partial function CompFunc
1492 input T inElement1;
1493 input T inElement2;
1494 output Boolean outIsEqual;
1495 end CompFunc;
1496 algorithm
1497
2/2
✓ Branch 0 taken 1201248 times.
✓ Branch 1 taken 330607 times.
1531855 for e in inList1 loop
1498
2/2
✓ Branch 1 taken 39323 times.
✓ Branch 2 taken 1161925 times.
1201248 if isMemberOnTrue(e, inList2, inCompFunc) then
1499 outIntersection := e :: outIntersection;
1500 end if;
1501 end for;
1502
1503 330607 outIntersection := listReverseInPlace(outIntersection);
1504 end intersectionOnTrue;
1505
1506 public function intersection1OnTrue<T>
1507 "Takes two lists and a comparison function over two elements of the lists. It
1508 returns the intersection of the two lists, using the comparison function
1509 passed as argument to determine identity between two elements. This function
1510 also returns a list of the elements from list 1 which is not in list 2 and a
1511 list of the elements from list 2 which is not in list 1."
1512 input list<T> inList1;
1513 input list<T> inList2;
1514 input CompFunc inCompFunc;
1515 output list<T> outIntersection = {};
1516 output list<T> outList1Rest = {};
1517 output list<T> outList2Rest = inList2;
1518
1519 partial function CompFunc
1520 input T inElement1;
1521 input T inElement2;
1522 output Boolean outIsEqual;
1523 end CompFunc;
1524 protected
1525 list<T> lst1 = inList1, lst2 = inList2;
1526 algorithm
1527
2/2
✓ Branch 0 taken 6707 times.
✓ Branch 1 taken 50926 times.
57633 if listEmpty(inList1) then
1528 6707 return;
1529 end if;
1530
2/2
✓ Branch 0 taken 28048 times.
✓ Branch 1 taken 22878 times.
50926 if listEmpty(inList2) then
1531 outList1Rest := inList1;
1532 22878 return;
1533 end if;
1534
1535
4/4
✓ Branch 0 taken 35399 times.
✓ Branch 1 taken 3174 times.
✓ Branch 2 taken 655 times.
✓ Branch 3 taken 34744 times.
38573 while not (listEmpty(lst1) or listEmpty(lst2)) loop
1536
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 34744 times.
✓ Branch 8 taken 24219 times.
✓ Branch 9 taken 10525 times.
34744 if not inCompFunc(listHead(lst1), listHead(lst2)) then
1537 break;
1538 end if;
1539
1540 10525 outIntersection := listHead(lst1) :: outIntersection;
1541 10525 lst1 := listRest(lst1);
1542 10525 lst2 := listRest(lst2);
1543 end while;
1544
1545
2/2
✓ Branch 0 taken 117752 times.
✓ Branch 1 taken 28048 times.
145800 for e in lst1 loop
1546
2/2
✓ Branch 1 taken 31939 times.
✓ Branch 2 taken 85813 times.
117752 if isMemberOnTrue(e, inList2, inCompFunc) then
1547 outIntersection := e :: outIntersection;
1548 elseif isPresent(outList1Rest) then
1549 outList1Rest := e :: outList1Rest;
1550 end if;
1551 end for;
1552
1553 28048 outIntersection := listReverseInPlace(outIntersection);
1554
2/2
✓ Branch 0 taken 26854 times.
✓ Branch 1 taken 1194 times.
28048 outList1Rest := if isPresent(outList1Rest) then listReverseInPlace(outList1Rest) else {};
1555
2/2
✓ Branch 0 taken 22290 times.
✓ Branch 1 taken 5758 times.
28048 outList2Rest := if isPresent(outList2Rest) then setDifferenceOnTrue(inList2, outIntersection, inCompFunc) else {};
1556 end intersection1OnTrue;
1557
1558 public function setDifferenceIntN
1559 "Provides same functionality as setDifference, but for integer values
1560 between 1 and N. The complexity in this case is O(n)"
1561 input list<Integer> inList1;
1562 input list<Integer> inList2;
1563 input Integer inN;
1564 output list<Integer> outDifference = {};
1565 protected
1566 array<Integer> a;
1567 algorithm
1568 ✗ if inN > 0 then
1569 ✗ a := arrayCreate(inN, 0);
1570 ✗ a := addPos(inList1, a, 1);
1571 ✗ a := addPos(inList2, a, 1);
1572
1573 ✗ for i in inN:-1:1 loop
1574 ✗ if arrayGet(a, i) == 1 then
1575 outDifference := i :: outDifference;
1576 end if;
1577 end for;
1578 ✗ GCExt.free(a);
1579 end if;
1580 end setDifferenceIntN;
1581
1582 public function setDifferenceOnTrue<T>
1583 "Takes two lists and a comparison function over two elements of the lists. It
1584 returns the set difference of the two lists A-B, using the comparison
1585 function passed as argument to determine identity between two elements.
1586 Example:
1587 setDifferenceOnTrue({1, 2, 3}, {1, 3}, intEq) => {2}"
1588 input list<T> inList1;
1589 input list<T> inList2;
1590 input CompFunc inCompFunc;
1591 output list<T> outDifference = inList1;
1592
1593 partial function CompFunc
1594 input T inElement1;
1595 input T inElement2;
1596 output Boolean outIsEqual;
1597 end CompFunc;
1598 algorithm
1599 // Empty - B = Empty
1600
2/2
✓ Branch 0 taken 58422 times.
✓ Branch 1 taken 3105 times.
61527 if listEmpty(inList1) then
1601 3105 return;
1602 end if;
1603
1604
2/2
✓ Branch 0 taken 383297 times.
✓ Branch 1 taken 58422 times.
441719 for e in inList2 loop
1605 383297 (outDifference, _) := deleteMemberOnTrue(e, outDifference, inCompFunc);
1606 end for;
1607 end setDifferenceOnTrue;
1608
1609 public function setDifference<T>
1610 "Takes two lists and returns the set difference of two lists A - B.
1611 Example:
1612 setDifference({1, 2, 3}, {1, 3}) => {2}"
1613 input list<T> inList1;
1614 input list<T> inList2;
1615 output list<T> outDifference = inList1;
1616 algorithm
1617
2/2
✓ Branch 0 taken 190817 times.
✓ Branch 1 taken 1975 times.
192792 if listEmpty(inList1) then
1618 1975 return;
1619 end if;
1620
1621
2/2
✓ Branch 0 taken 1315767 times.
✓ Branch 1 taken 190817 times.
1506584 for e in inList2 loop
1622 1315767 outDifference := deleteMemberOnTrue(e, outDifference, valueEq);
1623 end for;
1624 end setDifference;
1625
1626 public function unionIntN
1627 "Provides same functionality as listUnion, but for integer values between 1
1628 and N. The complexity in this case is O(n)"
1629 input list<Integer> inList1;
1630 input list<Integer> inList2;
1631 input Integer inN;
1632 output list<Integer> outUnion = {};
1633 protected
1634 array<Integer> a;
1635 algorithm
1636 ✗ if inN > 0 then
1637 ✗ a := arrayCreate(inN, 0);
1638 ✗ a := addPos(inList1, a, 1);
1639 ✗ a := addPos(inList2, a, 1);
1640
1641 ✗ for i in inN:-1:1 loop
1642 ✗ if arrayGet(a, i) > 0 then
1643 outUnion := i :: outUnion;
1644 end if;
1645 end for;
1646 ✗ GCExt.free(a);
1647 end if;
1648 end unionIntN;
1649
1650 public function unionElt<T>
1651 "Takes a value and a list of values and inserts the value into the list if it
1652 is not already in the list. If it is in the list it is not inserted.
1653 Example:
1654 unionElt(1, {2, 3}) => {1, 2, 3}
1655 unionElt(0, {0, 1, 2}) => {0, 1, 2}"
1656 input T inElement;
1657 input list<T> inList;
1658 output list<T> outList;
1659 algorithm
1660 584477 outList := consOnTrue(not listMember(inElement, inList), inElement, inList);
1661 end unionElt;
1662
1663 public function unionEltOnTrue<T>
1664 "Works as unionElt, but with a compare function."
1665 input T inElement;
1666 input list<T> inList;
1667 input CompFunc inCompFunc;
1668 output list<T> outList;
1669
1670 partial function CompFunc
1671 input T inElement1;
1672 input T inElement2;
1673 output Boolean outIsEqual;
1674 end CompFunc;
1675 algorithm
1676 2005446 outList := consOnTrue(not isMemberOnTrue(inElement, inList, inCompFunc),
1677 inElement, inList);
1678 end unionEltOnTrue;
1679
1680 public function union<T>
1681 "Takes two lists and returns the union of the two lists, i.e. a list of all
1682 elements combined without duplicates. Example:
1683 union({0, 1}, {2, 1}) => {0, 1, 2}"
1684 input list<T> inList1;
1685 input list<T> inList2;
1686 output list<T> outUnion = {};
1687 algorithm
1688
2/2
✓ Branch 0 taken 338305 times.
✓ Branch 1 taken 2447343 times.
2785648 for e in inList1 loop
1689 338305 outUnion := unionElt(e, outUnion);
1690 end for;
1691
1692
2/2
✓ Branch 0 taken 129196 times.
✓ Branch 1 taken 2447343 times.
2576539 for e in inList2 loop
1693 129196 outUnion := unionElt(e, outUnion);
1694 end for;
1695
1696 2447343 outUnion := listReverseInPlace(outUnion);
1697 end union;
1698
1699 public function unionOnTrue<T>
1700 "Takes two lists an a comparison function over two elements of the lists. It
1701 returns the union of the two lists, using the comparison function passed as
1702 argument to determine identity between two elements. Example:
1703 unionOnTrue({1, 2}, {2, 3}, intEq) => {1, 2, 3}"
1704 input list<T> inList1;
1705 input list<T> inList2;
1706 input CompFunc inCompFunc;
1707 output list<T> outUnion = {};
1708
1709 partial function CompFunc
1710 input T inList1;
1711 input T inList2;
1712 output Boolean outIsEqual;
1713 end CompFunc;
1714 algorithm
1715
2/2
✓ Branch 0 taken 58105 times.
✓ Branch 1 taken 76999 times.
135104 for e in inList1 loop
1716 58105 outUnion := unionEltOnTrue(e, outUnion, inCompFunc);
1717 end for;
1718
1719
2/2
✓ Branch 0 taken 49841 times.
✓ Branch 1 taken 76999 times.
126840 for e in inList2 loop
1720 49841 outUnion := unionEltOnTrue(e, outUnion, inCompFunc);
1721 end for;
1722
1723 76999 outUnion := listReverseInPlace(outUnion);
1724 end unionOnTrue;
1725
1726 public function unionAppendListOnTrue<T>
1727 input list<T> inList;
1728 input list<T> inUnion;
1729 input CompFunc inCompFunc;
1730 output list<T> outUnion;
1731
1732 partial function CompFunc
1733 input T inElement1;
1734 input T inElement2;
1735 output Boolean outIsEqual;
1736 end CompFunc;
1737 algorithm
1738 280232 outUnion := fold(inList, function unionEltOnTrue(inCompFunc = inCompFunc), inUnion);
1739 end unionAppendListOnTrue;
1740
1741 public function unionList<T>
1742 "Takes a list of lists and returns the union of the sublists.
1743 Example: unionList({1}, {1, 2}, {3, 4}, {5}}) => {1, 2, 3, 4, 5}"
1744 input list<list<T>> inList;
1745 output list<T> outUnion;
1746 algorithm
1747
1/2
✓ Branch 0 taken 530021 times.
✗ Branch 1 not taken.
530021 outUnion := if listEmpty(inList) then {} else reduce(inList, union);
1748 end unionList;
1749
1750 public function unionOnTrueList<T>
1751 "Takes a list of lists and a comparison function over two elements of the
1752 lists. It returns the union of all sublists using the comparison function
1753 for identity.
1754 Example:
1755 unionOnTrueList({{1}, {1, 2}, {3, 4}}, intEq) => {1, 2, 3, 4}"
1756 input list<list<T>> inList;
1757 input CompFunc inCompFunc;
1758 output list<T> outUnion;
1759
1760 partial function CompFunc
1761 input T inElement1;
1762 input T inElement2;
1763 output Boolean outIsEqual;
1764 end CompFunc;
1765 algorithm
1766 ✗ outUnion := if listEmpty(inList) then {}
1767 else reduce(inList, function unionOnTrue(inCompFunc = inCompFunc));
1768 end unionOnTrueList;
1769
1770 public function map<TI, TO>
1771 "Takes a list and a function, and creates a new list by applying the function
1772 to each element of the list."
1773 input list<TI> inList;
1774 input MapFunc inFunc;
1775 output list<TO> outList;
1776
1777 partial function MapFunc
1778 input TI inElement;
1779 output TO outElement;
1780 end MapFunc;
1781 algorithm
1782
6/6
✓ Branch 0 taken 29656518 times.
✓ Branch 1 taken 16464898 times.
✓ Branch 2 taken 29656518 times.
✓ Branch 3 taken 16464898 times.
✓ Branch 4 taken 1961246 times.
✓ Branch 5 taken 27695272 times.
46121416 outList := list(inFunc(e) for e in inList);
1783 end map;
1784
1785 public function mapArray<TI, TO>
1786 "Takes a list and a function, and creates a new list by applying the function
1787 to each element of the list."
1788 input array<TI> inArray;
1789 input MapFunc inFunc;
1790 output list<TO> outList;
1791
1792 partial function MapFunc
1793 input TI inElement;
1794 output TO outElement;
1795 end MapFunc;
1796 algorithm
1797
5/6
✓ Branch 0 taken 74589 times.
✓ Branch 1 taken 3170 times.
✓ Branch 3 taken 74589 times.
✓ Branch 4 taken 3170 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 74589 times.
155518 outList := list(inFunc(e) for e in inArray);
1798 end mapArray;
1799
1800 public function mapCheckReferenceEq<TI>
1801 "Takes a list and a function, and creates a new list by applying the function
1802 to each element of the list."
1803 input list<TI> inList;
1804 input MapFunc inFunc;
1805 output list<TI> outList;
1806
1807 partial function MapFunc
1808 input TI inElement;
1809 output TI outElement;
1810 end MapFunc;
1811 protected
1812 DoubleEnded.MutableList<TI> delst;
1813 Integer n=0;
1814 TI e1, savedElt;
1815 algorithm
1816
2/2
✓ Branch 0 taken 679675 times.
✓ Branch 1 taken 248477 times.
928152 for e in inList loop
1817
2/2
✓ Branch 0 taken 678363 times.
✓ Branch 1 taken 1312 times.
679675 e1 := inFunc(e);
1818 // Preserve reference equality without any allocation if nothing changed
1819
2/2
✓ Branch 0 taken 69718 times.
✓ Branch 1 taken 609957 times.
679675 if not referenceEq(e, e1) then
1820 savedElt := e1;
1821 69718 delst := DoubleEnded.empty(e1);
1822
2/2
✓ Branch 0 taken 382988 times.
✓ Branch 1 taken 69718 times.
452706 for elt in inList loop
1823
2/2
✓ Branch 0 taken 246496 times.
✓ Branch 1 taken 136492 times.
382988 if n < 0 then
1824
2/2
✓ Branch 0 taken 246474 times.
✓ Branch 1 taken 22 times.
246496 e1 := inFunc(elt);
1825 else
1826
2/2
✓ Branch 0 taken 66774 times.
✓ Branch 1 taken 69718 times.
136492 e1 := if n == 0 then savedElt else elt;
1827 end if;
1828 382988 DoubleEnded.push_back(delst, e1);
1829 382988 n := n-1;
1830 end for;
1831 69718 outList := DoubleEnded.toListAndClear(delst);
1832 69718 return;
1833 end if;
1834 609957 n := n + 1;
1835 end for;
1836 outList := inList;
1837 end mapCheckReferenceEq;
1838
1839 public function mapReverse<TI, TO>
1840 "Takes a list and a function, and creates a new list by applying the function
1841 to each element of the list. The created list will be reversed compared to
1842 the given list."
1843 input list<TI> inList;
1844 input MapFunc inFunc;
1845 output list<TO> outList;
1846
1847 partial function MapFunc
1848 input TI inElement;
1849 output TO outElement;
1850 end MapFunc;
1851 algorithm
1852
5/6
✓ Branch 0 taken 1244021 times.
✓ Branch 1 taken 189173 times.
✓ Branch 2 taken 1244021 times.
✓ Branch 3 taken 189173 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1244021 times.
1433194 outList := listReverse(inFunc(e) for e in inList);
1853 end mapReverse;
1854
1855 public function map_2<TI, TO1, TO2>
1856 "Takes a list and a function, and creates two new lists by applying the
1857 function to each element of the list."
1858 input list<TI> inList;
1859 input MapFunc inFunc;
1860 output list<TO1> outList1 = {};
1861 output list<TO2> outList2 = {};
1862
1863 partial function MapFunc
1864 input TI inElement;
1865 output TO1 outElement1;
1866 output TO2 outElement2;
1867 end MapFunc;
1868 protected
1869 TO1 e1;
1870 TO2 e2;
1871 algorithm
1872
2/2
✓ Branch 0 taken 135935 times.
✓ Branch 1 taken 18081 times.
154016 for e in inList loop
1873
2/2
✓ Branch 0 taken 124435 times.
✓ Branch 1 taken 11500 times.
135935 (e1, e2) := inFunc(e);
1874 outList1 := e1 :: outList1;
1875
2/2
✓ Branch 0 taken 11488 times.
✓ Branch 1 taken 65082 times.
76570 if isPresent(outList2) then
1876 11488 outList2 := e2 :: outList2;
1877 end if;
1878 end for;
1879
1880 18081 outList1 := listReverseInPlace(outList1);
1881
2/2
✓ Branch 0 taken 16827 times.
✓ Branch 1 taken 1254 times.
18081 if isPresent(outList2) then
1882 1254 outList2 := listReverseInPlace(outList2);
1883 end if;
1884 end map_2;
1885
1886 public function map_3<TI, TO1, TO2, TO3>
1887 "Takes a list and a function, and creates three new lists by applying the
1888 function to each element of the list."
1889 input list<TI> inList;
1890 input MapFunc inFunc;
1891 output list<TO1> outList1 = {};
1892 output list<TO2> outList2 = {};
1893 output list<TO3> outList3 = {};
1894
1895 partial function MapFunc
1896 input TI inElement;
1897 output TO1 outElement1;
1898 output TO2 outElement2;
1899 output TO3 outElement3;
1900 end MapFunc;
1901 protected
1902 TO1 e1;
1903 TO2 e2;
1904 TO3 e3;
1905 algorithm
1906
2/2
✓ Branch 0 taken 83384 times.
✓ Branch 1 taken 6817 times.
90201 for e in inList loop
1907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83384 times.
83384 (e1, e2, e3) := inFunc(e);
1908 outList1 := e1 :: outList1;
1909
2/2
✓ Branch 0 taken 82844 times.
✓ Branch 1 taken 540 times.
83384 if isPresent(outList2) then
1910 82844 outList2 := e2 :: outList2;
1911 end if;
1912
2/2
✓ Branch 0 taken 2089 times.
✓ Branch 1 taken 81295 times.
83384 if isPresent(outList3) then
1913 2089 outList3 := e3 :: outList3;
1914 end if;
1915 end for;
1916
1917 6817 outList1 := listReverseInPlace(outList1);
1918
2/2
✓ Branch 0 taken 6736 times.
✓ Branch 1 taken 81 times.
6817 if isPresent(outList2) then
1919 6736 outList2 := listReverseInPlace(outList2);
1920 end if;
1921
2/2
✓ Branch 0 taken 5623 times.
✓ Branch 1 taken 1194 times.
6817 if isPresent(outList3) then
1922 1194 outList3 := listReverseInPlace(outList3);
1923 end if;
1924 end map_3;
1925
1926 public function mapOption<TI, TO>
1927 "The same as map(map(inList, getOption), inMapFunc), but is more efficient and
1928 it strips out NONE() instead of failing on them."
1929 input list<Option<TI>> inList;
1930 input MapFunc inFunc;
1931 output list<TO> outList = {};
1932
1933 partial function MapFunc
1934 input TI inElement;
1935 output TO outElement;
1936 end MapFunc;
1937 protected
1938 TI ei;
1939 TO eo;
1940 algorithm
1941 ✗ for oe in inList loop
1942 ✗ if isSome(oe) then
1943 ✗ SOME(ei) := oe;
1944 ✗ eo := inFunc(ei);
1945 outList := eo :: outList;
1946 end if;
1947 end for;
1948
1949 ✗ outList := listReverseInPlace(outList);
1950 end mapOption;
1951
1952 public function map1Option<TI, TO, ArgT>
1953 "The same as map1(map(inList, getOption), inMapFunc), but is more efficient and
1954 it strips out NONE() instead of failing on them."
1955 input list<Option<TI>> inList;
1956 input MapFunc inFunc;
1957 input ArgT inArg1;
1958 output list<TO> outList = {};
1959
1960 partial function MapFunc
1961 input TI inElement;
1962 input ArgT inArg1;
1963 output TO outElement;
1964 end MapFunc;
1965 protected
1966 TI ei;
1967 TO eo;
1968 algorithm
1969
2/2
✓ Branch 0 taken 1980 times.
✓ Branch 1 taken 17 times.
1997 for oe in inList loop
1970
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1980 times.
✓ Branch 2 taken 1980 times.
✗ Branch 3 not taken.
1980 if isSome(oe) then
1971 1980 SOME(ei) := oe;
1972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1980 times.
1980 eo := inFunc(ei, inArg1);
1973 outList := eo :: outList;
1974 end if;
1975 end for;
1976
1977 17 outList := listReverseInPlace(outList);
1978 end map1Option;
1979
1980 public function map2Option<TI, TO, ArgT1, ArgT2>
1981 "The same as map2(map(inList, getOption), inMapFunc), but is more efficient and
1982 it strips out NONE() instead of failing on them."
1983 input list<Option<TI>> inList;
1984 input MapFunc inFunc;
1985 input ArgT1 inArg1;
1986 input ArgT2 inArg2;
1987 output list<TO> outList = {};
1988
1989 partial function MapFunc
1990 input TI inElement;
1991 input ArgT1 inArg1;
1992 input ArgT2 inArg2;
1993 output TO outElement;
1994 end MapFunc;
1995 protected
1996 TI ei;
1997 TO eo;
1998 algorithm
1999
2/2
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 474 times.
958 for oe in inList loop
2000
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 484 times.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 244 times.
484 if isSome(oe) then
2001 240 SOME(ei) := oe;
2002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 eo := inFunc(ei, inArg1, inArg2);
2003 outList := eo :: outList;
2004 end if;
2005 end for;
2006
2007 474 outList := listReverseInPlace(outList);
2008 end map2Option;
2009
2010 public function map_0<T>
2011 "Takes a list and a function which does not return a value. The function is
2012 probably a function with side effects, like print."
2013 input list<T> inList;
2014 input MapFunc inFunc;
2015
2016 partial function MapFunc
2017 input T inElement;
2018 end MapFunc;
2019 algorithm
2020
2/2
✓ Branch 0 taken 354535 times.
✓ Branch 1 taken 71043 times.
425578 for e in inList loop
2021
2/2
✓ Branch 0 taken 5908 times.
✓ Branch 1 taken 348627 times.
354535 inFunc(e);
2022 end for;
2023 end map_0;
2024
2025 public function map1<TI, TO, ArgT1>
2026 "Takes a list, a function and one extra argument, and creates a new list
2027 by applying the function to each element of the list."
2028 input list<TI> inList;
2029 input MapFunc inMapFunc;
2030 input ArgT1 inArg1;
2031 output list<TO> outList;
2032
2033 partial function MapFunc
2034 input TI inElement;
2035 input ArgT1 inArg1;
2036 output TO outElement;
2037 end MapFunc;
2038 algorithm
2039
6/6
✓ Branch 0 taken 5373906 times.
✓ Branch 1 taken 8853883 times.
✓ Branch 2 taken 5373906 times.
✓ Branch 3 taken 8853883 times.
✓ Branch 4 taken 223 times.
✓ Branch 5 taken 5373683 times.
14227789 outList := list(inMapFunc(e, inArg1) for e in inList);
2040 end map1;
2041
2042 public function map1r<TI, TO, ArgT1>
2043 "Takes a list, a function and one extra argument, and creates a new list
2044 by applying the function to each element of the list. The given map
2045 function has it's arguments reversed compared to map1."
2046 input list<TI> inList;
2047 input MapFunc inFunc;
2048 input ArgT1 inArg1;
2049 output list<TO> outList;
2050
2051 partial function MapFunc
2052 input ArgT1 inArg1;
2053 input TI inElement;
2054 output TO outElement;
2055 end MapFunc;
2056 algorithm
2057
5/6
✓ Branch 0 taken 3574053 times.
✓ Branch 1 taken 1963561 times.
✓ Branch 2 taken 3574053 times.
✓ Branch 3 taken 1963561 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3574053 times.
5537614 outList := list(inFunc(inArg1, e) for e in inList);
2058 end map1r;
2059
2060 public function map1_0<TI, ArgT1>
2061 "Takes a list, a function and one extra argument, and applies the functions to
2062 each element of the list."
2063 input list<TI> inList;
2064 input MapFunc inFunc;
2065 input ArgT1 inArg1;
2066
2067 partial function MapFunc
2068 input TI inElement;
2069 input ArgT1 inArg1;
2070 end MapFunc;
2071 algorithm
2072
2/2
✓ Branch 0 taken 84852 times.
✓ Branch 1 taken 94097 times.
178949 for e in inList loop
2073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84852 times.
84852 inFunc(e, inArg1);
2074 end for;
2075 end map1_0;
2076
2077 public function map1_2<TI, TO1, TO2, ArgT1>
2078 "Takes a list and a function, and creates two new lists by applying the
2079 function to each element of the list."
2080 input list<TI> inList;
2081 input MapFunc inFunc;
2082 input ArgT1 inArg1;
2083 output list<TO1> outList1 = {};
2084 output list<TO2> outList2 = {};
2085
2086 partial function MapFunc
2087 input TI inElement;
2088 input ArgT1 inArg1;
2089 output TO1 outElement1;
2090 output TO2 outElement2;
2091 end MapFunc;
2092 protected
2093 TO1 e1;
2094 TO2 e2;
2095 algorithm
2096
2/2
✓ Branch 0 taken 80191 times.
✓ Branch 1 taken 354210 times.
434401 for e in inList loop
2097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80191 times.
80191 (e1, e2) := inFunc(e, inArg1);
2098 outList1 := e1 :: outList1;
2099 80191 outList2 := e2 :: outList2;
2100 end for;
2101
2102 354210 outList1 := listReverseInPlace(outList1);
2103 354210 outList2 := listReverseInPlace(outList2);
2104 end map1_2;
2105
2106 public function map2<TI, TO, ArgT1, ArgT2>
2107 "Takes a list, a function and two extra arguments, and creates a new list
2108 by applying the function to each element of the list."
2109 input list<TI> inList;
2110 input MapFunc inFunc;
2111 input ArgT1 inArg1;
2112 input ArgT2 inArg2;
2113 output list<TO> outList;
2114
2115 partial function MapFunc
2116 input TI inElement;
2117 input ArgT1 inArg1;
2118 input ArgT2 inArg2;
2119 output TO outElement;
2120 end MapFunc;
2121 algorithm
2122
5/6
✓ Branch 0 taken 6772819 times.
✓ Branch 1 taken 3047679 times.
✓ Branch 2 taken 6772819 times.
✓ Branch 3 taken 3047679 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6772819 times.
9820498 outList := list(inFunc(e, inArg1, inArg2) for e in inList);
2123 end map2;
2124
2125 public function map2Reverse<TI, TO, ArgT1, ArgT2>
2126 "Takes a list, a function and two extra arguments, and creates a new list
2127 by applying the function to each element of the list. The created list will
2128 be reversed compared to the given list."
2129 input list<TI> inList;
2130 input MapFunc inFunc;
2131 input ArgT1 inArg1;
2132 input ArgT2 inArg2;
2133 output list<TO> outList;
2134
2135 partial function MapFunc
2136 input TI inElement;
2137 input ArgT1 inArg1;
2138 input ArgT2 inArg2;
2139 output TO outElement;
2140 end MapFunc;
2141 algorithm
2142
5/6
✓ Branch 0 taken 653245 times.
✓ Branch 1 taken 1458066 times.
✓ Branch 2 taken 653245 times.
✓ Branch 3 taken 1458066 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 653245 times.
2111311 outList := listReverse(inFunc(e, inArg1, inArg2) for e in inList);
2143 end map2Reverse;
2144
2145 public function map2_0<TI, ArgT1, ArgT2>
2146 "Takes a list, a function and two extra argument, and applies the functions to
2147 each element of the list."
2148 input list<TI> inList;
2149 input MapFunc inFunc;
2150 input ArgT1 inArg1;
2151 input ArgT2 inArg2;
2152
2153 partial function MapFunc
2154 input TI inElement;
2155 input ArgT1 inArg1;
2156 input ArgT2 inArg2;
2157 end MapFunc;
2158 algorithm
2159
2/2
✓ Branch 0 taken 1051340 times.
✓ Branch 1 taken 1119788 times.
2171128 for e in inList loop
2160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1051340 times.
1051340 inFunc(e, inArg1, inArg2);
2161 end for;
2162 end map2_0;
2163
2164 public function map2_2<TI, TO1, TO2, ArgT1, ArgT2>
2165 "Takes a list, a function and two extra argument, and creates two new lists
2166 by applying the function to each element of the list."
2167 input list<TI> inList;
2168 input MapFunc inFunc;
2169 input ArgT1 inArg1;
2170 input ArgT2 inArg2;
2171 output list<TO1> outList1 = {};
2172 output list<TO2> outList2 = {};
2173
2174 partial function MapFunc
2175 input TI inElement;
2176 input ArgT1 inArg1;
2177 input ArgT2 inArg2;
2178 output TO1 outElement1;
2179 output TO2 outElement2;
2180 end MapFunc;
2181 protected
2182 TO1 e1;
2183 TO2 e2;
2184 algorithm
2185
2/2
✓ Branch 0 taken 163749 times.
✓ Branch 1 taken 70681 times.
234430 for e in inList loop
2186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163749 times.
163749 (e1, e2) := inFunc(e, inArg1, inArg2);
2187 outList1 := e1 :: outList1;
2188 163666 outList2 := e2 :: outList2;
2189 end for;
2190
2191 70681 outList1 := listReverseInPlace(outList1);
2192 70681 outList2 := listReverseInPlace(outList2);
2193 end map2_2;
2194
2195 public function map3<TI, TO, ArgT1, ArgT2, ArgT3>
2196 "Takes a list, a function and three extra arguments, and creates a new list
2197 by applying the function to each element of the list."
2198 input list<TI> inList;
2199 input MapFunc inFunc;
2200 input ArgT1 inArg1;
2201 input ArgT2 inArg2;
2202 input ArgT3 inArg3;
2203 output list<TO> outList;
2204
2205 partial function MapFunc
2206 input TI inElement;
2207 input ArgT1 inArg1;
2208 input ArgT2 inArg2;
2209 input ArgT3 inArg3;
2210 output TO outElement;
2211 end MapFunc;
2212 algorithm
2213
5/6
✓ Branch 0 taken 608036 times.
✓ Branch 1 taken 595759 times.
✓ Branch 2 taken 608036 times.
✓ Branch 3 taken 595759 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 608036 times.
1203795 outList := list(inFunc(e, inArg1, inArg2, inArg3) for e in inList);
2214 end map3;
2215
2216 public function map4<TI, TO, ArgT1, ArgT2, ArgT3, ArgT4>
2217 "Takes a list, a function and four extra arguments, and creates a new list
2218 by applying the function to each element of the list."
2219 input list<TI> inList;
2220 input MapFunc inFunc;
2221 input ArgT1 inArg1;
2222 input ArgT2 inArg2;
2223 input ArgT3 inArg3;
2224 input ArgT4 inArg4;
2225 output list<TO> outList;
2226
2227 partial function MapFunc
2228 input TI inElement;
2229 input ArgT1 inArg1;
2230 input ArgT2 inArg2;
2231 input ArgT3 inArg3;
2232 input ArgT4 inArg4;
2233 output TO outElement;
2234 end MapFunc;
2235 algorithm
2236
5/6
✓ Branch 0 taken 423174 times.
✓ Branch 1 taken 380733 times.
✓ Branch 2 taken 423174 times.
✓ Branch 3 taken 380733 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 423174 times.
803907 outList := list(inFunc(e, inArg1, inArg2, inArg3, inArg4) for e in inList);
2237 end map4;
2238
2239 public function map4_0<TI, ArgT1, ArgT2, ArgT3, ArgT4>
2240 "Takes a list, a function and four extra arguments, and applies the functions to
2241 each element of the list."
2242 input list<TI> inList;
2243 input MapFunc inFunc;
2244 input ArgT1 inArg1;
2245 input ArgT2 inArg2;
2246 input ArgT3 inArg3;
2247 input ArgT4 inArg4;
2248
2249 partial function MapFunc
2250 input TI inElement;
2251 input ArgT1 inArg1;
2252 input ArgT2 inArg2;
2253 input ArgT3 inArg3;
2254 input ArgT4 inArg4;
2255 end MapFunc;
2256 algorithm
2257
2/2
✓ Branch 0 taken 10830 times.
✓ Branch 1 taken 54308 times.
65138 for e in inList loop
2258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10830 times.
10830 inFunc(e, inArg1, inArg2, inArg3, inArg4);
2259 end for;
2260 end map4_0;
2261
2262 public function map5<TI, TO, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5>
2263 "Takes a list, a function and five extra arguments, and creates a new list
2264 by applying the function to each element of the list."
2265 input list<TI> inList;
2266 input MapFunc inFunc;
2267 input ArgT1 inArg1;
2268 input ArgT2 inArg2;
2269 input ArgT3 inArg3;
2270 input ArgT4 inArg4;
2271 input ArgT5 inArg5;
2272 output list<TO> outList;
2273
2274 partial function MapFunc
2275 input TI inElement;
2276 input ArgT1 inArg1;
2277 input ArgT2 inArg2;
2278 input ArgT3 inArg3;
2279 input ArgT4 inArg4;
2280 input ArgT5 inArg5;
2281 output TO outElement;
2282 end MapFunc;
2283 algorithm
2284
5/6
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
19 outList := list(inFunc(e, inArg1, inArg2, inArg3, inArg4, inArg5) for e in inList);
2285 end map5;
2286
2287 public function map6<TI, TO, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5, ArgT6>
2288 "Takes a list, a function and six extra arguments, and creates a new list
2289 by applying the function to each element of the list."
2290 input list<TI> inList;
2291 input MapFunc inFunc;
2292 input ArgT1 inArg1;
2293 input ArgT2 inArg2;
2294 input ArgT3 inArg3;
2295 input ArgT4 inArg4;
2296 input ArgT5 inArg5;
2297 input ArgT6 inArg6;
2298 output list<TO> outList;
2299
2300 partial function MapFunc
2301 input TI inElement;
2302 input ArgT1 inArg1;
2303 input ArgT2 inArg2;
2304 input ArgT3 inArg3;
2305 input ArgT4 inArg4;
2306 input ArgT5 inArg5;
2307 input ArgT6 inArg6;
2308 output TO outElement;
2309 end MapFunc;
2310 algorithm
2311
5/6
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 408 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 408 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 100 times.
508 outList := list(inFunc(e, inArg1, inArg2, inArg3, inArg4, inArg5, inArg6) for e in inList);
2312 end map6;
2313
2314 public function mapFlat<TI, TO>
2315 "Takes a list and a function that maps elements to lists, which are flattened
2316 into one list. Example (fill2(n) = {n, n}):
2317 mapFlat({1, 2, 3}, fill2) => {1, 1, 2, 2, 3, 3}"
2318 input list<TI> inList;
2319 input MapFunc inMapFunc;
2320 output list<TO> outList;
2321
2322 partial function MapFunc
2323 input TI inElement;
2324 output list<TO> outList;
2325 end MapFunc;
2326 algorithm
2327 146502 outList := listReverse(mapFlatReverse(inList, inMapFunc));
2328 end mapFlat;
2329
2330 public function mapFlatReverse<TI, TO>
2331 "Takes a list and a function that maps elements to lists, which are flattened
2332 into one list. Returns the values in reverse order as the input.
2333 Example (fill2(n) = {n, n}):
2334 mapFlat({1, 2, 3}, fill2) => {3, 3, 2, 2, 1, 1}"
2335 input list<TI> inList;
2336 input MapFunc inMapFunc;
2337 output list<TO> outList = {};
2338
2339 partial function MapFunc
2340 input TI inElement;
2341 output list<TO> outList;
2342 end MapFunc;
2343 algorithm
2344
2/2
✓ Branch 0 taken 615917 times.
✓ Branch 1 taken 151060 times.
766977 for e in inList loop
2345
2/2
✓ Branch 0 taken 131623 times.
✓ Branch 1 taken 484294 times.
615917 outList := listAppend(inMapFunc(e), outList);
2346 end for;
2347 end mapFlatReverse;
2348
2349 public function mapMap<TI, TO1, TO2>
2350 "More efficient than: map(map(inList, inMapFunc1), inMapFunc2)"
2351 input list<TI> inList;
2352 input MapFunc1 inMapFunc1;
2353 input MapFunc2 inMapFunc2;
2354 output list<TO2> outList;
2355
2356 partial function MapFunc1
2357 input TI inElement;
2358 output TO1 outElement;
2359 end MapFunc1;
2360
2361 partial function MapFunc2
2362 input TO1 inElement;
2363 output TO2 outElement;
2364 end MapFunc2;
2365 algorithm
2366
6/10
✓ Branch 0 taken 45133 times.
✓ Branch 1 taken 22314 times.
✓ Branch 2 taken 45133 times.
✓ Branch 3 taken 22314 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 45133 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 45133 times.
67447 outList := list(inMapFunc2(inMapFunc1(e)) for e in inList);
2367 end mapMap;
2368
2369 public function foldAllValue<TI, TO, ArgT1>
2370 "Applies a function to all elements in the lists, and fails if not all
2371 elements are equal to the given value. This function also takes an extra
2372 argument that are passed to the mapping function and updated"
2373 input list<TI> inList;
2374 input MapFunc inMapFunc;
2375 input TO inValue;
2376 input ArgT1 inArg1;
2377
2378 partial function MapFunc
2379 input TI inElement;
2380 input ArgT1 inArg1;
2381 output TO outElement;
2382 output ArgT1 outArg1;
2383 end MapFunc;
2384 protected
2385 ArgT1 arg = inArg1;
2386 TO eo;
2387 algorithm
2388
2/2
✓ Branch 0 taken 4488 times.
✓ Branch 1 taken 720 times.
5208 for e in inList loop
2389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4488 times.
4488 (eo, arg) := inMapFunc(e, arg);
2390
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 4477 times.
4488 true := valueEq(eo, inValue);
2391 end for;
2392 end foldAllValue;
2393
2394 public function applyAndFold<TI, TO, FT>
2395 "fold(map(inList, inApplyFunc), inFoldFunc, inFoldArg), but is more
2396 memory-efficient."
2397 input list<TI> inList;
2398 input FoldFunc inFoldFunc;
2399 input ApplyFunc inApplyFunc;
2400 input FT inFoldArg;
2401 output FT outResult = inFoldArg;
2402
2403 partial function ApplyFunc
2404 input TI inElement;
2405 output TO outElement;
2406 end ApplyFunc;
2407
2408 partial function FoldFunc
2409 input TO inElement;
2410 input FT inAccumulator;
2411 output FT outResult;
2412 end FoldFunc;
2413 algorithm
2414
2/2
✓ Branch 0 taken 541439 times.
✓ Branch 1 taken 51336 times.
592775 for e in inList loop
2415
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 541439 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 541439 times.
541439 outResult := inFoldFunc(inApplyFunc(e), outResult);
2416 end for;
2417 end applyAndFold;
2418
2419 public function applyAndFold1<TI, TO, FT, ArgT1>
2420 "fold(map(inList, inApplyFunc(inExtraArg)), inFoldFunc, inFoldArg), but is more
2421 memory-efficient."
2422 input list<TI> inList;
2423 input FoldFunc inFoldFunc;
2424 input ApplyFunc inApplyFunc;
2425 input ArgT1 inExtraArg;
2426 input FT inFoldArg;
2427 output FT outResult = inFoldArg;
2428
2429 partial function ApplyFunc
2430 input TI inElement1;
2431 input ArgT1 inElement2;
2432 output TO outElement;
2433 end ApplyFunc;
2434
2435 partial function FoldFunc
2436 input TO inElement;
2437 input FT inAccumulator;
2438 output FT outResult;
2439 end FoldFunc;
2440 algorithm
2441
2/2
✓ Branch 0 taken 65315 times.
✓ Branch 1 taken 1856 times.
67171 for e in inList loop
2442
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 65315 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 65315 times.
65315 outResult := inFoldFunc(inApplyFunc(e, inExtraArg), outResult);
2443 end for;
2444 end applyAndFold1;
2445
2446 public function mapMapBoolAnd<TI,TI2>
2447 "Maps each element of a inList to Boolean type with inFunc. Stops mapping at first occurrence of false return value."
2448 input list<TI> inList;
2449 input MapFunc inFunc;
2450 input MapBFunc inBFunc;
2451 output Boolean res = false;
2452
2453 partial function MapBFunc
2454 input TI2 inElement;
2455 output Boolean outBool;
2456 end MapBFunc;
2457 partial function MapFunc
2458 input TI inElement;
2459 output TI2 outElement;
2460 end MapFunc;
2461 algorithm
2462
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 257 times.
681 for e in inList loop
2463
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 424 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 424 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 424 times.
424 if not inBFunc(inFunc(e)) then
2464 ✗ return;
2465 end if;
2466 end for;
2467 res := true;
2468 end mapMapBoolAnd;
2469
2470 public function mapList<TI, TO>
2471 "Takes a list of lists and a functions, and creates a new list of lists by
2472 applying the function to all elements in the list of lists.
2473 Example: mapList({{1, 2},{3},{4}}, intString) =>
2474 {{\"1\", \"2\"}, {\"3\"}, {\"4\"}}"
2475 input list<list<TI>> inListList;
2476 input MapFunc inFunc;
2477 output list<list<TO>> outListList;
2478
2479 partial function MapFunc
2480 input TI inElement;
2481 output TO outElement;
2482 end MapFunc;
2483 algorithm
2484
9/10
✓ Branch 0 taken 3251 times.
✓ Branch 1 taken 1179 times.
✓ Branch 2 taken 3251 times.
✓ Branch 3 taken 1179 times.
✓ Branch 4 taken 9723 times.
✓ Branch 5 taken 3251 times.
✓ Branch 6 taken 9723 times.
✓ Branch 7 taken 3251 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 9723 times.
14153 outListList := list(list(inFunc(e) for e in lst) for lst in inListList);
2485 end mapList;
2486
2487 public function mapListReverse<TI, TO>
2488 "Takes a list of lists and a functions, and creates a new list of lists by
2489 applying the function to all elements in the list of lists. The order of the
2490 elements in the inner lists will be reversed compared to mapList.
2491 Example: mapListReverse({{1, 2}, {3}, {4}}, intString) =>
2492 {{\"4\"}, {\"3\"}, {\"2\", \"1\"}}"
2493 input list<list<TI>> inListList;
2494 input MapFunc inFunc;
2495 output list<list<TO>> outListList;
2496
2497 partial function MapFunc
2498 input TI inElement;
2499 output TO outElement;
2500 end MapFunc;
2501 algorithm
2502
9/10
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 52 times.
✓ Branch 4 taken 14966 times.
✓ Branch 5 taken 180 times.
✓ Branch 6 taken 14966 times.
✓ Branch 7 taken 180 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 14966 times.
15378 outListList := list(listReverse(inFunc(e) for e in lst) for lst in inListList);
2503 end mapListReverse;
2504
2505 public function map1List<TI, TO, ArgT1>
2506 "Similar to mapList but with a mapping function that takes an extra argument."
2507 input list<list<TI>> inListList;
2508 input MapFunc inFunc;
2509 input ArgT1 inArg1;
2510 output list<list<TO>> outListList;
2511
2512 partial function MapFunc
2513 input TI inElement;
2514 input ArgT1 inArg1;
2515 output TO outElement;
2516 end MapFunc;
2517 algorithm
2518
9/10
✓ Branch 0 taken 29228 times.
✓ Branch 1 taken 6993 times.
✓ Branch 2 taken 29228 times.
✓ Branch 3 taken 6993 times.
✓ Branch 4 taken 124486 times.
✓ Branch 5 taken 29228 times.
✓ Branch 6 taken 124486 times.
✓ Branch 7 taken 29228 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 124486 times.
160707 outListList := list(list(inFunc(e, inArg1) for e in lst) for lst in inListList);
2519 end map1List;
2520
2521 public function map2List<TI, TO, ArgT1, ArgT2>
2522 "Similar to mapList but with a mapping function that takes two extra arguments."
2523 input list<list<TI>> inListList;
2524 input MapFunc inFunc;
2525 input ArgT1 inArg1;
2526 input ArgT2 inArg2;
2527 output list<list<TO>> outListList;
2528
2529 partial function MapFunc
2530 input TI inElement;
2531 input ArgT1 inArg1;
2532 input ArgT2 inArg2;
2533 output TO outElement;
2534 end MapFunc;
2535 algorithm
2536
9/10
✓ Branch 0 taken 1307 times.
✓ Branch 1 taken 489 times.
✓ Branch 2 taken 1307 times.
✓ Branch 3 taken 489 times.
✓ Branch 4 taken 4227 times.
✓ Branch 5 taken 1307 times.
✓ Branch 6 taken 4227 times.
✓ Branch 7 taken 1307 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4227 times.
6023 outListList := list(list(inFunc(e, inArg1, inArg2) for e in lst) for lst in inListList);
2537 end map2List;
2538
2539 public function fold<T, FT>
2540 "Takes a list and a function operating on list elements having an extra
2541 argument that is 'updated', thus returned from the function. fold will call
2542 the function for each element in a sequence, updating the start value.
2543 Example: fold({1, 2, 3}, intAdd, 2) => 8
2544 intAdd(1, 2) => 3, intAdd(2, 3) => 5, intAdd(3, 5) => 8"
2545 input list<T> inList;
2546 input FoldFunc inFoldFunc;
2547 input FT inStartValue;
2548 output FT outResult = inStartValue;
2549
2550 partial function FoldFunc
2551 input T inElement;
2552 input FT inFoldArg;
2553 output FT outFoldArg;
2554 end FoldFunc;
2555 algorithm
2556
2/2
✓ Branch 0 taken 31169750 times.
✓ Branch 1 taken 12219400 times.
43389150 for e in inList loop
2557
2/2
✓ Branch 0 taken 986605 times.
✓ Branch 1 taken 30183145 times.
31169750 outResult := inFoldFunc(e, outResult);
2558 end for;
2559 end fold;
2560
2561 public function foldr<T, FT>
2562 "Same as fold, but with reversed order on the fold function arguments."
2563 input list<T> inList;
2564 input FoldFunc inFoldFunc;
2565 input FT inStartValue;
2566 output FT outResult = inStartValue;
2567
2568 partial function FoldFunc
2569 input FT inFoldArg;
2570 input T inElement;
2571 output FT outFoldArg;
2572 end FoldFunc;
2573 algorithm
2574
2/2
✓ Branch 0 taken 1129242 times.
✓ Branch 1 taken 1641848 times.
2771090 for e in inList loop
2575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1129242 times.
1129242 outResult := inFoldFunc(outResult, e);
2576 end for;
2577 end foldr;
2578
2579 public function fold1<T, FT, ArgT1>
2580 "Takes a list and a function operating on list elements having an extra
2581 argument that is 'updated', thus returned from the function, and a constant
2582 argument that is not updated. fold will call the function for each element in
2583 a sequence, updating the start value."
2584 input list<T> inList;
2585 input FoldFunc inFoldFunc;
2586 input ArgT1 inExtraArg;
2587 input FT inStartValue;
2588 output FT outResult = inStartValue;
2589
2590 partial function FoldFunc
2591 input T inElement;
2592 input ArgT1 inArg;
2593 input FT inFoldArg;
2594 output FT outFoldArg;
2595 end FoldFunc;
2596 algorithm
2597
2/2
✓ Branch 0 taken 1985246 times.
✓ Branch 1 taken 707544 times.
2692790 for e in inList loop
2598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1985246 times.
1985246 outResult := inFoldFunc(e, inExtraArg, outResult);
2599 end for;
2600 end fold1;
2601
2602 public function fold1r<T, FT, ArgT1>
2603 "Same as fold1, but with reversed order on the fold function arguments."
2604 input list<T> inList;
2605 input FoldFunc inFoldFunc;
2606 input ArgT1 inExtraArg;
2607 input FT inStartValue;
2608 output FT outResult = inStartValue;
2609
2610 partial function FoldFunc
2611 input FT inFoldArg;
2612 input T inElement;
2613 input ArgT1 inArg;
2614 output FT outFoldArg;
2615 end FoldFunc;
2616 algorithm
2617
2/2
✓ Branch 0 taken 537396 times.
✓ Branch 1 taken 125212 times.
662608 for e in inList loop
2618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 537396 times.
537396 outResult := inFoldFunc(outResult, e, inExtraArg);
2619 end for;
2620 end fold1r;
2621
2622 public function fold2<T, FT, ArgT1, ArgT2>
2623 "Takes a list and a function operating on list elements having an extra
2624 argument that is 'updated', thus returned from the function, and two constant
2625 arguments that is not updated. fold will call the function for each element in
2626 a sequence, updating the start value."
2627 input list<T> inList;
2628 input FoldFunc inFoldFunc;
2629 input ArgT1 inExtraArg1;
2630 input ArgT2 inExtraArg2;
2631 input FT inStartValue;
2632 output FT outResult = inStartValue;
2633
2634 partial function FoldFunc
2635 input T inElement;
2636 input ArgT1 inArg1;
2637 input ArgT2 inArg2;
2638 input FT inFoldArg;
2639 output FT outFoldArg;
2640 end FoldFunc;
2641 algorithm
2642
2/2
✓ Branch 0 taken 1917125 times.
✓ Branch 1 taken 1849856 times.
3766981 for e in inList loop
2643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1917125 times.
1917125 outResult := inFoldFunc(e, inExtraArg1, inExtraArg2, outResult);
2644 end for;
2645 end fold2;
2646
2647 public function fold22<T, FT1, FT2, ArgT1, ArgT2>
2648 "Takes a list and a function operating on list elements having three extra
2649 arguments that is 'updated', thus returned from the function, and three constant
2650 arguments that are not updated. fold will call the function for each element in
2651 a sequence, updating the start values."
2652 input list<T> inList;
2653 input FoldFunc inFoldFunc;
2654 input ArgT1 inExtraArg1;
2655 input ArgT2 inExtraArg2;
2656 input FT1 inStartValue1;
2657 input FT2 inStartValue2;
2658 output FT1 outResult1 = inStartValue1;
2659 output FT2 outResult2 = inStartValue2;
2660
2661 partial function FoldFunc
2662 input T inElement;
2663 input ArgT1 inConstantArg1;
2664 input ArgT2 inConstantArg2;
2665 input FT1 inFoldArg1;
2666 input FT2 inFoldArg2;
2667 output FT1 outFoldArg1;
2668 output FT2 outFoldArg2;
2669 end FoldFunc;
2670 algorithm
2671
2/2
✓ Branch 0 taken 9222463 times.
✓ Branch 1 taken 6146382 times.
15368845 for e in inList loop
2672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9222463 times.
9222463 (outResult1, outResult2) := inFoldFunc(e, inExtraArg1, inExtraArg2, outResult1, outResult2);
2673 end for;
2674 end fold22;
2675
2676 public function foldList<T, FT>
2677 input list<list<T>> inList;
2678 input FoldFunc inFoldFunc;
2679 input FT inStartValue;
2680 output FT outResult = inStartValue;
2681
2682 partial function FoldFunc
2683 input T inElement;
2684 input FT inFoldArg;
2685 output FT outFoldArg;
2686 end FoldFunc;
2687 algorithm
2688
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 43 times.
105 for lst in inList loop
2689
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 62 times.
205 for e in lst loop
2690
1/2
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
143 outResult := inFoldFunc(e, outResult);
2691 end for;
2692 end for;
2693 end foldList;
2694
2695 public function fold2r<T, FT, ArgT1, ArgT2>
2696 "Same as fold2, but with reversed order on the fold function arguments."
2697 input list<T> inList;
2698 input FoldFunc inFoldFunc;
2699 input ArgT1 inExtraArg1;
2700 input ArgT2 inExtraArg2;
2701 input FT inStartValue;
2702 output FT outResult = inStartValue;
2703
2704 partial function FoldFunc
2705 input FT inFoldArg;
2706 input T inElement;
2707 input ArgT1 inArg1;
2708 input ArgT2 inArg2;
2709 output FT outFoldArg;
2710 end FoldFunc;
2711 algorithm
2712
2/2
✓ Branch 0 taken 183181 times.
✓ Branch 1 taken 12897 times.
196078 for e in inList loop
2713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183181 times.
183181 outResult := inFoldFunc(outResult, e, inExtraArg1, inExtraArg2);
2714 end for;
2715 end fold2r;
2716
2717 public function fold3<T, FT, ArgT1, ArgT2, ArgT3>
2718 "Takes a list and a function operating on list elements having an extra
2719 argument that is 'updated', thus returned from the function, and three constant
2720 arguments that is not updated. fold will call the function for each element in
2721 a sequence, updating the start value."
2722 input list<T> inList;
2723 input FoldFunc inFoldFunc;
2724 input ArgT1 inExtraArg1;
2725 input ArgT2 inExtraArg2;
2726 input ArgT3 inExtraArg3;
2727 input FT inStartValue;
2728 output FT outResult = inStartValue;
2729
2730 partial function FoldFunc
2731 input T inElement;
2732 input ArgT1 inArg1;
2733 input ArgT2 inArg2;
2734 input ArgT3 inArg3;
2735 input FT inFoldArg;
2736 output FT outFoldArg;
2737 end FoldFunc;
2738 algorithm
2739
2/2
✓ Branch 0 taken 40994 times.
✓ Branch 1 taken 5566 times.
46560 for e in inList loop
2740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40994 times.
40994 outResult := inFoldFunc(e, inExtraArg1, inExtraArg2, inExtraArg3, outResult);
2741 end for;
2742 end fold3;
2743
2744 public function fold4<T, FT, ArgT1, ArgT2, ArgT3, ArgT4>
2745 "Takes a list and a function operating on list elements having an extra
2746 argument that is 'updated', thus returned from the function, and four constant
2747 arguments that is not updated. fold will call the function for each element in
2748 a sequence, updating the start value."
2749 input list<T> inList;
2750 input FoldFunc inFoldFunc;
2751 input ArgT1 inExtraArg1;
2752 input ArgT2 inExtraArg2;
2753 input ArgT3 inExtraArg3;
2754 input ArgT4 inExtraArg4;
2755 input FT inStartValue;
2756 output FT outResult = inStartValue;
2757
2758 partial function FoldFunc
2759 input T inElement;
2760 input ArgT1 inArg1;
2761 input ArgT2 inArg2;
2762 input ArgT3 inArg3;
2763 input ArgT4 inArg4;
2764 input FT inFoldArg;
2765 output FT outFoldArg;
2766 end FoldFunc;
2767 algorithm
2768
2/2
✓ Branch 0 taken 1549308 times.
✓ Branch 1 taken 192004 times.
1741312 for e in inList loop
2769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1549308 times.
1549308 outResult := inFoldFunc(e, inExtraArg1, inExtraArg2, inExtraArg3,
2770 inExtraArg4, outResult);
2771 end for;
2772 end fold4;
2773
2774 public function fold20<T, FT1, FT2>
2775 "Takes a list and a function operating on list elements having two extra
2776 arguments that are 'updated', thus returned from the function. fold will call
2777 the function for each element in a sequence, updating the start value."
2778 input list<T> inList;
2779 input FoldFunc inFoldFunc;
2780 input FT1 inStartValue1;
2781 input FT2 inStartValue2;
2782 output FT1 outResult1 = inStartValue1;
2783 output FT2 outResult2 = inStartValue2;
2784
2785 partial function FoldFunc
2786 input T inElement;
2787 input FT1 inFoldArg1;
2788 input FT2 inFoldArg2;
2789 output FT1 outFoldArg1;
2790 output FT2 outFoldArg2;
2791 end FoldFunc;
2792 algorithm
2793
2/2
✓ Branch 0 taken 4456 times.
✓ Branch 1 taken 4456 times.
8912 for e in inList loop
2794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4456 times.
4456 (outResult1, outResult2) := inFoldFunc(e, outResult1, outResult2);
2795 end for;
2796 end fold20;
2797
2798 public function fold21<T, FT1, FT2, ArgT1>
2799 "Takes a list and a function operating on list elements having two extra
2800 argument that are 'updated', thus returned from the function, and one constant
2801 argument that is not updated. fold will call the function for each element in
2802 a sequence, updating the start value."
2803 input list<T> inList;
2804 input FoldFunc inFoldFunc;
2805 input ArgT1 inExtraArg1;
2806 input FT1 inStartValue1;
2807 input FT2 inStartValue2;
2808 output FT1 outResult1 = inStartValue1;
2809 output FT2 outResult2 = inStartValue2;
2810
2811 partial function FoldFunc
2812 input T inElement;
2813 input ArgT1 inExtraArg1;
2814 input FT1 inFoldArg1;
2815 input FT2 inFoldArg2;
2816 output FT1 outFoldArg1;
2817 output FT2 outFoldArg2;
2818 end FoldFunc;
2819 algorithm
2820
2/2
✓ Branch 0 taken 5606 times.
✓ Branch 1 taken 136 times.
5742 for e in inList loop
2821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5606 times.
5606 (outResult1, outResult2) := inFoldFunc(e, inExtraArg1, outResult1,outResult2);
2822 end for;
2823 end fold21;
2824
2825 public function fold31<T, FT1, FT2, FT3, ArgT1>
2826 "Takes a list and a function operating on list elements having three extra
2827 argument that are 'updated', thus returned from the function, and one constant
2828 argument that is not updated. fold will call the function for each element in
2829 a sequence, updating the start value."
2830 input list<T> inList;
2831 input FoldFunc inFoldFunc;
2832 input ArgT1 inExtraArg1;
2833 input FT1 inStartValue1;
2834 input FT2 inStartValue2;
2835 input FT3 inStartValue3;
2836 output FT1 outResult1 = inStartValue1;
2837 output FT2 outResult2 = inStartValue2;
2838 output FT3 outResult3 = inStartValue3;
2839
2840 partial function FoldFunc
2841 input T inElement;
2842 input ArgT1 inExtraArg1;
2843 input output FT1 inFoldArg1;
2844 input output FT2 inFoldArg2;
2845 input output FT3 inFoldArg3;
2846 end FoldFunc;
2847 algorithm
2848
2/2
✓ Branch 0 taken 161804 times.
✓ Branch 1 taken 2757 times.
164561 for e in inList loop
2849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 161804 times.
161804 (outResult1, outResult2, outResult3) := inFoldFunc(e, inExtraArg1, outResult1, outResult2, outResult3);
2850 end for;
2851 end fold31;
2852
2853 public function mapFold<TI, TO, FT>
2854 "Takes a list, an extra argument and a function. The function will be applied
2855 to each element in the list, and the extra argument will be passed to the
2856 function and updated."
2857 input list<TI> inList;
2858 input FuncType inFunc;
2859 input FT inArg;
2860 output list<TO> outList = {};
2861 output FT outArg = inArg;
2862
2863 partial function FuncType
2864 input TI inElem;
2865 input FT inArg;
2866 output TO outResult;
2867 output FT outArg;
2868 end FuncType;
2869 protected
2870 TO res;
2871 algorithm
2872
2/2
✓ Branch 0 taken 3885113 times.
✓ Branch 1 taken 3307387 times.
7192500 for e in inList loop
2873
2/2
✓ Branch 0 taken 1642290 times.
✓ Branch 1 taken 2242823 times.
3885113 (res, outArg) := inFunc(e, outArg);
2874 outList := res :: outList;
2875 end for;
2876 3307387 outList := listReverseInPlace(outList);
2877 end mapFold;
2878
2879 public function mapFold2<TI, TO, FT1, FT2>
2880 "Takes a list, a function, and two extra arguments. The function will be applied
2881 to each element in the list, and the extra arguments will be passed to the
2882 function and updated."
2883 input list<TI> inList;
2884 input FuncType inFunc;
2885 input FT1 inArg1;
2886 input FT2 inArg2;
2887 output list<TO> outList = {};
2888 output FT1 outArg1 = inArg1;
2889 output FT2 outArg2 = inArg2;
2890
2891 partial function FuncType
2892 input TI inElem;
2893 input FT1 inArg1;
2894 input FT2 inArg2;
2895 output TO outResult;
2896 output FT1 outArg1;
2897 output FT2 outArg2;
2898 end FuncType;
2899 protected
2900 TO res;
2901 algorithm
2902
2/2
✓ Branch 0 taken 183594 times.
✓ Branch 1 taken 23925 times.
207519 for e in inList loop
2903
2/2
✓ Branch 0 taken 101614 times.
✓ Branch 1 taken 81980 times.
183594 (res, outArg1, outArg2) := inFunc(e, outArg1, outArg2);
2904 outList := res::outList;
2905 end for;
2906 23925 outList := listReverseInPlace(outList);
2907 end mapFold2;
2908
2909 public function mapFold3<TI, TO, FT1, FT2, FT3>
2910 "Takes a list, a function, and three extra arguments. The function will be applied
2911 to each element in the list, and the extra arguments will be passed to the
2912 function and updated."
2913 input list<TI> inList;
2914 input FuncType inFunc;
2915 output list<TO> outList = {};
2916 input output FT1 inArg1;
2917 input output FT2 inArg2;
2918 input output FT3 inArg3;
2919
2920 partial function FuncType
2921 input TI inElem;
2922 output TO outResult;
2923 input output FT1 inArg1;
2924 input output FT2 inArg2;
2925 input output FT3 inArg3;
2926 end FuncType;
2927 protected
2928 TO res;
2929 algorithm
2930
2/2
✓ Branch 0 taken 23096 times.
✓ Branch 1 taken 19380 times.
42476 for e in inList loop
2931
1/2
✓ Branch 0 taken 23096 times.
✗ Branch 1 not taken.
23096 (res, inArg1, inArg2, inArg3) := inFunc(e, inArg1, inArg2, inArg3);
2932 outList := res::outList;
2933 end for;
2934 19380 outList := listReverseInPlace(outList);
2935 end mapFold3;
2936
2937 public function mapFold5<TI, TO, FT1, FT2, FT3, FT4, FT5>
2938 "Takes a list, a function, and five extra arguments. The function will be applied
2939 to each element in the list, and the extra arguments will be passed to the
2940 function and updated."
2941 input list<TI> inList;
2942 input FuncType inFunc;
2943 output list<TO> outList = {};
2944 input output FT1 inArg1;
2945 input output FT2 inArg2;
2946 input output FT3 inArg3;
2947 input output FT4 inArg4;
2948 input output FT5 inArg5;
2949
2950 partial function FuncType
2951 input TI inElem;
2952 output TO outResult;
2953 input output FT1 inArg1;
2954 input output FT2 inArg2;
2955 input output FT3 inArg3;
2956 input output FT4 inArg4;
2957 input output FT5 inArg5;
2958 end FuncType;
2959 protected
2960 TO res;
2961 algorithm
2962
2/2
✓ Branch 0 taken 65352 times.
✓ Branch 1 taken 3336 times.
68688 for e in inList loop
2963
1/2
✓ Branch 0 taken 65352 times.
✗ Branch 1 not taken.
65352 (res, inArg1, inArg2, inArg3, inArg4, inArg5) := inFunc(e, inArg1, inArg2, inArg3, inArg4, inArg5);
2964 outList := res::outList;
2965 end for;
2966 3336 outList := listReverseInPlace(outList);
2967 end mapFold5;
2968
2969 public function map1Fold<TI, TO, FT, ArgT1>
2970 "Takes a list, an extra argument, an extra constant argument, and a function.
2971 The function will be applied to each element in the list, and the extra
2972 argument will be passed to the function and updated."
2973 input list<TI> inList;
2974 input FuncType inFunc;
2975 input ArgT1 inConstArg;
2976 input FT inArg;
2977 output list<TO> outList = {};
2978 output FT outArg = inArg;
2979
2980 partial function FuncType
2981 input TI inElem;
2982 input ArgT1 inConstArg;
2983 input FT inArg;
2984 output TO outResult;
2985 output FT outArg;
2986 end FuncType;
2987 protected
2988 TO res;
2989 algorithm
2990
2/2
✓ Branch 0 taken 822983 times.
✓ Branch 1 taken 2942256 times.
3765239 for e in inList loop
2991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 822983 times.
822983 (res, outArg) := inFunc(e, inConstArg, outArg);
2992 outList := res :: outList;
2993 end for;
2994 2942256 outList := listReverseInPlace(outList);
2995 end map1Fold;
2996
2997 public function map2Fold<TI, TO, FT, ArgT1, ArgT2>
2998 "Takes a list, two extra constant arguments, an extra argument, and a function.
2999 The function will be applied to each element in the list, and the extra
3000 argument will be passed to the function and updated."
3001 input list<TI> inList;
3002 input FuncType inFunc;
3003 input ArgT1 inConstArg;
3004 input ArgT2 inConstArg2;
3005 input FT inArg;
3006 input list<TO> inAccum = {};
3007 output list<TO> outList = inAccum;
3008 output FT outArg = inArg;
3009
3010 partial function FuncType
3011 input TI inElem;
3012 input ArgT1 inConstArg;
3013 input ArgT2 inConstArg2;
3014 input FT inArg;
3015 output TO outResult;
3016 output FT outArg;
3017 end FuncType;
3018 protected
3019 TO res;
3020 algorithm
3021
2/2
✓ Branch 0 taken 1061696 times.
✓ Branch 1 taken 290619 times.
1352315 for e in inList loop
3022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1061696 times.
1061696 (res, outArg) := inFunc(e, inConstArg, inConstArg2, outArg);
3023 outList := res :: outList;
3024 end for;
3025 290619 outList := listReverseInPlace(outList);
3026 end map2Fold;
3027
3028 public function map2FoldCheckReferenceEq<TIO, FT, ArgT1, ArgT2>
3029 "Takes a list, two extra constant arguments, an extra argument, and a function.
3030 The function will be applied to each element in the list, and the extra
3031 argument will be passed to the function and updated."
3032 input list<TIO> inList;
3033 input FuncType inFunc;
3034 input ArgT1 inConstArg;
3035 input ArgT2 inConstArg2;
3036 input FT inArg;
3037 output list<TIO> outList;
3038 output FT outArg = inArg;
3039
3040 partial function FuncType
3041 input TIO inElem;
3042 input ArgT1 inConstArg;
3043 input ArgT2 inConstArg2;
3044 input FT inArg;
3045 output TIO outResult;
3046 output FT outArg;
3047 end FuncType;
3048 protected
3049 TIO res, savedElt;
3050 DoubleEnded.MutableList<TIO> delst;
3051 Integer n=0;
3052 algorithm
3053
2/2
✓ Branch 0 taken 1197697 times.
✓ Branch 1 taken 2201823 times.
3399520 for e in inList loop
3054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1197697 times.
1197697 (res, outArg) := inFunc(e, inConstArg, inConstArg2, outArg);
3055 // Preserve reference equality without any allocation if nothing changed
3056
2/2
✓ Branch 0 taken 85967 times.
✓ Branch 1 taken 1111730 times.
1197697 if not referenceEq(e, res) then
3057 savedElt := res;
3058 85967 delst := DoubleEnded.empty(res);
3059
2/2
✓ Branch 0 taken 119091 times.
✓ Branch 1 taken 85967 times.
205058 for elt in inList loop
3060
2/2
✓ Branch 0 taken 29760 times.
✓ Branch 1 taken 89331 times.
119091 if n < 0 then
3061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29760 times.
29760 (res, outArg) := inFunc(elt, inConstArg, inConstArg2, outArg);
3062 else
3063
2/2
✓ Branch 0 taken 3364 times.
✓ Branch 1 taken 85967 times.
89331 res := if n == 0 then savedElt else elt;
3064 end if;
3065 119091 DoubleEnded.push_back(delst, res);
3066 119091 n := n-1;
3067 end for;
3068 85967 outList := DoubleEnded.toListAndClear(delst);
3069 85967 return;
3070 end if;
3071 1111730 n := n + 1;
3072 end for;
3073 outList := inList;
3074 end map2FoldCheckReferenceEq;
3075
3076 public function map3Fold<TI, TO, FT, ArgT1, ArgT2, ArgT3>
3077 "Takes a list, three extra constant arguments, an extra argument, and a function.
3078 The function will be applied to each element in the list, and the extra
3079 argument will be passed to the function and updated."
3080 input list<TI> inList;
3081 input FuncType inFunc;
3082 input ArgT1 inConstArg;
3083 input ArgT2 inConstArg2;
3084 input ArgT3 inConstArg3;
3085 input FT inArg;
3086 output list<TO> outList = {};
3087 output FT outArg = inArg;
3088
3089 partial function FuncType
3090 input TI inElem;
3091 input ArgT1 inConstArg;
3092 input ArgT2 inConstArg2;
3093 input ArgT3 inConstArg3;
3094 input FT inArg;
3095 output TO outResult;
3096 output FT outArg;
3097 end FuncType;
3098 protected
3099 TO res;
3100 algorithm
3101
2/2
✓ Branch 0 taken 1544643 times.
✓ Branch 1 taken 211440 times.
1756083 for e in inList loop
3102
2/2
✓ Branch 0 taken 51659 times.
✓ Branch 1 taken 1492984 times.
1544643 (res, outArg) := inFunc(e, inConstArg, inConstArg2, inConstArg3, outArg);
3103 outList := res :: outList;
3104 end for;
3105 211440 outList := listReverseInPlace(outList);
3106 end map3Fold;
3107
3108 public function mapFoldList<TI, TO, FT>
3109 "Takes a list of lists, an extra argument, and a function. The function will
3110 be applied to each element in the list, and the extra argument will be passed
3111 to the function and updated for each element."
3112 input list<list<TI>> inListList;
3113 input FuncType inFunc;
3114 input FT inArg;
3115 output list<list<TO>> outListList = {};
3116 output FT outArg = inArg;
3117
3118 partial function FuncType
3119 input TI inElem;
3120 input FT inArg;
3121 output TO outResult;
3122 output FT outArg;
3123 end FuncType;
3124 protected
3125 list<TO> res;
3126 algorithm
3127
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for lst in inListList loop
3128 32 (res, outArg) := mapFold(lst, inFunc, outArg);
3129 outListList := res :: outListList;
3130 end for;
3131 8 outListList := listReverseInPlace(outListList);
3132 end mapFoldList;
3133
3134 public function reduce<T>
3135 "Takes a list and a function operating on two elements of the list.
3136 The function performs a reduction of the list to a single value using the
3137 function. Example:
3138 reduce({1, 2, 3}, intAdd) => 6"
3139 input list<T> inList;
3140 input ReduceFunc inReduceFunc;
3141 output T outResult;
3142
3143 partial function ReduceFunc
3144 input T inElement1;
3145 input T inElement2;
3146 output T outElement;
3147 end ReduceFunc;
3148 protected
3149 list<T> rest;
3150 algorithm
3151
2/2
✓ Branch 0 taken 2291 times.
✓ Branch 1 taken 1105363 times.
1107654 outResult :: rest := inList;
3152
2/2
✓ Branch 0 taken 1841292 times.
✓ Branch 1 taken 1105358 times.
2946650 for e in rest loop
3153
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1841286 times.
1841292 outResult := inReduceFunc(outResult, e);
3154 end for;
3155 end reduce;
3156
3157 public function flatten<T>
3158 "Takes a list of lists and flattens it out, producing one list of all elements
3159 of the sublists. O(len(outList))
3160 Example: flatten({{1, 2}, {3, 4, 5}, {6}, {}}) => {1, 2, 3, 4, 5, 6}"
3161 input list<list<T>> inList;
3162 output list<T> outList = if listEmpty(inList) then {} elseif hasOneElement(inList) then listHead(inList) else listAppend(lst for lst in listReverse(inList));
3163 end flatten;
3164
3165 public function flattenReverse<T>
3166 input list<list<T>> inList;
3167 output list<T> outList = if listEmpty(inList) then {} elseif hasOneElement(inList) then listHead(inList) else listAppend(lst for lst in inList);
3168 end flattenReverse;
3169
3170 public function thread<T>
3171 "Takes two lists of the same type and threads (interleaves) them together.
3172 Example: thread({1, 2, 3}, {4, 5, 6}) => {4, 1, 5, 2, 6, 3}"
3173 input list<T> inList1;
3174 input list<T> inList2;
3175 input list<T> inAccum = {};
3176 output list<T> outList = {};
3177 protected
3178 T e2;
3179 list<T> rest_e2 = inList2;
3180 algorithm
3181
2/2
✓ Branch 0 taken 8302 times.
✓ Branch 1 taken 6054 times.
14356 for e1 in inList1 loop
3182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8302 times.
8302 e2 :: rest_e2 := rest_e2;
3183
3184 outList := e1 :: e2 :: outList;
3185 end for;
3186
3187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6054 times.
6054 true := listEmpty(rest_e2);
3188 6054 outList := listReverseInPlace(outList);
3189 end thread;
3190
3191 public function zip<T1, T2>
3192 "Takes two lists and zips the arguments together into a list of tuples
3193 consisting of the two element types.
3194 Example: zip({1, 2, 3}, {true, false, true}) =>
3195 {(1, true), (2, false), (3, true)}"
3196 input list<T1> inList1;
3197 input list<T2> inList2;
3198 output list<tuple<T1, T2>> outTuples;
3199 algorithm
3200
7/8
✓ Branch 0 taken 2159854 times.
✓ Branch 1 taken 539227 times.
✓ Branch 2 taken 2159854 times.
✓ Branch 3 taken 539227 times.
✓ Branch 4 taken 2159854 times.
✓ Branch 5 taken 539227 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 539227 times.
2699081 outTuples := list((e1, e2) threaded for e1 in inList1, e2 in inList2);
3201 end zip;
3202
3203 public function zip3<T1, T2, T3>
3204 "Takes three lists and zips the arguments together into a list of tuples
3205 consisting of the three element types.
3206 Example: zip3({1, 2, 3}, {true, false, true}, {4.0, 5.0, 6.0}) =>
3207 {(1, true, 4.0), (2, false, 5.0), (3, true, 6.0)}"
3208 input list<T1> l1;
3209 input list<T2> l2;
3210 input list<T3> l3;
3211 output list<tuple<T1, T2, T3>> res;
3212 algorithm
3213
9/10
✓ Branch 0 taken 4700 times.
✓ Branch 1 taken 26953 times.
✓ Branch 2 taken 4700 times.
✓ Branch 3 taken 26953 times.
✓ Branch 4 taken 4700 times.
✓ Branch 5 taken 26953 times.
✓ Branch 6 taken 4700 times.
✓ Branch 7 taken 26953 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 26953 times.
31653 res := list((e1, e2, e3) threaded for e1 in l1, e2 in l2, e3 in l3);
3214 end zip3;
3215
3216 public function unzip<T1, T2>
3217 "Takes a list of two-element tuples and splits the tuples into two separate
3218 lists. Example: unzip({(1, 2), (3, 4)}) => ({1, 3}, {2, 4})"
3219 input list<tuple<T1, T2>> inTuples;
3220 output list<T1> outList1 = {};
3221 output list<T2> outList2 = {};
3222 protected
3223 T1 e1;
3224 T2 e2;
3225 algorithm
3226
2/2
✓ Branch 0 taken 6226 times.
✓ Branch 1 taken 2086 times.
8312 for tpl in inTuples loop
3227 6226 (e1, e2) := tpl;
3228 outList1 := e1 :: outList1;
3229
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 6051 times.
6226 if isPresent(outList2) then
3230 outList2 := e2 :: outList2;
3231 end if;
3232 end for;
3233 2086 outList1 := listReverseInPlace(outList1);
3234 2086 outList2 := listReverseInPlace(outList2);
3235 end unzip;
3236
3237 public function unzip3<T1, T2, T3>
3238 "Takes a list of three-element tuples and splits them into separate lists."
3239 input list<tuple<T1, T2, T3>> tuples;
3240 output list<T1> l1 = {};
3241 output list<T2> l2 = {};
3242 output list<T3> l3 = {};
3243 protected
3244 T1 e1;
3245 T2 e2;
3246 T3 e3;
3247 algorithm
3248
2/2
✓ Branch 1 taken 984 times.
✓ Branch 2 taken 679 times.
1663 for t in listReverse(tuples) loop
3249 984 (e1, e2, e3) := t;
3250 l1 := e1 :: l1;
3251 l2 := e2 :: l2;
3252 l3 := e3 :: l3;
3253 end for;
3254 end unzip3;
3255
3256 public function unzipSecond<T1, T2>
3257 "Takes a list of two-element tuples and creates a list from the second element
3258 of each tuple. Example: unzipSecond({(1, 2), (3, 4)}) => {2, 4}"
3259 input list<tuple<T1, T2>> inTuples;
3260 output list<T2> outList = {};
3261 protected
3262 T2 e;
3263 algorithm
3264
2/2
✓ Branch 0 taken 71466 times.
✓ Branch 1 taken 7143 times.
78609 for tpl in inTuples loop
3265 71466 (_, e) := tpl;
3266 outList := e :: outList;
3267 end for;
3268 7143 outList := listReverseInPlace(outList);
3269 end unzipSecond;
3270
3271 public function threadMap<T1, T2, TO>
3272 "Takes two lists and a function and threads (interleaves) and maps the
3273 elements of two lists, creating a new list.
3274 Example: threadMap({1, 2}, {3, 4}, intAdd) => {1+3, 2+4}"
3275 input list<T1> inList1;
3276 input list<T2> inList2;
3277 input MapFunc inMapFunc;
3278 output list<TO> outList;
3279
3280 partial function MapFunc
3281 input T1 inElement1;
3282 input T2 inElement2;
3283 output TO outElement;
3284 end MapFunc;
3285 algorithm
3286
9/10
✓ Branch 0 taken 1737141 times.
✓ Branch 1 taken 1264193 times.
✓ Branch 2 taken 1737141 times.
✓ Branch 3 taken 1264193 times.
✓ Branch 4 taken 1737141 times.
✓ Branch 5 taken 1264193 times.
✓ Branch 6 taken 504 times.
✓ Branch 7 taken 1736637 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1264193 times.
3001334 outList := list(inMapFunc(e1, e2) threaded for e1 in inList1, e2 in inList2);
3287 end threadMap;
3288
3289 public function threadMap_2<T1, T2, TO1, TO2>
3290 "Like threadMap, but returns two lists instead of one."
3291 input list<T1> inList1;
3292 input list<T2> inList2;
3293 input MapFunc inMapFunc;
3294 output list<TO1> outList1 = {};
3295 output list<TO2> outList2 = {};
3296
3297 partial function MapFunc
3298 input T1 inElement1;
3299 input T2 inElement2;
3300 output TO1 outElement1;
3301 output TO2 outElement2;
3302 end MapFunc;
3303 protected
3304 T2 e2;
3305 list<T2> rest_e2 = inList2;
3306 TO1 ret1;
3307 TO2 ret2;
3308 algorithm
3309
2/2
✓ Branch 0 taken 2749 times.
✓ Branch 1 taken 1084 times.
3833 for e1 in inList1 loop
3310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2749 times.
2749 e2 :: rest_e2 := rest_e2;
3311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2749 times.
2749 (ret1, ret2) := inMapFunc(e1, e2);
3312 outList1 := ret1 :: outList1;
3313 2749 outList2 := ret2 :: outList2;
3314 end for;
3315
3316 1084 outList1 := listReverseInPlace(outList1);
3317 1084 outList2 := listReverseInPlace(outList2);
3318 end threadMap_2;
3319
3320 public function threadMapList<T1, T2, TO>
3321 "Takes two lists of lists and a function and threads (interleaves) and maps
3322 the elements of the two lists, creating a new list.
3323 Example: threadMapList({{1, 2}}, {{3, 4}}, intAdd) => {{1 + 3, 2 + 4}}"
3324 input list<list<T1>> inList1;
3325 input list<list<T2>> inList2;
3326 input MapFunc inMapFunc;
3327 output list<list<TO>> outList;
3328
3329 partial function MapFunc
3330 input T1 inElement1;
3331 input T2 inElement2;
3332 output TO outElement;
3333 end MapFunc;
3334 algorithm
3335 ✗ outList := list(threadMap(lst1, lst2, inMapFunc) threaded for lst1 in inList1,
3336 lst2 in inList2);
3337 end threadMapList;
3338
3339 public function threadMapList_2<T1, T2, TO1, TO2>
3340 "Like threadMapList, but returns two lists instead of one."
3341 input list<list<T1>> inList1;
3342 input list<list<T2>> inList2;
3343 input MapFunc inMapFunc;
3344 output list<list<TO1>> outList1 = {};
3345 output list<list<TO2>> outList2 = {};
3346
3347 partial function MapFunc
3348 input T1 inElement1;
3349 input T2 inElement2;
3350 output TO1 outElement1;
3351 output TO2 outElement2;
3352 end MapFunc;
3353 protected
3354 list<T2> l2;
3355 list<list<T2>> rest_l2 = inList2;
3356 list<TO1> ret1;
3357 list<TO2> ret2;
3358 algorithm
3359
2/2
✓ Branch 0 taken 1084 times.
✓ Branch 1 taken 437 times.
1521 for l1 in inList1 loop
3360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1084 times.
1084 l2 :: rest_l2 := rest_l2;
3361 1084 (ret1, ret2) := threadMap_2(l1, l2, inMapFunc);
3362 outList1 := ret1 :: outList1;
3363 1084 outList2 := ret2 :: outList2;
3364 end for;
3365
3366 437 outList1 := listReverseInPlace(outList1);
3367 437 outList2 := listReverseInPlace(outList2);
3368 end threadMapList_2;
3369
3370 public function threadMap1<T1, T2, TO, ArgT1>
3371 "Takes two lists and a function and threads (interleaves) and maps the
3372 elements of two lists, creating a new list. This function also takes an
3373 extra arguments that are passed to the mapping function."
3374 input list<T1> inList1;
3375 input list<T2> inList2;
3376 input MapFunc inMapFunc;
3377 input ArgT1 inArg1;
3378 output list<TO> outList;
3379
3380 partial function MapFunc
3381 input T1 inElement1;
3382 input T2 inElement2;
3383 input ArgT1 inArg1;
3384 output TO outElement;
3385 end MapFunc;
3386 algorithm
3387
8/10
✓ Branch 0 taken 16567 times.
✓ Branch 1 taken 5791 times.
✓ Branch 2 taken 16567 times.
✓ Branch 3 taken 5791 times.
✓ Branch 4 taken 16567 times.
✓ Branch 5 taken 5791 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16567 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5791 times.
22358 outList := list(inMapFunc(e1, e2, inArg1) threaded for e1 in inList1, e2 in inList2);
3388 end threadMap1;
3389
3390 public function threadMap1_0<T1, T2, ArgT1>
3391 "Takes two lists and a function, and applies the function to each element of
3392 the lists in a pairwise fashion. This function also takes an extra argument
3393 which is passed to the mapping function, but returns no result."
3394 input list<T1> inList1;
3395 input list<T2> inList2;
3396 input MapFunc inMapFunc;
3397 input ArgT1 inArg1;
3398
3399 partial function MapFunc
3400 input T1 inElement1;
3401 input T2 inElement2;
3402 input ArgT1 inArg1;
3403 end MapFunc;
3404 protected
3405 list<T2> rest2 = inList2;
3406 T2 e2;
3407 algorithm
3408
2/2
✓ Branch 0 taken 28196 times.
✓ Branch 1 taken 16678 times.
44874 for e1 in inList1 loop
3409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28196 times.
28196 e2 :: rest2 := rest2;
3410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28196 times.
28196 inMapFunc(e1, e2, inArg1);
3411 end for;
3412
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16678 times.
16678 true := listEmpty(rest2);
3414 end threadMap1_0;
3415
3416 public function threadMap2<T1, T2, TO, ArgT1, ArgT2>
3417 "Takes two lists and a function and threads (interleaves) and maps the
3418 elements of two lists, creating a new list. This function also takes two
3419 extra arguments that are passed to the mapping function."
3420 input list<T1> inList1;
3421 input list<T2> inList2;
3422 input MapFunc inMapFunc;
3423 input ArgT1 inArg1;
3424 input ArgT2 inArg2;
3425 output list<TO> outList;
3426
3427 partial function MapFunc
3428 input T1 inElement1;
3429 input T2 inElement2;
3430 input ArgT1 inArg1;
3431 input ArgT2 inArg2;
3432 output TO outElement;
3433 end MapFunc;
3434 algorithm
3435
8/10
✓ Branch 0 taken 358 times.
✓ Branch 1 taken 1106 times.
✓ Branch 2 taken 358 times.
✓ Branch 3 taken 1106 times.
✓ Branch 4 taken 358 times.
✓ Branch 5 taken 1106 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 358 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1106 times.
1464 outList := list(inMapFunc(e1, e2, inArg1, inArg2) threaded for e1 in inList1, e2 in inList2);
3436 end threadMap2;
3437
3438 public function thread3Map<T1, T2, T3, TO>
3439 "Takes three lists and a function, and threads (interleaves) and maps the
3440 elements of the three lists, creating a new list.
3441 Example: thread3Map({1, 2}, {3, 4}, {5, 6}, intAdd3) => {1+3+5, 2+4+6}"
3442 input list<T1> inList1;
3443 input list<T2> inList2;
3444 input list<T3> inList3;
3445 input MapFunc inFunc;
3446 output list<TO> outList;
3447
3448 partial function MapFunc
3449 input T1 inElement1;
3450 input T2 inElement2;
3451 input T3 inElement3;
3452 output TO outElement;
3453 end MapFunc;
3454 algorithm
3455 ✗ outList := list(inFunc(e1, e2, e3) threaded for e1 in inList1, e2 in inList2, e3 in inList3);
3456 end thread3Map;
3457
3458 public function thread3MapFold<T1, T2, T3, TO, ArgT1>
3459 "Takes three lists and a function, and threads (interleaves) and maps the
3460 elements of the three lists, creating a new list. This function also takes
3461 one extra argument which are passed to the mapping function and fold."
3462 input list<T1> inList1;
3463 input list<T2> inList2;
3464 input list<T3> inList3;
3465 input MapFunc inFunc;
3466 input ArgT1 inArg;
3467 output list<TO> outList = {};
3468 output ArgT1 outArg = inArg;
3469
3470 partial function MapFunc
3471 input T1 inElement1;
3472 input T2 inElement2;
3473 input T3 inElement3;
3474 input ArgT1 inArg;
3475 output TO outElement;
3476 output ArgT1 outArg;
3477 end MapFunc;
3478 protected
3479 T2 e2;
3480 list<T2> rest_e2 = inList2;
3481 T3 e3;
3482 list<T3> rest_e3 = inList3;
3483 TO res;
3484 algorithm
3485 ✗ for e1 in inList1 loop
3486 ✗ e2 :: rest_e2 := rest_e2;
3487 ✗ e3 :: rest_e3 := rest_e3;
3488 ✗ (res, outArg) := inFunc(e1, e2, e3, outArg);
3489 outList := res :: outList;
3490 end for;
3491
3492 ✗ true := listEmpty(rest_e2);
3493 ✗ true := listEmpty(rest_e3);
3494 ✗ outList := listReverseInPlace(outList);
3495 end thread3MapFold;
3496
3497 public function threadFold1<T1, T2, FT, ArgT1>
3498 "This is a combination of thread and fold that applies a function to the head
3499 of two lists with an extra argument that is updated and passed on. This
3500 function also takes an extra constant argument that is passed to the function."
3501 input list<T1> inList1;
3502 input list<T2> inList2;
3503 input FoldFunc inFoldFunc;
3504 input ArgT1 inArg1;
3505 input FT inFoldArg;
3506 output FT outFoldArg = inFoldArg;
3507
3508 partial function FoldFunc
3509 input T1 inElement1;
3510 input T2 inElement2;
3511 input ArgT1 inArg1;
3512 input FT inFoldArg;
3513 output FT outFoldArg;
3514 end FoldFunc;
3515 protected
3516 list<T2> rest2 = inList2;
3517 T2 e2;
3518 algorithm
3519
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 5 times.
17 for e1 in inList1 loop
3520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 e2 :: rest2 := rest2;
3521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 outFoldArg := inFoldFunc(e1, e2, inArg1, outFoldArg);
3522 end for;
3523
3524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 true := listEmpty(rest2);
3525 end threadFold1;
3526
3527 public function threadFold2<T1, T2, FT, ArgT1, ArgT2>
3528 "This is a combination of thread and fold that applies a function to the head
3529 of two lists with an extra argument that is updated and passed on. This
3530 function also takes two extra constant arguments that is passed to the function."
3531 input list<T1> inList1;
3532 input list<T2> inList2;
3533 input FoldFunc inFoldFunc;
3534 input ArgT1 inArg1;
3535 input ArgT2 inArg2;
3536 input FT inFoldArg;
3537 output FT outFoldArg = inFoldArg;
3538
3539 partial function FoldFunc
3540 input T1 inElement1;
3541 input T2 inElement2;
3542 input ArgT1 inArg1;
3543 input ArgT2 inArg2;
3544 input FT inFoldArg;
3545 output FT outFoldArg;
3546 end FoldFunc;
3547 protected
3548 list<T2> rest2 = inList2;
3549 T2 e2;
3550 algorithm
3551
2/2
✓ Branch 0 taken 3932 times.
✓ Branch 1 taken 1310 times.
5242 for e1 in inList1 loop
3552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3932 times.
3932 e2 :: rest2 := rest2;
3553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3932 times.
3932 outFoldArg := inFoldFunc(e1, e2, inArg1, inArg2, outFoldArg);
3554 end for;
3555
3556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1310 times.
1310 true := listEmpty(rest2);
3557 end threadFold2;
3558
3559 public function threadFold3<T1, T2, FT, ArgT1, ArgT2, ArgT3>
3560 "This is a combination of thread and fold that applies a function to the head
3561 of two lists with an extra argument that is updated and passed on. This
3562 function also takes three extra constant arguments that is passed to the function."
3563 input list<T1> inList1;
3564 input list<T2> inList2;
3565 input FoldFunc inFoldFunc;
3566 input ArgT1 inArg1;
3567 input ArgT2 inArg2;
3568 input ArgT3 inArg3;
3569 input FT inFoldArg;
3570 output FT outFoldArg = inFoldArg;
3571
3572 partial function FoldFunc
3573 input T1 inElement1;
3574 input T2 inElement2;
3575 input ArgT1 inArg1;
3576 input ArgT2 inArg2;
3577 input ArgT3 inArg3;
3578 input FT inFoldArg;
3579 output FT outFoldArg;
3580 end FoldFunc;
3581 protected
3582 list<T2> rest2 = inList2;
3583 T2 e2;
3584 algorithm
3585
2/2
✓ Branch 0 taken 50748 times.
✓ Branch 1 taken 13081 times.
63829 for e1 in inList1 loop
3586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50748 times.
50748 e2 :: rest2 := rest2;
3587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50748 times.
50748 outFoldArg := inFoldFunc(e1, e2, inArg1, inArg2, inArg3, outFoldArg);
3588 end for;
3589
3590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13081 times.
13081 true := listEmpty(rest2);
3591 end threadFold3;
3592
3593 public function threadFold<T1, T2, FT>
3594 "This is a combination of thread and fold that applies a function to the head
3595 of two lists with an extra argument that is updated and passed on."
3596 input list<T1> inList1;
3597 input list<T2> inList2;
3598 input FoldFunc inFoldFunc;
3599 input FT inFoldArg;
3600 output FT outFoldArg = inFoldArg;
3601
3602 partial function FoldFunc
3603 input T1 inElement1;
3604 input T2 inElement2;
3605 input FT inFoldArg;
3606 output FT outFoldArg;
3607 end FoldFunc;
3608 protected
3609 list<T2> rest2 = inList2;
3610 T2 e2;
3611 algorithm
3612
2/2
✓ Branch 0 taken 66432 times.
✓ Branch 1 taken 26196 times.
92628 for e1 in inList1 loop
3613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66432 times.
66432 e2 :: rest2 := rest2;
3614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66432 times.
66432 outFoldArg := inFoldFunc(e1, e2, outFoldArg);
3615 end for;
3616
3617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26196 times.
26196 true := listEmpty(rest2);
3618 end threadFold;
3619
3620 public function threadMapFold<T1, T2, TO, FT>
3621 "Takes a list, an extra argument and a function. The function will be applied
3622 to each element in the list, and the extra argument will be passed to the
3623 function and updated."
3624 input list<T1> inList1;
3625 input list<T2> inList2;
3626 input FuncType inFunc;
3627 input FT inArg;
3628 output list<TO> outList = {};
3629 output FT outArg = inArg;
3630
3631 partial function FuncType
3632 input T1 inElem1;
3633 input T2 inElem2;
3634 input FT inArg;
3635 output TO outResult;
3636 output FT outArg;
3637 end FuncType;
3638 protected
3639 T2 e2;
3640 list<T2> rest_e2 = inList2;
3641 TO res;
3642 algorithm
3643
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for e1 in inList1 loop
3644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 e2 :: rest_e2 := rest_e2;
3645
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 (res, outArg) := inFunc(e1, e2, outArg);
3646 outList := res :: outList;
3647 end for;
3648
3649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 true := listEmpty(rest_e2);
3650 8 outList := listReverseInPlace(outList);
3651 end threadMapFold;
3652
3653 public function position<T>
3654 "Takes a value and a list, and returns the position of the first list element
3655 that whose value is equal to the given value.
3656 Example: position(2, {0, 1, 2, 3}) => 3"
3657 input T inElement;
3658 input list<T> inList;
3659 output Integer outPosition = 1 "one-based index";
3660 algorithm
3661
2/2
✓ Branch 0 taken 6007888 times.
✓ Branch 1 taken 7266 times.
6015154 for e in inList loop
3662
2/2
✓ Branch 1 taken 56591 times.
✓ Branch 2 taken 5951297 times.
6007888 if valueEq(e, inElement) then
3663 56591 return;
3664 end if;
3665 5951297 outPosition := outPosition + 1;
3666 end for;
3667 7266 fail();
3668 end position;
3669
3670 public function positionOnTrue<T>
3671 "Takes a list and a predicate function, and returns the index of the first
3672 element for which the function returns true, or -1 if no match is found."
3673 input list<T> inList;
3674 input PredFunc inPredFunc;
3675 output Integer outPosition = 1;
3676
3677 partial function PredFunc
3678 input T inElement;
3679 output Boolean outMatch;
3680 end PredFunc;
3681 algorithm
3682
2/2
✓ Branch 0 taken 3381 times.
✓ Branch 1 taken 15 times.
3396 for e in inList loop
3683
3/4
✓ Branch 0 taken 3381 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 1167 times.
✓ Branch 5 taken 2214 times.
3381 if inPredFunc(e) then
3684 1167 return;
3685 end if;
3686
3687 2214 outPosition := outPosition + 1;
3688 end for;
3689
3690 outPosition := -1;
3691 end positionOnTrue;
3692
3693 public function position1OnTrue<T, ArgT>
3694 "Takes a list, a predicate function and an extra argument, and return the
3695 index of the first element for which the function returns true, or -1 if no
3696 match is found. The extra argument is passed to the predicate function for
3697 each call."
3698 input list<T> inList;
3699 input PredFunc inPredFunc;
3700 input ArgT inArg;
3701 output Integer outPosition = 1;
3702
3703 partial function PredFunc
3704 input T inElement;
3705 input ArgT inArg;
3706 output Boolean outMatch;
3707 end PredFunc;
3708 algorithm
3709
1/2
✓ Branch 0 taken 12579 times.
✗ Branch 1 not taken.
12579 for e in inList loop
3710
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12579 times.
✓ Branch 4 taken 5882 times.
✓ Branch 5 taken 6697 times.
12579 if inPredFunc(e, inArg) then
3711 5882 return;
3712 end if;
3713
3714 6697 outPosition := outPosition + 1;
3715 end for;
3716
3717 outPosition := -1;
3718 end position1OnTrue;
3719
3720 public function getMember<T>
3721 "Takes a value and a list, and returns the value if it's present in the list.
3722 If not present the function will fail.
3723 Example: listGetMember(0, {1, 2, 3}) => fail
3724 listGetMember(1, {1, 2, 3}) => 1"
3725 input T inElement;
3726 input list<T> inList;
3727 output T outElement;
3728 protected
3729 T e;
3730 algorithm
3731
2/2
✓ Branch 0 taken 31416 times.
✓ Branch 1 taken 6 times.
31422 for e in inList loop
3732
2/2
✓ Branch 1 taken 5898 times.
✓ Branch 2 taken 25518 times.
31416 if valueEq(inElement, e) then
3733 outElement := e;
3734 5898 return;
3735 end if;
3736 end for;
3737 6 fail();
3738 end getMember;
3739
3740 public function getMemberOnTrue<T, VT>
3741 "Takes a value and a list of values and a comparison function over two values.
3742 If the value is present in the list (using the comparison function returning
3743 true) the value is returned, otherwise the function fails.
3744 Example:
3745 function equalLength(string,string) returns true if the strings are of same length
3746 getMemberOnTrue(\"a\",{\"bb\",\"b\",\"ccc\"},equalLength) => \"b\""
3747 input VT inValue;
3748 input list<T> inList;
3749 input CompFunc inCompFunc;
3750 output T outElement;
3751
3752 partial function CompFunc
3753 input VT inValue;
3754 input T inElement;
3755 output Boolean outIsEqual;
3756 end CompFunc;
3757 algorithm
3758
2/2
✓ Branch 0 taken 19145697 times.
✓ Branch 1 taken 6100157 times.
25245854 for e in inList loop
3759
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 19145692 times.
✓ Branch 4 taken 489957 times.
✓ Branch 5 taken 18655740 times.
19145697 if inCompFunc(inValue, e) then
3760 outElement := e;
3761 489957 return;
3762 end if;
3763 end for;
3764 6100157 fail();
3765 end getMemberOnTrue;
3766
3767 public function notMember<T>
3768 "Returns true if a list does not contain the given element, otherwise false."
3769 input T inElement;
3770 input list<T> inList;
3771 output Boolean outIsNotMember;
3772 algorithm
3773 127 outIsNotMember := not listMember(inElement, inList);
3774 end notMember;
3775
3776 public function isMemberOnTrue<T, VT>
3777 "Returns true if the given value is a member of the list, as determined by the
3778 comparison function given."
3779 input VT inValue;
3780 input list<T> inList;
3781 input CompFunc inCompFunc;
3782 output Boolean outIsMember;
3783
3784 partial function CompFunc
3785 input VT inValue;
3786 input T inElement;
3787 output Boolean outIsEqual;
3788 end CompFunc;
3789 algorithm
3790
2/2
✓ Branch 0 taken 19148658 times.
✓ Branch 1 taken 4032338 times.
23180996 for e in inList loop
3791
4/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 19148595 times.
✓ Branch 4 taken 786583 times.
✓ Branch 5 taken 18362075 times.
19148658 if inCompFunc(inValue, e) then
3792 outIsMember := true;
3793 786583 return;
3794 end if;
3795 end for;
3796
3797 outIsMember := false;
3798 end isMemberOnTrue;
3799
3800 public function exist1<T, ArgT1>
3801 "Returns true if a certain element exists in the given list as indicated by
3802 the given predicate function. Also takes an extra argument that is passed to
3803 the predicate function."
3804 input list<T> inList;
3805 input FindFunc inFindFunc;
3806 input ArgT1 inExtraArg;
3807 output Boolean outExists;
3808
3809 partial function FindFunc
3810 input T inElement;
3811 input ArgT1 inExtraArg;
3812 output Boolean outFound;
3813 end FindFunc;
3814 algorithm
3815
2/2
✓ Branch 0 taken 1063744 times.
✓ Branch 1 taken 172430 times.
1236174 for e in inList loop
3816
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1063744 times.
✓ Branch 4 taken 53879 times.
✓ Branch 5 taken 1009865 times.
1063744 if inFindFunc(e, inExtraArg) then
3817 outExists := true;
3818 53879 return;
3819 end if;
3820 end for;
3821
3822 outExists := false;
3823 end exist1;
3824
3825 public function extractOnTrue<T>
3826 "Takes a list of values and a filter function over the values and returns
3827 two lists. One of values for which the matching function returns true and the
3828 other containing the remaining elements.
3829 Example:
3830 extractOnTrue({1, 2, 3, 4, 5}, isEven) => {2, 4}, {1, 3, 5}"
3831 input list<T> inList;
3832 input FilterFunc inFilterFunc;
3833 output list<T> outExtractedList = {};
3834 output list<T> outRemainingList = {};
3835
3836 partial function FilterFunc
3837 input T inElement;
3838 output Boolean outResult;
3839 end FilterFunc;
3840 algorithm
3841
2/2
✓ Branch 0 taken 980226 times.
✓ Branch 1 taken 323407 times.
1303633 for e in inList loop
3842
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 980226 times.
✓ Branch 4 taken 32490 times.
✓ Branch 5 taken 947736 times.
980226 if inFilterFunc(e) then
3843 outExtractedList := e :: outExtractedList;
3844 else
3845 outRemainingList := e :: outRemainingList;
3846 end if;
3847 end for;
3848
3849 323407 outExtractedList := listReverseInPlace(outExtractedList);
3850 323407 outRemainingList := listReverseInPlace(outRemainingList);
3851 end extractOnTrue;
3852
3853 public function extract1OnTrue<T, ArgT1>
3854 "Takes a list of values and a filter function over the values and an extra
3855 argument and returns two lists. One of values for which the matching function
3856 returns true and the other containing the remaining elements."
3857 input list<T> inList;
3858 input FilterFunc inFilterFunc;
3859 input ArgT1 inArg;
3860 output list<T> outExtractedList = {};
3861 output list<T> outRemainingList = {};
3862
3863 partial function FilterFunc
3864 input T inElement;
3865 input ArgT1 inArg;
3866 output Boolean outResult;
3867 end FilterFunc;
3868 algorithm
3869
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 41 times.
515 for e in inList loop
3870
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 474 times.
✓ Branch 4 taken 218 times.
✓ Branch 5 taken 256 times.
474 if inFilterFunc(e, inArg) then
3871 outExtractedList := e :: outExtractedList;
3872 else
3873 outRemainingList := e :: outRemainingList;
3874 end if;
3875 end for;
3876
3877 41 outExtractedList := listReverseInPlace(outExtractedList);
3878 41 outRemainingList := listReverseInPlace(outRemainingList);
3879 end extract1OnTrue;
3880
3881 public function filter<T>
3882 "Takes a list of values and a filter function over the values and returns a
3883 sub list of values for which the matching function succeeds.
3884 Example:
3885 filter({1, 2, 3, 4, 5}, isEven) => {2, 4}"
3886 input list<T> inList;
3887 input FilterFunc inFilterFunc;
3888 output list<T> outList = {};
3889
3890 partial function FilterFunc
3891 input T inElement;
3892 end FilterFunc;
3893 algorithm
3894 ✗ for e in inList loop
3895 try
3896 ✗ inFilterFunc(e);
3897 outList := e :: outList;
3898 else
3899 end try;
3900 end for;
3901
3902 ✗ outList := listReverseInPlace(outList);
3903 end filter;
3904
3905 public function filterMap<TI, TO>
3906 "Applies a function to each element in the given list, but also filters out
3907 all elements for which the function fails."
3908 input list<TI> inList;
3909 input FilterMapFunc inFilterMapFunc;
3910 output list<TO> outList = {};
3911
3912 partial function FilterMapFunc
3913 input TI inElement;
3914 output TO outElement;
3915 end FilterMapFunc;
3916 protected
3917 TO oe;
3918 algorithm
3919
2/2
✓ Branch 0 taken 211474 times.
✓ Branch 1 taken 282255 times.
493729 for e in inList loop
3920 try
3921
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 211469 times.
211474 oe := inFilterMapFunc(e);
3922 outList := oe :: outList;
3923 else
3924 end try;
3925 end for;
3926
3927 282255 outList := listReverseInPlace(outList);
3928 end filterMap;
3929
3930 public function filterMap1<TI, TO, ArgT1>
3931 "Applies a function to each element in the given list, but also filters out
3932 all elements for which the function fails."
3933 input list<TI> inList;
3934 input FilterMapFunc inFilterMapFunc;
3935 input ArgT1 inExtraArg;
3936 output list<TO> outList = {};
3937
3938 partial function FilterMapFunc
3939 input TI inElement;
3940 input ArgT1 inExtraArg;
3941 output TO outElement;
3942 end FilterMapFunc;
3943 protected
3944 TO oe;
3945 algorithm
3946
2/2
✓ Branch 0 taken 9362 times.
✓ Branch 1 taken 984 times.
10346 for e in inList loop
3947 try
3948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9362 times.
9362 oe := inFilterMapFunc(e, inExtraArg);
3949 outList := oe :: outList;
3950 else
3951 end try;
3952 end for;
3953
3954 984 outList := listReverseInPlace(outList);
3955 end filterMap1;
3956
3957 public function filterOnTrue<T>
3958 "Takes a list of values and a filter function over the values and returns a
3959 sub list of values for which the matching function returns true.
3960 Example:
3961 filter({1, 2, 3, 4, 5}, isEven) => {2, 4}"
3962 input list<T> inList;
3963 input FilterFunc inFilterFunc;
3964 output list<T> outList;
3965
3966 partial function FilterFunc
3967 input T inElement;
3968 output Boolean outResult;
3969 end FilterFunc;
3970 algorithm
3971
15/16
✓ Branch 0 taken 14956 times.
✓ Branch 1 taken 1413309 times.
✓ Branch 4 taken 936744 times.
✓ Branch 5 taken 491521 times.
✓ Branch 6 taken 1428265 times.
✓ Branch 7 taken 235656 times.
✓ Branch 8 taken 491521 times.
✓ Branch 9 taken 235656 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 9777896 times.
✓ Branch 14 taken 9049375 times.
✓ Branch 15 taken 728521 times.
✓ Branch 16 taken 9777896 times.
✓ Branch 17 taken 580143 times.
✓ Branch 18 taken 728521 times.
✓ Branch 19 taken 580143 times.
12021960 outList := list(e for e guard(inFilterFunc(e)) in inList);
3972 end filterOnTrue;
3973
3974 public function filterOnFalse<T>
3975 "Takes a list of values and a filter function over the values and returns a
3976 sub list of values for which the matching function returns false.
3977 Example:
3978 filterOnFalse({1, 2, 3, 1, 5}, isEven) => {1, 3, 1, 5}"
3979 input list<T> inList;
3980 input FilterFunc inFilterFunc;
3981 output list<T> outList;
3982
3983 partial function FilterFunc
3984 input T inElement;
3985 output Boolean outResult;
3986 end FilterFunc;
3987 algorithm
3988
8/8
✓ Branch 0 taken 58617 times.
✓ Branch 1 taken 81493 times.
✓ Branch 4 taken 54686 times.
✓ Branch 5 taken 85424 times.
✓ Branch 6 taken 140110 times.
✓ Branch 7 taken 108993 times.
✓ Branch 8 taken 85424 times.
✓ Branch 9 taken 108993 times.
249103 outList := list(e for e guard(boolNot(inFilterFunc(e))) in inList);
3989 end filterOnFalse;
3990
3991 public function filter1OnTrueSync<T1, T2, ArgT1>
3992 "like filterOnTrue but performs the same filtering synchronously on a second list.
3993 Takes 2 list of values and a filter function and an extra argument over the values of the first list and returns a
3994 sub list of values for both lists for which the matching function returns true for the first list.
3995 Example:
3996 filter({1, 2, 3, 4, 5}, isEven) => {2, 4}"
3997 input list<T1> inList;
3998 input FilterFunc inFilterFunc;
3999 input ArgT1 inArg1;
4000 input list<T2> inSyncList;
4001 output list<T1> outList_a = {};
4002 output list<T2> outList_b = {};
4003
4004 partial function FilterFunc
4005 input T1 inElement;
4006 input ArgT1 inArg1;
4007 output Boolean outResult;
4008 end FilterFunc;
4009 protected
4010 T2 e2;
4011 list<T2> rest2 = inSyncList;
4012 algorithm
4013
2/2
✓ Branch 0 taken 212059 times.
✓ Branch 1 taken 63027 times.
275086 for e1 in inList loop
4014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212059 times.
212059 e2 :: rest2 := rest2;
4015
4016
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 212059 times.
✓ Branch 4 taken 62110 times.
✓ Branch 5 taken 149949 times.
212059 if inFilterFunc(e1, inArg1) then
4017 outList_a := e1 :: outList_a;
4018 outList_b := e2 :: outList_b;
4019 end if;
4020 end for;
4021
4022 63027 outList_a := listReverseInPlace(outList_a);
4023 63027 outList_b := listReverseInPlace(outList_b);
4024 end filter1OnTrueSync;
4025
4026 public function filterOnTrueSync<T1, T2>
4027 "Like filterOnTrue but performs the same filtering synchronously on a second list.
4028 Takes 2 list of values and a filter function over the values of the first
4029 list and returns a sub list of values for both lists for which the matching
4030 function returns true for the first list."
4031 input list<T1> inList;
4032 input FilterFunc inFilterFunc;
4033 input list<T2> inSyncList;
4034 output list<T1> outList_a = {};
4035 output list<T2> outList_b = {};
4036
4037 partial function FilterFunc
4038 input T1 inElement;
4039 output Boolean outResult;
4040 end FilterFunc;
4041 protected
4042 T2 e2;
4043 list<T2> rest2 = inSyncList;
4044 algorithm
4045
2/2
✓ Branch 2 taken 780489 times.
✓ Branch 3 taken 1045 times.
781534 true := listLength(inList) == listLength(inSyncList);
4046
4047
2/2
✓ Branch 0 taken 499524 times.
✓ Branch 1 taken 780489 times.
1280013 for e1 in inList loop
4048
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 499524 times.
499524 e2 :: rest2 := rest2;
4049
4050
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 499524 times.
✓ Branch 4 taken 427707 times.
✓ Branch 5 taken 71817 times.
499524 if inFilterFunc(e1) then
4051 outList_a := e1 :: outList_a;
4052 outList_b := e2 :: outList_b;
4053 end if;
4054 end for;
4055
4056 780489 outList_a := listReverseInPlace(outList_a);
4057 780489 outList_b := listReverseInPlace(outList_b);
4058 end filterOnTrueSync;
4059
4060 public function filter1<T, ArgT1>
4061 "Takes a list of values, a filter function over the values and an extra
4062 argument, and returns a sub list of values for which the matching function
4063 succeeds.
4064 Example:
4065 filter({1, 2, 3, 4, 5}, isEven) => {2, 4}"
4066 input list<T> inList;
4067 input FilterFunc inFilterFunc;
4068 input ArgT1 inArg1;
4069 output list<T> outList = {};
4070
4071 partial function FilterFunc
4072 input T inElement;
4073 input ArgT1 inArg1;
4074 end FilterFunc;
4075 algorithm
4076
2/2
✓ Branch 0 taken 860 times.
✓ Branch 1 taken 9791 times.
10651 for e in inList loop
4077 try
4078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860 times.
860 inFilterFunc(e, inArg1);
4079 outList := e :: outList;
4080 else
4081 end try;
4082 end for;
4083
4084 9791 outList := listReverseInPlace(outList);
4085 end filter1;
4086
4087 public function filter1OnTrue<T, ArgT1>
4088 "Takes a list of values and a filter function over the values and returns a
4089 sub list of values for which the matching function returns true.
4090 Example:
4091 filter1OnTrue({1, 2, 3, 1, 5}, intEq, 1) => {1, 1}"
4092 input list<T> inList;
4093 input FilterFunc inFilterFunc;
4094 input ArgT1 inArg1;
4095 output list<T> outList;
4096
4097 partial function FilterFunc
4098 input T inElement;
4099 input ArgT1 inArg1;
4100 output Boolean outResult;
4101 end FilterFunc;
4102 algorithm
4103
14/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1408381 times.
✓ Branch 4 taken 373031 times.
✓ Branch 5 taken 1035350 times.
✓ Branch 6 taken 1408381 times.
✓ Branch 7 taken 329341 times.
✓ Branch 8 taken 1035350 times.
✓ Branch 9 taken 329341 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 9986116 times.
✓ Branch 14 taken 9479355 times.
✓ Branch 15 taken 506761 times.
✓ Branch 16 taken 9986116 times.
✓ Branch 17 taken 397992 times.
✓ Branch 18 taken 506761 times.
✓ Branch 19 taken 397992 times.
12121830 outList := list(e for e guard(inFilterFunc(e, inArg1)) in inList);
4104 end filter1OnTrue;
4105
4106 public function filter1OnTrueAndUpdate<T, ArgT1>
4107 "Takes a list of values and a filter function over the values and returns a
4108 sub list of values for which the matching function returns true. The
4109 matching function may update the values.
4110 Example:
4111 filter1OnTrue({1, 2, 3, 1, 5}, intEq, 1) => {1, 1}"
4112 input list<T> inList;
4113 input FilterFunc inFilterFunc;
4114 input UpdateFunc inUpdateFunc;
4115 input ArgT1 inArg1;
4116 output list<T> outList;
4117
4118 partial function FilterFunc
4119 input T inElement;
4120 input ArgT1 inArg1;
4121 output Boolean outResult;
4122 end FilterFunc;
4123
4124 partial function UpdateFunc
4125 input output T inElement;
4126 input ArgT1 inArg1;
4127 end UpdateFunc;
4128 algorithm
4129
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 46 times.
✓ Branch 6 taken 54 times.
✓ Branch 7 taken 27 times.
✓ Branch 8 taken 46 times.
✓ Branch 9 taken 27 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 46 times.
81 outList := list(inUpdateFunc(e,inArg1) for e guard(inFilterFunc(e, inArg1)) in inList);
4130 end filter1OnTrueAndUpdate;
4131
4132 public function filter1rOnTrue<T, ArgT1>
4133 "Takes a list of values and a filter function over the values and returns a
4134 sub list of values for which the matching function returns true.
4135 Example:
4136 filter1rOnTrue({1, 2, 3, 1, 5}, intEq, 1) => {1, 1}"
4137 input list<T> inList;
4138 input FilterFunc inFilterFunc;
4139 input ArgT1 inArg1;
4140 output list<T> outList;
4141
4142 partial function FilterFunc
4143 input ArgT1 inArg1;
4144 input T inElement;
4145 output Boolean outResult;
4146 end FilterFunc;
4147 algorithm
4148
7/16
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 45383 times.
✓ Branch 14 taken 26706 times.
✓ Branch 15 taken 18677 times.
✓ Branch 16 taken 45383 times.
✓ Branch 17 taken 15822 times.
✓ Branch 18 taken 18677 times.
✓ Branch 19 taken 15822 times.
61205 outList := list(e for e guard(inFilterFunc(inArg1, e)) in inList);
4149 end filter1rOnTrue;
4150
4151 public function filter2OnTrue<T, ArgT1, ArgT2>
4152 "Takes a list of values and a filter function over the values and returns a
4153 sub list of values for which the matching function returns true."
4154 input list<T> inList;
4155 input FilterFunc inFilterFunc;
4156 input ArgT1 inArg1;
4157 input ArgT2 inArg2;
4158 output list<T> outList;
4159
4160 partial function FilterFunc
4161 input T inElement;
4162 input ArgT1 inArg1;
4163 input ArgT2 inArg2;
4164 output Boolean outResult;
4165 end FilterFunc;
4166 algorithm
4167
13/16
✗ Branch 0 not taken.
✓ Branch 1 taken 248055 times.
✓ Branch 4 taken 21273 times.
✓ Branch 5 taken 226782 times.
✓ Branch 6 taken 248055 times.
✓ Branch 7 taken 194170 times.
✓ Branch 8 taken 226782 times.
✓ Branch 9 taken 194170 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 24 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24 times.
✓ Branch 16 taken 24 times.
✓ Branch 17 taken 17 times.
✓ Branch 18 taken 24 times.
✓ Branch 19 taken 17 times.
442266 outList := list(e for e guard(inFilterFunc(e, inArg1, inArg2)) in inList);
4168 end filter2OnTrue;
4169
4170 public function removeOnTrue<T, VT>
4171 "Goes through a list and removes all elements which are equal to the given
4172 value, using the given comparison function."
4173 input VT inValue;
4174 input CompFunc inCompFunc;
4175 input list<T> inList;
4176 output list<T> outList;
4177
4178 partial function CompFunc
4179 input VT inValue;
4180 input T inElement;
4181 output Boolean outIsEqual;
4182 end CompFunc;
4183 algorithm
4184
7/8
✗ Branch 0 not taken.
✓ Branch 1 taken 3914490 times.
✓ Branch 4 taken 958938 times.
✓ Branch 5 taken 2955552 times.
✓ Branch 6 taken 3914490 times.
✓ Branch 7 taken 1098461 times.
✓ Branch 8 taken 2955552 times.
✓ Branch 9 taken 1098461 times.
5012951 outList := list(e for e guard(not inCompFunc(inValue, e)) in inList);
4185 end removeOnTrue;
4186
4187 public function filterCons<T>
4188 "Adds the elements from inList for which the filter function returns true to
4189 accumList in reverse order. Ex:
4190 filterCons({1, 2, 3, 4, 5}, isOdd, {6, 7}) => {5, 3, 1, 6, 7}"
4191 input list<T> inList;
4192 input FilterFunc fn;
4193 input output list<T> accumList;
4194
4195 partial function FilterFunc
4196 input T e;
4197 output Boolean res;
4198 end FilterFunc;
4199 algorithm
4200
2/2
✓ Branch 0 taken 3028 times.
✓ Branch 1 taken 352 times.
3380 for e in inList loop
4201
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3028 times.
✓ Branch 4 taken 2351 times.
✓ Branch 5 taken 677 times.
3028 if fn(e) then
4202 accumList := e :: accumList;
4203 end if;
4204 end for;
4205 end filterCons;
4206
4207 public function select = filterOnTrue;
4208 public function select1 = filter1OnTrue;
4209 public function select1r = filter1rOnTrue;
4210 public function select2 = filter2OnTrue;
4211
4212 public function find<T>
4213 "This function retrieves the first element of a list for which the passed
4214 function evaluates to true."
4215 input list<T> inList;
4216 input SelectFunc inFunc;
4217 output T outElement;
4218
4219 partial function SelectFunc
4220 input T inElement;
4221 output Boolean outSelect;
4222 end SelectFunc;
4223 algorithm
4224
2/2
✓ Branch 0 taken 377548 times.
✓ Branch 1 taken 25001 times.
402549 for e in inList loop
4225
4/4
✓ Branch 0 taken 305589 times.
✓ Branch 1 taken 71959 times.
✓ Branch 4 taken 73450 times.
✓ Branch 5 taken 304098 times.
377548 if inFunc(e) then
4226 outElement := e;
4227 73450 return;
4228 end if;
4229 end for;
4230 25001 fail();
4231 end find;
4232
4233 public function findOption<T>
4234 "Returns the first element of a list for which the predicate function return
4235 true as an Option, or NONE() if no element is found."
4236 input list<T> lst;
4237 input Predicate fn;
4238 output Option<T> result;
4239
4240 partial function Predicate
4241 input T e;
4242 output Boolean matching;
4243 end Predicate;
4244 algorithm
4245
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 177866 times.
177868 for e in lst loop
4246
3/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if fn(e) then
4247 result := SOME(e);
4248 2 return;
4249 end if;
4250 end for;
4251
4252 result := NONE();
4253 end findOption;
4254
4255 public function find1<T, ArgT1>
4256 "This function retrieves the first element of a list for which the passed
4257 function evaluates to true."
4258 input list<T> inList;
4259 input SelectFunc inFunc;
4260 input ArgT1 arg1;
4261 output T outElement;
4262
4263 partial function SelectFunc
4264 input T inElement;
4265 input ArgT1 arg;
4266 output Boolean outSelect;
4267 end SelectFunc;
4268 algorithm
4269
2/2
✓ Branch 0 taken 11434309 times.
✓ Branch 1 taken 49839 times.
11484148 for e in inList loop
4270
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11434309 times.
✓ Branch 4 taken 66207 times.
✓ Branch 5 taken 11368102 times.
11434309 if inFunc(e, arg1) then
4271 outElement := e;
4272 66207 return;
4273 end if;
4274 end for;
4275 49839 fail();
4276 end find1;
4277
4278 public function findAndRemove<T>
4279 "This function retrieves the first element of a list for which the passed
4280 function evaluates to true. And returns the list with the element removed."
4281 input list<T> inList;
4282 input SelectFunc inFunc;
4283 output T outElement;
4284 output list<T> rest;
4285
4286 partial function SelectFunc
4287 input T inElement;
4288 output Boolean outSelect;
4289 end SelectFunc;
4290 protected
4291 Integer i=0;
4292 DoubleEnded.MutableList<T> delst;
4293 T t;
4294 algorithm
4295
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 4 times.
25 for e in inList loop
4296
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 12 times.
21 if inFunc(e) then
4297 outElement := e;
4298 9 delst := DoubleEnded.fromList({});
4299 rest := inList;
4300
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
13 for i in 1:i loop
4301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 t::rest := rest;
4302 4 DoubleEnded.push_back(delst, t);
4303 end for;
4304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 _::rest := rest;
4305 9 rest := DoubleEnded.toListAndClear(delst, prependToList=rest);
4306
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 return;
4307 end if;
4308 12 i := i + 1;
4309 end for;
4310 4 fail();
4311 end findAndRemove;
4312
4313
4314 public function findAndRemove1<T, ArgT1>
4315 "This function retrieves the first element of a list for which the passed
4316 function evaluates to true. And returns the list with the element removed."
4317 input list<T> inList;
4318 input SelectFunc inFunc;
4319 input ArgT1 arg1;
4320 output T outElement;
4321 output list<T> rest;
4322
4323 partial function SelectFunc
4324 input T inElement;
4325 input ArgT1 arg;
4326 output Boolean outSelect;
4327 end SelectFunc;
4328 protected
4329 Integer i=0;
4330 DoubleEnded.MutableList<T> delst;
4331 T t;
4332 algorithm
4333
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 time.
14 for e in inList loop
4334
3/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 2 times.
13 if inFunc(e, arg1) then
4335 outElement := e;
4336 11 delst := DoubleEnded.fromList({});
4337 rest := inList;
4338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 for i in 1:i loop
4339 ✗ t::rest := rest;
4340 ✗ DoubleEnded.push_back(delst, t);
4341 end for;
4342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 _::rest := rest;
4343 11 rest := DoubleEnded.toListAndClear(delst, prependToList=rest);
4344
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 return;
4345 end if;
4346 2 i := i + 1;
4347 end for;
4348 1 fail();
4349 end findAndRemove1;
4350
4351 public function findBoolList<T>
4352 "This function returns the first value in the given list for which the
4353 corresponding element in the boolean list is true."
4354 input list<Boolean> inBooleans;
4355 input list<T> inList;
4356 input T inFalseValue;
4357 output T outElement;
4358 protected
4359 T e;
4360 list<T> rest = inList;
4361 algorithm
4362
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
4 for b in inBooleans loop
4363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 e :: rest := rest;
4364
4365
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
3 if b then
4366 outElement := e;
4367 1 return;
4368 end if;
4369 end for;
4370 outElement := inFalseValue;
4371 end findBoolList;
4372
4373 public function deleteMemberOnTrue<T, VT>
4374 "Takes a list and a value and a comparison function and deletes the first
4375 occurence of the value in the list for which the function returns true. It
4376 returns the new list and the deleted element, or only the original list if
4377 no element was removed.
4378 Example: deleteMemberOnTrue(2,{1,2,3,2},intEq) => ({1,3,2}, SOME(2))"
4379 input VT inValue;
4380 input list<T> inList;
4381 input CompareFunc inCompareFunc;
4382 output list<T> outList = inList;
4383 output Option<T> outDeletedElement = NONE();
4384
4385 partial function CompareFunc
4386 input VT inValue;
4387 input T inElement;
4388 output Boolean outIsEqual;
4389 end CompareFunc;
4390 protected
4391 T e;
4392 list<T> rest = inList, acc = {};
4393 algorithm
4394
2/2
✓ Branch 0 taken 13851718 times.
✓ Branch 1 taken 1358419 times.
15210137 while not listEmpty(rest) loop
4395 13851718 e :: rest := rest;
4396
4397
4/4
✓ Branch 0 taken 15145 times.
✓ Branch 1 taken 13836573 times.
✓ Branch 4 taken 3512585 times.
✓ Branch 5 taken 10339133 times.
13851718 if inCompareFunc(inValue, e) then
4398 3512585 outList := listAppend(listReverseInPlace(acc), rest);
4399
2/2
✓ Branch 0 taken 1080031 times.
✓ Branch 1 taken 2432554 times.
3512585 if isPresent(outDeletedElement) then
4400 outDeletedElement := SOME(e);
4401 end if;
4402 3512585 return;
4403 end if;
4404
4405 acc := e :: acc;
4406 end while;
4407 end deleteMemberOnTrue;
4408
4409 public function deletePositions<T>
4410 "Takes a list and a list of positions, and deletes the positions from the
4411 list.
4412 Example: deletePositions({1, 2, 3, 4, 5}, {3, 1, 4}) => {2, 5}"
4413 input list<T> inList;
4414 input list<Integer> inPositions;
4415 input Boolean zeroBased = false;
4416 output list<T> outList;
4417 protected
4418 list<Integer> sorted_pos;
4419 algorithm
4420 710 sorted_pos := sortedUnique(sort(inPositions, intGt), intEq);
4421 710 outList := deletePositionsSorted(inList, sorted_pos, zeroBased);
4422 end deletePositions;
4423
4424 public function deletePositionsSorted<T>
4425 "Takes a list and a sorted list of positions (smallest index first), and
4426 deletes the positions from the list.
4427 Example: deletePositionsSorted({1, 2, 3, 4, 5}, {1, 3, 4}) => {2, 5}"
4428 input list<T> inList;
4429 input list<Integer> inPositions;
4430 input Boolean zeroBased = false;
4431 output list<T> outList = {};
4432 protected
4433 Integer i = if zeroBased then 0 else 1;
4434 T e;
4435 list<T> rest = inList;
4436 algorithm
4437
2/2
✓ Branch 0 taken 869 times.
✓ Branch 1 taken 710 times.
1579 for pos in inPositions loop
4438
2/2
✓ Branch 0 taken 1041 times.
✓ Branch 1 taken 869 times.
1910 while i <> pos loop
4439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1041 times.
1041 e :: rest := rest;
4440 outList := e :: outList;
4441 1041 i := i + 1;
4442 end while;
4443
4444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 869 times.
869 _ :: rest := rest;
4445 869 i := i + 1;
4446 end for;
4447
4448 710 outList := append_reverse(outList, rest);
4449 end deletePositionsSorted;
4450
4451 public function keepPositions<T>
4452 "Takes a list and a list of positions, and deletes all other elements from the
4453 list.
4454 Example: keepPositions({1, 2, 3, 4, 5}, {3, 1, 4}) => {1, 3, 4}"
4455 input list<T> inList;
4456 input list<Integer> inPositions;
4457 input Boolean zeroBased = false;
4458 output list<T> outList;
4459 protected
4460 list<Integer> sorted_pos;
4461 algorithm
4462 68 sorted_pos := sortedUnique(sort(inPositions, intGt), intEq);
4463 68 outList := keepPositionsSorted(inList, sorted_pos, zeroBased);
4464 end keepPositions;
4465
4466 public function keepPositionsSorted<T>
4467 "Takes a list and a sorted list of positions (smallest index first), and
4468 deletes all other positions from the list.
4469 Example: deletePositionsSorted({1, 2, 3, 4, 5}, {1, 3, 4}) => {1, 3, 4}"
4470 input list<T> inList;
4471 input list<Integer> inPositions;
4472 input Boolean zeroBased = false;
4473 output list<T> outList = {};
4474 protected
4475 Integer i = if zeroBased then 0 else 1;
4476 T e;
4477 list<T> rest = inList;
4478 algorithm
4479
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 68 times.
312 for pos in inPositions loop
4480
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 244 times.
444 while i <> pos loop
4481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 _ :: rest := rest;
4482 200 i := i + 1;
4483 end while;
4484
4485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 244 times.
244 e :: rest := rest;
4486 outList := e :: outList;
4487 244 i := i + 1;
4488 end for;
4489 68 outList := listReverse(outList);
4490 end keepPositionsSorted;
4491
4492 public function replaceAt<T>
4493 "Takes an element, a position and a list, and replaces the value at the given
4494 position in the list. Position is an integer between 1 and n for a list of
4495 n elements.
4496 Example: replaceAt('A', 2, {'a', 'b', 'c'}) => {'a', 'A', 'c'}"
4497 input T inElement;
4498 input Integer inPosition "one-based index" ;
4499 input list<T> inList;
4500 output list<T> outList;
4501 protected
4502 T e;
4503 list<T> rest = inList;
4504 DoubleEnded.MutableList<T> delst;
4505 algorithm
4506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 134835 times.
134835 true := inPosition >= 1;
4507 134835 delst := DoubleEnded.fromList({});
4508
4509 // Shuffle elements from inList to outList until the position is reached.
4510
2/2
✓ Branch 0 taken 100117 times.
✓ Branch 1 taken 34718 times.
1163851 for i in 1:inPosition-1 loop
4511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1029016 times.
1029016 e :: rest := rest;
4512 1029016 DoubleEnded.push_back(delst, e);
4513 end for;
4514
4515 // Replace the element at the position and append the remaining elements.
4516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 134835 times.
134835 _ :: rest := rest;
4517 134835 outList := DoubleEnded.toListAndClear(delst, prependToList=inElement::rest);
4518 end replaceAt;
4519
4520 public function replaceOnTrue<T>
4521 "Applies the function to each element of the list until the function returns
4522 true, and then replaces that element with the replacement.
4523 Example: replaceOnTrue(4, {1, 2, 3}, isTwo) => {1, 4, 3}."
4524 input T inReplacement;
4525 input list<T> inList;
4526 input FuncType inFunc;
4527 output list<T> outList = {};
4528 output Boolean outReplaced = false;
4529
4530 partial function FuncType
4531 input T inElement;
4532 output Boolean outReplace;
4533 end FuncType;
4534 protected
4535 T e;
4536 list<T> rest = inList;
4537 algorithm
4538
2/2
✓ Branch 0 taken 9674 times.
✓ Branch 1 taken 6949 times.
16623 while not listEmpty(rest) loop
4539 9674 e :: rest := rest;
4540
4541
3/4
✓ Branch 0 taken 9674 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 2358 times.
✓ Branch 5 taken 7316 times.
9674 if inFunc(e) then
4542 outReplaced := true;
4543 2358 outList := append_reverse(outList, inReplacement :: rest);
4544 2358 return;
4545 end if;
4546
4547 outList := e :: outList;
4548 end while;
4549
4550 outList := inList;
4551 end replaceOnTrue;
4552
4553 public function replaceAtIndexFirst<T>
4554 "Takes an element, a position and a list, and replaces the value at the given
4555 position in the list. Position is an integer between 1 and n for a list of
4556 n elements.
4557 Example: replaceAtIndexFirst(2, 'A', {'a', 'b', 'c'}) => {'a', 'A', 'c'}"
4558 input Integer inPosition "one-based index" ;
4559 input T inElement;
4560 input list<T> inList;
4561 output list<T> outList;
4562 algorithm
4563 ✗ outList := replaceAt(inElement, inPosition, inList);
4564 end replaceAtIndexFirst;
4565
4566 public function replaceAtWithList<T>
4567 "Takes an list, a position and a list, and replaces the element at the given
4568 position with the first list in the second list. Position is an integer
4569 between 1 and n for a list of n elements.
4570 Example: replaceAt({'A', 'B'}, 2, {'a', 'b', 'c'}) => {'a', 'A', 'B', 'c'}"
4571 input list<T> inReplacementList;
4572 input Integer inPosition;
4573 input list<T> inList;
4574 output list<T> outList = {};
4575 protected
4576 T e;
4577 list<T> rest = inList;
4578 algorithm
4579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 true := inPosition > 0;
4580
4581 // Shuffle elements from inList to outList until the position is reached.
4582
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
3867 for i in 1:inPosition-1 loop
4583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3861 times.
3861 e :: rest := rest;
4584 outList := e :: outList;
4585 end for;
4586
4587 // Replace the element at the position and append the remaining elements.
4588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 _ :: rest := rest;
4589 6 rest := listAppend(inReplacementList, rest);
4590 6 outList := append_reverse(outList, rest);
4591 end replaceAtWithList;
4592
4593
4594 public function toString<T>
4595 input list<T> inList;
4596 input FuncType inPrintFunc;
4597 input Style style = Style.FLAT_CURLY;
4598 output String s;
4599
4600 partial function FuncType
4601 input T t;
4602 output String s;
4603 end FuncType;
4604 algorithm
4605 s := match style
4606 ✗ case Style.NONE then toStringCustom(inList, inPrintFunc, "", "", "", "", true, 0);
4607 248 case Style.FLAT then toStringCustom(inList, inPrintFunc, "", "", ", ", "", true, 0);
4608 28 case Style.FLAT_BRACKETS then toStringCustom(inList, inPrintFunc, "", "(", ", ", ")", true, 0);
4609 547 case Style.FLAT_CURLY then toStringCustom(inList, inPrintFunc, "", "{", ", ", "}", true, 0);
4610 6 case Style.FLAT_CURLY_SHORT then toStringCustom(inList, inPrintFunc, "", "{", ", ", "}", true, 10);
4611 26 case Style.NEWLINE then toStringCustom(inList, inPrintFunc, "", "", "\n", "", true, 0);
4612 9 case Style.NEWLINE_INDENT then toStringCustom(inList, inPrintFunc, "", " ", "\n ", "", true, 0);
4613 16 case Style.NEWLINE_TAB then toStringCustom(inList, inPrintFunc, "", "\t", "\n\t", "", true, 0);
4614 else algorithm
4615 ✗ print(getInstanceName() + " failed because of unknown list style.\n");
4616 ✗ then fail();
4617 end match;
4618 end toString;
4619
4620 public function toStringCustom<T>
4621 "Creates a string from a list and a function that maps a list element to a
4622 string. It also takes several parameters that determine the formatting of
4623 the string. Ex:
4624 toString({1, 2, 3}, intString, 'nums', '{', ';', '}', true) =>
4625 'nums{1;2;3}'
4626 "
4627 input list<T> inList;
4628 input FuncType inPrintFunc;
4629 input String inNameStr = "" "The name of the list.";
4630 input String inBeginStr = "{" "The start of the list";
4631 input String inDelimitStr = ", " "The delimiter between list elements.";
4632 input String inEndStr = "}" "The end of the list.";
4633 input Boolean inPrintEmpty = true "If false, don't output begin and end if the list is empty.";
4634 input Integer maxLength = 0 "If > 0, only the first maxLength elements are printed";
4635 output String outString;
4636
4637 partial function FuncType
4638 input T t;
4639 output String s;
4640 end FuncType;
4641 protected
4642 list<T> lst = inList;
4643 String endStr = inEndStr;
4644 algorithm
4645
4/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 594597 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 15 times.
594614 if maxLength > 0 and listLength(lst) > maxLength then
4646 2 lst := firstN(lst, maxLength);
4647 2 endStr := stringAppendList({inDelimitStr, "...", endStr});
4648 end if;
4649
4650 outString := match(lst, inPrintEmpty)
4651 local
4652 String str;
4653
4654 // Empty list and inPrintEmpty true => concatenate the list name, begin
4655 // string and end string.
4656 case ({}, true)
4657 257 then stringAppendList({inNameStr, inBeginStr, endStr});
4658
4659 // Empty list and inPrintEmpty false => output only list name.
4660 case ({}, false)
4661 then inNameStr;
4662
4663 else
4664 algorithm
4665 93435 str := stringDelimitList(map(lst, inPrintFunc), inDelimitStr);
4666 93435 str := stringAppendList({inNameStr, inBeginStr, str, endStr});
4667 then
4668 str;
4669
4670 end match;
4671 end toStringCustom;
4672
4673 public function hasOneElement<T>
4674 "@author:adrpo
4675 returns true if the list has exactly one element, otherwise false"
4676 input list<T> inList;
4677 output Boolean b;
4678 algorithm
4679 b := match inList
4680 case {_} then true;
4681 else false;
4682 end match;
4683 end hasOneElement;
4684
4685 public function hasSeveralElements<T>
4686 "author:waurich
4687 returns true if the list has more than one element, otherwise false"
4688 input list<T> inList;
4689 output Boolean b;
4690 algorithm
4691 b := match inList
4692 case {_} then false;
4693 case {} then false;
4694 else true;
4695 end match;
4696 end hasSeveralElements;
4697
4698 public function lengthListElements<T>
4699 input list<list<T>> inListList;
4700 output Integer outLength;
4701 algorithm
4702
4/4
✓ Branch 0 taken 49330 times.
✓ Branch 1 taken 9425 times.
✓ Branch 2 taken 49330 times.
✓ Branch 3 taken 9425 times.
58755 outLength := sum(listLength(lst) for lst in inListList);
4703 end lengthListElements;
4704
4705 public function accumulateMapAccum<TI, TO>
4706 "Takes a list, a function and a result list. The function is applied to each
4707 element of the list, and the function is itself responsible for adding
4708 elements to the result list."
4709 input list<TI> inList;
4710 input MapFunc inMapFunc;
4711 output list<TO> outList = {};
4712
4713 partial function MapFunc
4714 input TI inElement;
4715 input list<TO> inAccumList;
4716 output list<TO> outList;
4717 end MapFunc;
4718 algorithm
4719
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 144 times.
434 for e in inList loop
4720
1/2
✓ Branch 0 taken 290 times.
✗ Branch 1 not taken.
290 outList := inMapFunc(e, outList);
4721 end for;
4722 144 outList := listReverse(outList);
4723 end accumulateMapAccum;
4724
4725 public function findMap<T>
4726 "Same as map, but stops when it find a certain element as indicated by the
4727 mapping function. Returns the new list, and whether the element was found or
4728 not."
4729 input list<T> inList;
4730 input FuncType inFunc;
4731 output list<T> outList = {};
4732 output Boolean outFound = false;
4733
4734 partial function FuncType
4735 input T inElement;
4736 output T outElement;
4737 output Boolean outFound;
4738 end FuncType;
4739 protected
4740 T e;
4741 list<T> rest = inList;
4742 algorithm
4743
4/4
✓ Branch 0 taken 1536603 times.
✓ Branch 1 taken 938073 times.
✓ Branch 2 taken 1526036 times.
✓ Branch 3 taken 10567 times.
2474676 while not listEmpty(rest) and not outFound loop
4744 1526036 e :: rest := rest;
4745
1/2
✓ Branch 0 taken 1526036 times.
✗ Branch 1 not taken.
1526036 (e, outFound) := inFunc(e);
4746 outList := e :: outList;
4747 end while;
4748
4749 948640 outList := append_reverse(outList, rest);
4750 end findMap;
4751
4752 public function findAndMap<T>
4753 "Applies a function to the first element in the list for which the predicate
4754 function returns true, and returns the new list as well as whether the
4755 element was found or not."
4756 input list<T> inList;
4757 input PredFunc pred;
4758 input Func func;
4759 output list<T> outList = {};
4760 output Boolean found = false;
4761
4762 partial function PredFunc
4763 input T e;
4764 output Boolean result;
4765 end PredFunc;
4766
4767 partial function Func
4768 input output T e;
4769 end Func;
4770 protected
4771 T e;
4772 list<T> rest = inList;
4773 algorithm
4774
4/4
✓ Branch 0 taken 401 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 335 times.
✓ Branch 3 taken 66 times.
567 while not listEmpty(rest) and not found loop
4775 335 e :: rest := rest;
4776
4777
3/4
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 155 times.
✓ Branch 5 taken 180 times.
335 if pred(e) then
4778
1/2
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
155 e := func(e);
4779 found := true;
4780 end if;
4781
4782 outList := e :: outList;
4783 end while;
4784
4785
2/2
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 77 times.
232 if found then
4786 155 outList := append_reverse(outList, rest);
4787 else
4788 outList := inList;
4789 end if;
4790 end findAndMap;
4791
4792 public function findSome<T1,T2>
4793 "Applies the given function over the list and returns either the first SOME()
4794 value the function returns or NONE() if no SOME() is returned."
4795 input list<T1> inList;
4796 input FuncType inFunc;
4797 output Option<T2> outVal = NONE();
4798
4799 partial function FuncType
4800 input T1 inElement;
4801 output Option<T2> outValOpt;
4802 end FuncType;
4803 algorithm
4804
2/2
✓ Branch 0 taken 1395 times.
✓ Branch 1 taken 2578 times.
3973 for e in inList loop
4805
2/2
✓ Branch 0 taken 1380 times.
✓ Branch 1 taken 15 times.
1395 outVal := inFunc(e);
4806
4807
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1395 times.
✓ Branch 2 taken 899 times.
✓ Branch 3 taken 496 times.
1395 if isSome(outVal) then
4808 496 return;
4809 end if;
4810 end for;
4811 end findSome;
4812
4813 public function splitEqualPrefix<T1, T2>
4814 input list<T1> inFullList;
4815 input list<T2> inPrefixList;
4816 input EqFunc inEqFunc;
4817 input list<T1> inAccum = {};
4818 output list<T1> outPrefix = {};
4819 output list<T1> outRest;
4820
4821 partial function EqFunc
4822 input T1 inElem1;
4823 input T2 inElem2;
4824 output Boolean outIsEqual;
4825 end EqFunc;
4826 protected
4827 T1 e1;
4828 T2 e2;
4829 list<T1> rest_e1 = inFullList;
4830 list<T2> rest_e2 = inPrefixList;
4831 algorithm
4832 1767 while true loop
4833
4/4
✓ Branch 0 taken 5901 times.
✓ Branch 1 taken 741 times.
✓ Branch 2 taken 3392 times.
✓ Branch 3 taken 2509 times.
6642 if listEmpty(rest_e1) or listEmpty(rest_e2) then
4834 break;
4835 end if;
4836
4837 3392 e1 :: rest_e1 := rest_e1;
4838 3392 e2 :: rest_e2 := rest_e2;
4839
4840
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3392 times.
✓ Branch 4 taken 1767 times.
✓ Branch 5 taken 1625 times.
3392 if not inEqFunc(e1, e2) then
4841 break;
4842 end if;
4843
4844 outPrefix := e1 :: outPrefix;
4845 end while;
4846
4847 4875 outPrefix := listReverseInPlace(outPrefix);
4848 outRest := rest_e1;
4849 end splitEqualPrefix;
4850
4851 public function combination<TI>
4852 "Takes a two-dimensional list and creates a list combinations
4853 given by the cartesian product of the sublists.
4854
4855 Ex: combination({{1, 2}, {3}, {4, 5}}) =>
4856 {{1, 3, 4}, {1, 3, 5}, {2, 3, 4}, {2, 3, 5}}
4857 "
4858 input list<list<TI>> inElements;
4859 output list<list<TI>> outElements;
4860 protected
4861 list<list<TI>> elems;
4862 algorithm
4863
2/2
✓ Branch 0 taken 1231333 times.
✓ Branch 1 taken 24348 times.
1255681 if listEmpty(inElements) then
4864 outElements := {};
4865 else
4866 1231333 elems := combination_tail(inElements, {}, {});
4867 1231333 outElements := listReverse(elems);
4868 end if;
4869 end combination;
4870
4871 protected function combination_tail<TI>
4872 input list<list<TI>> inElements;
4873 input list<TI> inCombination;
4874 input list<list<TI>> inAccumElems;
4875 output list<list<TI>> outElements;
4876 algorithm
4877 outElements := match inElements
4878 local
4879 list<TI> head;
4880 list<list<TI>> rest;
4881 list<list<TI>> acc;
4882
4883 case head :: rest
4884 algorithm
4885 acc := inAccumElems;
4886
2/2
✓ Branch 1 taken 2058343 times.
✓ Branch 2 taken 1496889 times.
3555232 for e in head loop
4887 2058343 acc := combination_tail(rest, e :: inCombination, acc);
4888 end for;
4889 then
4890 acc;
4891
4892 1792787 else listReverse(inCombination) :: inAccumElems;
4893
4894 end match;
4895 end combination_tail;
4896
4897 public function combinationMap<TI, TO>
4898 "Takes a two-dimensional list and calls the given function on the combinations
4899 given by the cartesian product of the sublists.
4900
4901 Ex: combinationMap({{1, 2}, {3}, {4, 5}}, func) =>
4902 {func({1, 3, 4}), func({1, 3, 5}), func({2, 3, 4}), func({2, 3, 5})}
4903 "
4904 input list<list<TI>> inElements;
4905 input MapFunc inMapFunc;
4906 output list<TO> outElements;
4907
4908 partial function MapFunc
4909 input list<TI> inElements;
4910 output TO outElement;
4911 end MapFunc;
4912 protected
4913 list<TO> elems;
4914 algorithm
4915 73 elems := combinationMap_tail(inElements, inMapFunc, {}, {});
4916 73 outElements := listReverse(elems);
4917 end combinationMap;
4918
4919 protected function combinationMap_tail<TI, TO>
4920 input list<list<TI>> inElements;
4921 input MapFunc inMapFunc;
4922 input list<TI> inCombination;
4923 input list<TO> inAccumElems;
4924 output list<TO> outElements;
4925
4926 partial function MapFunc
4927 input list<TI> inElements;
4928 output TO outElement;
4929 end MapFunc;
4930 algorithm
4931 outElements := match inElements
4932 local
4933 list<TI> head;
4934 list<list<TI>> rest;
4935 list<TO> acc;
4936
4937 case head :: rest
4938 algorithm
4939 acc := inAccumElems;
4940
2/2
✓ Branch 1 taken 157 times.
✓ Branch 2 taken 94 times.
251 for e in head loop
4941 157 acc := combinationMap_tail(rest, inMapFunc, e :: inCombination, acc);
4942 end for;
4943 then
4944 acc;
4945
4946
1/2
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
136 else inMapFunc(listReverse(inCombination)) :: inAccumElems;
4947
4948 end match;
4949 end combinationMap_tail;
4950
4951 public function allReferenceEq<T>
4952 "Checks if all elements in the lists have equal references"
4953 input list<T> inList1;
4954 input list<T> inList2;
4955 output Boolean outEqual;
4956 protected
4957 list<T> rest1 = inList1, rest2 = inList2;
4958 T e1, e2;
4959 algorithm
4960
4/4
✓ Branch 0 taken 560000 times.
✓ Branch 1 taken 226483 times.
✓ Branch 2 taken 559998 times.
✓ Branch 3 taken 2 times.
786483 while not (listEmpty(rest1) or listEmpty(rest2)) loop
4961 559998 e1 :: rest1 := rest1;
4962 559998 e2 :: rest2 := rest2;
4963
4964
2/2
✓ Branch 0 taken 504864 times.
✓ Branch 1 taken 55134 times.
559998 if not referenceEq(e1, e2) then
4965 outEqual := false;
4966 55134 return;
4967 end if;
4968 end while;
4969
4970
3/4
✓ Branch 0 taken 226483 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 226483 times.
226485 outEqual := listEmpty(rest1) and listEmpty(rest2);
4971 end allReferenceEq;
4972
4973 public function listIsLonger<T>
4974 "Returns true if inList1 is longer than inList2, otherwise false."
4975 input list<T> inList1;
4976 input list<T> inList2;
4977 output Boolean isLonger = compareLength(inList1, inList2) > 0;
4978 end listIsLonger;
4979
4980 public function toListWithPositions<T>
4981 input list<T> inList;
4982 output list<tuple<T, Integer>> outList = {};
4983 protected
4984 Integer pos = 1;
4985 algorithm
4986
2/2
✓ Branch 1 taken 9524 times.
✓ Branch 2 taken 5161 times.
14685 for e in inList loop
4987 9524 outList := (e, pos) :: outList;
4988 9524 pos := pos + 1;
4989 end for;
4990 5161 outList := listReverseInPlace(outList);
4991 end toListWithPositions;
4992
4993 public function mkOption<T>
4994 "@author: adrpo
4995 make NONE() if the list is empty
4996 make SOME(list) if the list is not empty"
4997 input list<T> inList;
4998 output Option<list<T>> outOption;
4999 algorithm
5000 ✗ outOption := if listEmpty(inList) then NONE() else SOME(inList);
5001 end mkOption;
5002
5003 public function all<T>
5004 "Returns true if the given predicate function returns true for all elements in
5005 the given list."
5006 input list<T> inList;
5007 input PredFunc inFunc;
5008 output Boolean outResult;
5009
5010 partial function PredFunc
5011 input T inElement;
5012 output Boolean outMatch;
5013 end PredFunc;
5014 algorithm
5015
2/2
✓ Branch 0 taken 2587583 times.
✓ Branch 1 taken 1761884 times.
4349467 for e in inList loop
5016
4/4
✓ Branch 0 taken 162010 times.
✓ Branch 1 taken 2425573 times.
✓ Branch 4 taken 511775 times.
✓ Branch 5 taken 1911315 times.
2587583 if not inFunc(e) then
5017 outResult := false;
5018 511775 return;
5019 end if;
5020 end for;
5021
5022 outResult := true;
5023 end all;
5024
5025 public function none<T>
5026 "Returns true if the given predicate function returns false for all elements in
5027 the given list."
5028 input list<T> inList;
5029 input PredFunc inFunc;
5030 output Boolean outResult;
5031
5032 partial function PredFunc
5033 input T inElement;
5034 output Boolean outMatch;
5035 end PredFunc;
5036 algorithm
5037
2/2
✓ Branch 0 taken 213743 times.
✓ Branch 1 taken 4620391 times.
4834134 for e in inList loop
5038
4/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 213714 times.
✓ Branch 4 taken 19409 times.
✓ Branch 5 taken 194334 times.
213743 if inFunc(e) then
5039 outResult := false;
5040 19409 return;
5041 end if;
5042 end for;
5043
5044 outResult := true;
5045 end none;
5046
5047 public function any<T>
5048 "Returns true if the given predicate function returns true for any element in
5049 the given list."
5050 input list<T> inList;
5051 input PredFunc inFunc;
5052 output Boolean outResult;
5053
5054 partial function PredFunc
5055 input T inElement;
5056 output Boolean outMatch;
5057 end PredFunc;
5058 algorithm
5059
2/2
✓ Branch 0 taken 12333111 times.
✓ Branch 1 taken 3890186 times.
16223297 for e in inList loop
5060
4/4
✓ Branch 0 taken 26746 times.
✓ Branch 1 taken 12306365 times.
✓ Branch 4 taken 3466214 times.
✓ Branch 5 taken 8866896 times.
12333111 if inFunc(e) then
5061 outResult := true;
5062 3466214 return;
5063 end if;
5064 end for;
5065
5066 outResult := false;
5067 end any;
5068
5069 public function count<T>
5070 "Counts the number of elements the function returns true for"
5071 input list<T> inList;
5072 input PredFunc inFunc;
5073 output Integer outResult = 0;
5074
5075 partial function PredFunc
5076 input T inElement;
5077 output Boolean outMatch;
5078 end PredFunc;
5079 algorithm
5080
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 188 times.
200 for e in inList loop
5081
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 11 times.
12 if inFunc(e) then
5082 1 outResult := outResult + 1;
5083 end if;
5084 end for;
5085 end count;
5086
5087 public function separateOnTrue<T>
5088 "Takes a list of values and a filter function over the values and returns 2
5089 sub lists of values for which the matching function returns true and false."
5090 input list<T> inList;
5091 input FilterFunc inFilterFunc;
5092 output list<T> outListTrue = {};
5093 output list<T> outListFalse = {};
5094
5095 partial function FilterFunc
5096 input T inElement;
5097 output Boolean outResult;
5098 end FilterFunc;
5099 algorithm
5100
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 1069 times.
1131 for e in inList loop
5101
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
✓ Branch 4 taken 62 times.
✗ Branch 5 not taken.
62 if inFilterFunc(e) then
5102 outListTrue := e::outListTrue;
5103 else
5104 outListFalse := e::outListFalse;
5105 end if;
5106 end for;
5107 end separateOnTrue;
5108
5109 public function separate1OnTrue<T, ArgT1>
5110 "Takes a list of values and a filter function over the values and returns 2
5111 sub lists of values for which the matching function returns true and false."
5112 input list<T> inList;
5113 input FilterFunc inFilterFunc;
5114 input ArgT1 inArg1;
5115 output list<T> outListTrue = {};
5116 output list<T> outListFalse = {};
5117
5118 partial function FilterFunc
5119 input T inElement;
5120 input ArgT1 inArg1;
5121 output Boolean outResult;
5122 end FilterFunc;
5123 algorithm
5124 ✗ for e in inList loop
5125 ✗ if inFilterFunc(e, inArg1) then
5126 outListTrue := e::outListTrue;
5127 else
5128 outListFalse := e::outListFalse;
5129 end if;
5130 end for;
5131 end separate1OnTrue;
5132
5133 function mapIndices<T>
5134 "Applies a function to only the elements given by the sorted list of indices."
5135 input list<T> inList;
5136 input list<Integer> indices;
5137 input MapFunc func;
5138 output list<T> outList;
5139
5140 partial function MapFunc
5141 input output T e;
5142 end MapFunc;
5143 protected
5144 Integer i = 1, idx;
5145 list<Integer> rest_idx;
5146 T e;
5147 list<T> rest_lst;
5148 algorithm
5149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1523 times.
1523 if listEmpty(indices) then
5150 outList := inList;
5151 ✗ return;
5152 end if;
5153
5154 1523 idx :: rest_idx := indices;
5155 rest_lst := inList;
5156 outList := {};
5157
5158
1/2
✓ Branch 0 taken 4631 times.
✗ Branch 1 not taken.
4631 while not listEmpty(rest_lst) loop
5159 4631 e :: rest_lst := rest_lst;
5160
5161
2/2
✓ Branch 0 taken 3939 times.
✓ Branch 1 taken 692 times.
4631 if i == idx then
5162
1/2
✓ Branch 0 taken 3939 times.
✗ Branch 1 not taken.
3939 outList := func(e) :: outList;
5163
5164
2/2
✓ Branch 0 taken 1523 times.
✓ Branch 1 taken 2416 times.
3939 if listEmpty(rest_idx) then
5165 1523 outList := append_reverse(rest_lst, outList);
5166 1523 break;
5167 else
5168 2416 idx :: rest_idx := rest_idx;
5169 end if;
5170 else
5171 outList := e :: outList;
5172 end if;
5173
5174 3108 i := i + 1;
5175 end while;
5176
5177 1523 outList := listReverseInPlace(outList);
5178 end mapIndices;
5179
5180 public function allCombinations<T>
5181 "{{1,2,3},{4,5},{6}} => {{1,4,6},{1,5,6},{2,4,6},...}.
5182 The output is a 2-dim list with lengths (len1*len2*...*lenN)) and N.
5183
5184 This function screams WARNING I USE COMBINATORIAL EXPLOSION.
5185 So there are flags that limit the size of the set it works on."
5186 input list<list<T>> lst;
5187 input Option<Integer> maxTotalSize;
5188 input SourceInfo info;
5189 output list<list<T>> out;
5190 algorithm
5191 out := match maxTotalSize
5192 local
5193 Integer sz,maxSz;
5194 case SOME(maxSz)
5195 algorithm
5196 131 sz := intMul(listLength(lst), applyAndFold(lst,intMul,listLength,1));
5197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131 times.
131 true := (sz <= maxSz);
5198 131 then allCombinations2(lst);
5199 2201 case NONE() then allCombinations2(lst);
5200 /*
5201 case (_,SOME(_),_)
5202 algorithm
5203 Error.addSourceMessage(Error.COMPILER_NOTIFICATION, {"List.allCombinations failed because the input was too large"}, info);
5204 then fail();
5205 */
5206 end match;
5207 end allCombinations;
5208
5209 protected function allCombinations2<T>
5210 "{{1,2,3},{4,5},{6}} => {{1,4,6},{1,5,6},{2,4,6},...}.
5211 The output is a 2-dim list with lengths (len1*len2*...*lenN)) and N.
5212
5213 This function screams WARNING I USE COMBINATORIAL EXPLOSION."
5214 input list<list<T>> ilst;
5215 output list<list<T>> out;
5216 algorithm
5217 out := match ilst
5218 local
5219 list<T> x;
5220 list<list<T>> lst;
5221 case {} then {};
5222 case x::lst
5223 algorithm
5224 2949 lst := allCombinations2(lst);
5225 2949 then allCombinations3(x, lst, {});
5226 end match;
5227 end allCombinations2;
5228
5229 protected function allCombinations3<T>
5230 input list<T> ilst1;
5231 input list<list<T>> ilst2;
5232 input list<list<T>> iacc;
5233 output list<list<T>> out;
5234 algorithm
5235 out := match ilst1
5236 local
5237 T x;
5238 list<T> lst1;
5239 list<list<T>> acc;
5240 2949 case {} then listReverse(iacc);
5241 case x::lst1
5242 algorithm
5243 9829 acc := allCombinations4(x, ilst2, iacc);
5244 9829 then allCombinations3(lst1, ilst2, acc);
5245 end match;
5246 end allCombinations3;
5247
5248 protected function allCombinations4<T>
5249 input T x;
5250 input list<list<T>> ilst;
5251 input list<list<T>> iacc;
5252 output list<list<T>> out;
5253 protected
5254 list<list<T>> acc = iacc;
5255 algorithm
5256
2/2
✓ Branch 0 taken 1940 times.
✓ Branch 1 taken 7889 times.
9829 if listEmpty(ilst) then
5257 out := {x} :: acc;
5258 7889 return;
5259 end if;
5260
2/2
✓ Branch 1 taken 5636 times.
✓ Branch 2 taken 1940 times.
7576 for l in ilst loop
5261 acc := (x::l)::acc;
5262 end for;
5263 out := acc;
5264 end allCombinations4;
5265
5266 public function contains<T>
5267 input list<T> lst;
5268 input T elem;
5269 input equalityFunc eqFunc;
5270 partial function equalityFunc
5271 input T t1;
5272 input T t2;
5273 output Boolean res;
5274 end equalityFunc;
5275 output Boolean res = false;
5276 algorithm
5277
2/2
✓ Branch 0 taken 19762 times.
✓ Branch 1 taken 6882 times.
26644 for i in lst loop
5278
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19762 times.
✓ Branch 4 taken 980 times.
✓ Branch 5 taken 18782 times.
19762 if eqFunc(i, elem) then
5279 res := true;
5280 980 return;
5281 end if;
5282 end for;
5283 end contains;
5284
5285 function minElement<T>
5286 "Returns the smallest element in the list, or fails if the list is empty."
5287 input list<T> inList;
5288 input LessFn lessFn;
5289 output T res;
5290
5291 partial function LessFn
5292 "Returns true if e1 < e2, otherwise false."
5293 input T e1;
5294 input T e2;
5295 output Boolean res;
5296 end LessFn;
5297 algorithm
5298 427 res := listHead(inList);
5299
5300
2/2
✓ Branch 1 taken 293 times.
✓ Branch 2 taken 427 times.
720 for e in listRest(inList) loop
5301
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 293 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 278 times.
293 if lessFn(e, res) then
5302 res := e;
5303 end if;
5304 end for;
5305 end minElement;
5306
5307 function maxElement<T>
5308 "Returns the largest element in the list, or fails if the list is empty."
5309 input list<T> inList;
5310 input LessFn lessFn;
5311 output T res;
5312
5313 partial function LessFn
5314 "Returns true if e1 < e2, otherwise false."
5315 input T e1;
5316 input T e2;
5317 output Boolean res;
5318 end LessFn;
5319 algorithm
5320 371 res := listHead(inList);
5321
5322
2/2
✓ Branch 1 taken 310 times.
✓ Branch 2 taken 371 times.
681 for e in listRest(inList) loop
5323
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 310 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 298 times.
310 if lessFn(res, e) then
5324 res := e;
5325 end if;
5326 end for;
5327 end maxElement;
5328
5329 function trim<T>
5330 "Removes elements from the head of the list while the given function returns
5331 true for the first element, or until the list is empty."
5332 input output list<T> l;
5333 input PredFn fn;
5334
5335 partial function PredFn
5336 input T e;
5337 output Boolean res;
5338 end PredFn;
5339 algorithm
5340
5/8
✓ Branch 0 taken 178649 times.
✓ Branch 1 taken 703797 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 178649 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 10 taken 92168 times.
✓ Branch 11 taken 86481 times.
882446 while not listEmpty(l) and fn(listHead(l)) loop
5341 86481 l := listRest(l);
5342 end while;
5343 end trim;
5344
5345 function apply<T>
5346 "Applies a function to all the elements in the given list."
5347 input list<T> lst;
5348 input Fn fn;
5349
5350 partial function Fn
5351 input T e;
5352 end Fn;
5353 algorithm
5354
2/2
✓ Branch 0 taken 402583 times.
✓ Branch 1 taken 6540 times.
409123 for e in lst loop
5355
1/2
✓ Branch 0 taken 402583 times.
✗ Branch 1 not taken.
402583 fn(e);
5356 end for;
5357 end apply;
5358
5359 annotation(__OpenModelica_Interface="util_datatypes_basic");
5360 end List;
5361