001/*
002 * $Id: LIST.java 4987 2014-11-22 18:26:30Z kredel $
003 */
004
005package edu.mas.kern;
006
007
008import java.util.Collections;
009import java.util.Iterator;
010import java.util.LinkedList;
011import java.util.List;
012
013
014/**
015 * MAS and SAC2/Aldes LIST emulation and adaptor class.
016 * @author Heinz Kredel
017 */
018
019public class LIST<C> {
020
021
022    public static final LIST<?> SIL = null; // not usable
023
024
025    /**
026     * Internal data structure.
027     */
028    protected LinkedList<C> list = null; // List list not ok
029
030
031    /**
032     * Internal iterator.
033     */
034    protected Iterator<C> iter = null;
035
036
037    /**
038     * LIST constructor.
039     */
040    public LIST() {
041        this(new LinkedList<C>());
042    }
043
044
045    /**
046     * internal LIST constructor.
047     * @param l
048     */
049    protected LIST(LinkedList<C> l) {
050        list = l;
051        iter = null;
052    }
053
054
055    /**
056     * LIST constructor.
057     * @param l any Java List
058     */
059    public LIST(List<C> l) {
060        this(new LinkedList<C>(l));
061    }
062
063
064    /**
065     * Is null. Test if the list L is null.
066     */
067    protected static <C> boolean isNull(LIST<C> L) {
068        if (L == null || L.list == null) {
069            return true;
070        }
071        return false;
072    }
073
074
075    /**
076     * Is empty. Test if the list L is empty.
077     */
078    public static <C> boolean isEmpty(LIST<C> L) {
079        if (isNull(L) || L.list.isEmpty()) {
080            return true;
081        }
082        if (L.iter != null) {
083            return !L.iter.hasNext();
084        }
085        return false;
086    }
087
088
089    /**
090     * Length. L is a list. Returns length(L).
091     */
092    public static <C> int LENGTH(LIST<C> L) {
093        if (isNull(L)) {
094            return 0;
095        }
096        return L.list.size();
097    }
098
099
100    /**
101     * First. L is a non-null list. a is the first element of L.
102     */
103    public static <C> C FIRST(LIST<C> L) {
104        if (isNull(L)) {
105            return null;
106        }
107        if (L.iter != null) {
108            if (L.iter.hasNext()) {
109                return L.iter.next();
110            }
111            L.iter = null;
112            return null;
113        }
114        return L.list.getFirst();
115    }
116
117
118    /**
119     * Reductum. L is a non-null list. Returns the reductum of L.
120     */
121    public static <C> LIST<C> RED(LIST<C> L) {
122        if (isNull(L)) {
123            return L;
124        }
125        LIST<C> LP = L;
126        // ok: LP = new LIST<C>( L.list.subList(1,L.list.size()) );
127        if (L.iter == null) {
128            LP = new LIST<C>(L.list);
129            LP.iter = LP.list.iterator();
130            /*C x =*/LP.iter.next();
131            //System.out.println("x = " + x);
132        } // else noop
133        return LP;
134    }
135
136
137    /**
138     * Set first. L is a non-null list. a is a list. The first element of L is
139     * changed to a.
140     */
141    public static <C> void SFIRST(LIST<C> L, C a) {
142        if (!isNull(L)) {
143            L.list.set(0, a);
144        }
145    }
146
147
148    /**
149     * Set reductum. L is a non-null list. LP is a list. The reductum of L is
150     * changed to LP.
151     */
152    public static <C> void SRED(LIST<C> L, LIST<C> LP) {
153        if (!isNull(L)) {
154            L.list.subList(1, L.list.size()).clear();
155            if (!isEmpty(LP)) {
156                L.list.addAll(LP.list);
157            }
158        }
159
160    }
161
162
163    /**
164     * Composition. a is an object. L is a list. Returns the composition of a
165     * and L.
166     */
167    public static <C> LIST<C> COMP(C a, LIST<C> L) {
168        LIST<C> LP = L;
169        if (L == null) {
170            LP = new LIST<C>();
171        }
172        LP.list.addFirst(a);
173        return LP;
174    }
175
176
177    /**
178     * To string.
179     */
180    @Override
181    public String toString() {
182        if (isNull(this)) {
183            return "[]";
184        }
185        return list.toString();
186    }
187
188
189    /**
190     * Reductum. A is a list. i is a non-negative beta-integer not less than
191     * LENGTH(A). B=A, if i=0. Otherwise, B is the i-th reductum of A.
192     */
193    public static <C> LIST<C> REDUCT(LIST<C> L, int i) {
194        LIST<C> LP = null;
195        if (!isNull(L)) {
196            LP = new LIST<C>(L.list.subList(i, L.list.size()));
197        }
198        return LP;
199    }
200
201
202    /**
203     * Reductum 2. L is a list of length 2 or more. LP=RED(RED(L)).
204     */
205    public static <C> LIST<C> RED2(LIST<C> L) {
206        LIST<C> LP = null;
207        if (!isNull(L)) {
208            LP = new LIST<C>(L.list.subList(2, L.list.size()));
209        }
210        return LP;
211    }
212
213
214    /**
215     * Reductum 3. L is a list of length 3 or more. M is the third reductum of
216     * L.
217     */
218    public static <C> LIST<C> RED3(LIST<C> L) {
219        LIST<C> LP = null;
220        if (!isNull(L)) {
221            LP = new LIST<C>(L.list.subList(3, L.list.size()));
222        }
223        return LP;
224    }
225
226
227    /**
228     * Reductum 4. L is a list of length 4 or more. M is the fourth reductum of
229     * L.
230     */
231    public static <C> LIST<C> RED4(LIST<C> L) {
232        LIST<C> LP = null;
233        if (!isNull(L)) {
234            LP = new LIST<C>(L.list.subList(42, L.list.size()));
235        }
236        return LP;
237    }
238
239
240    /**
241     * Clock. Returns the current CPU clock reading in milliseconds. Intervalls
242     * are system dependent.
243     */
244    public static long CLOCK() {
245        return java.lang.System.currentTimeMillis();
246    }
247
248
249    /**
250     * List element. A is a list. 1 le i le LENGTH(A). a is the i-th element of
251     * A.
252     */
253    public static <C> C LELT(LIST<C> L, int i) {
254        C x = null;
255        if (!isNull(L)) {
256            x = L.list.get(i);
257        }
258        return x;
259    }
260
261
262    /**
263     * Second. L is a list of length 2 or more. a is the second element of L.
264     */
265    public static <C> C SECOND(LIST<C> L) {
266        C x = null;
267        if (!isNull(L)) {
268            x = L.list.get(2);
269        }
270        return x;
271    }
272
273
274    /**
275     * Third. L is a list of length 3 or more. a is the third element of L.
276     */
277    public static <C> C THIRD(LIST<C> L) {
278        C x = null;
279        if (!isNull(L)) {
280            x = L.list.get(3);
281        }
282        return x;
283    }
284
285
286    /**
287     * Fourth. L is a list of length 4 or more. a is the fourth element of L.
288     */
289    public static <C> C FOURTH(LIST<C> L) {
290        C x = null;
291        if (!isNull(L)) {
292            x = L.list.get(4);
293        }
294        return x;
295    }
296
297
298    /**
299     * Constructive concatenation. L1 and L2 are lists. L is the concatenation
300     * of L1 and L2. The list L is constructed.
301     */
302    public static <C> LIST<C> CCONC(LIST<C> L1, LIST<C> L2) {
303        if (isNull(L1)) {
304            return L2;
305        }
306        if (isNull(L2)) {
307            return L1;
308        }
309        LinkedList<C> list = new LinkedList<C>(L1.list);
310        list.addAll(L2.list);
311        return new LIST<C>(list);
312    }
313
314
315    /**
316     * Constructive inverse. L is a list. M=INV(L). M is constructed using COMP.
317     */
318    public static <C> LIST<C> CINV(LIST<C> L) {
319        if (isNull(L)) {
320            return L;
321        }
322        LinkedList<C> list = new LinkedList<C>(L.list);
323        Collections.reverse(list);
324        return new LIST<C>(list);
325    }
326
327
328    /**
329     * Inverse. L is a list. The inverse of L is returned. The list L is
330     * modified.
331     */
332    public static <C> LIST<C> INV(LIST<C> L) {
333        if (isNull(L)) {
334            return L;
335        }
336        Collections.reverse(L.list);
337        return L;
338    }
339
340
341    /**
342     * Composition 2. a and b are objects. L is a list. M=COMP(a,COMP(b,L)).
343     */
344    public static <C> LIST<C> COMP2(C a, C b, LIST<C> L) {
345        LIST<C> LP = L;
346        if (L == null) {
347            LP = new LIST<C>();
348        }
349        LP.list.addFirst(b);
350        LP.list.addFirst(a);
351        return LP;
352    }
353
354
355    /**
356     * Composition 3. a1, a2 and a3 are objects. L is a list.
357     * M=COMP(a1,COMP(a2,COMP(a3,L))).
358     */
359    public static <C> LIST<C> COMP3(C a, C b, C c, LIST<C> L) {
360        LIST<C> LP = L;
361        if (L == null) {
362            LP = new LIST<C>();
363        }
364        LP.list.addFirst(c);
365        LP.list.addFirst(b);
366        LP.list.addFirst(a);
367        return LP;
368    }
369
370
371    /**
372     * Composition 4. a1, a2, a3 and a4 are objects. L is a list.
373     * M=COMP(a1,COMP(a2,COMP(a3,COMP(a4,l)))).
374     */
375    public static <C> LIST<C> COMP3(C a, C b, C c, C d, LIST<C> L) {
376        LIST<C> LP = L;
377        if (L == null) {
378            LP = new LIST<C>();
379        }
380        LP.list.addFirst(d);
381        LP.list.addFirst(c);
382        LP.list.addFirst(b);
383        LP.list.addFirst(a);
384        return LP;
385    }
386
387
388    /**
389     * Concatenation. L1 and L2 are lists. L=CONC(L1,L2). The list L1 is
390     * modified.
391     */
392    public static <C> LIST<C> CONC(LIST<C> L1, LIST<C> L2) {
393        if (isNull(L1)) {
394            return L2;
395        }
396        if (isNull(L2)) {
397            return L1;
398        }
399        L1.list.addAll(L2.list);
400        return L1;
401    }
402
403
404    /**
405     * Equal. a and b are objects. t=true if a and b are equal and otherwise
406     * t=false.
407     */
408    public static <C> boolean EQUAL(LIST<C> L1, LIST<C> L2) {
409        if (isNull(L1)) {
410            return isNull(L2);
411        }
412        if (isNull(L2)) {
413            return isNull(L1);
414        }
415        return L1.list.equals(L2.list);
416    }
417
418
419    /**
420     * Extent. L is a list. n the number of cells of L.
421     */
422    public static <C> int EXTENT(LIST<C> L) {
423        if (isNull(L)) {
424            return 0;
425        }
426        int n = 0;
427        for (C a : L.list) {
428            if (a instanceof LIST) {
429                LIST<C> LP = null;
430                try {
431                    LP = (LIST<C>) a;
432                } catch (ClassCastException e) {
433                }
434                if (isNull(LP)) {
435                    n++;
436                } else {
437                    n += EXTENT(LP);
438                }
439            } else {
440                n++;
441            }
442        }
443        return n;
444    }
445
446
447    /**
448     * List, 1 element. a in an object. L is the list (a).
449     */
450    public static <C> LIST<C> LIST1(C a) {
451        LIST<C> L = new LIST<C>();
452        L.list.addFirst(a);
453        return L;
454    }
455
456
457    /**
458     * List, 10 elements. a1, a2, a3, a4, a5, a6, a7, a8, a9 and a10 are
459     * objects. L is the list (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10).
460     */
461    public static <C> LIST<C> LIST10(C a1, C a2, C a3, C a4, C a5, C a6, C a7, C a8, C a9, C a10) {
462        LIST<C> L = new LIST<C>();
463        L.list.addFirst(a10);
464        L.list.addFirst(a9);
465        L.list.addFirst(a8);
466        L.list.addFirst(a7);
467        L.list.addFirst(a6);
468        L.list.addFirst(a5);
469        L.list.addFirst(a4);
470        L.list.addFirst(a3);
471        L.list.addFirst(a2);
472        L.list.addFirst(a1);
473        return L;
474    }
475
476
477    /**
478     * List, 2 elements. a and b are objects. L is the list (a,b).
479     */
480    public static <C> LIST<C> LIST2(C a, C b) {
481        LIST<C> L = new LIST<C>();
482        L.list.addFirst(b);
483        L.list.addFirst(a);
484        return L;
485    }
486
487
488    /**
489     * List, 3 elements. a1, a2 and a3 are objects. L=(a1,a2,a3).
490     */
491    public static <C> LIST<C> LIST3(C a, C b, C c) {
492        LIST<C> L = new LIST<C>();
493        L.list.addFirst(c);
494        L.list.addFirst(b);
495        L.list.addFirst(a);
496        return L;
497    }
498
499
500    /**
501     * List, 4 elements. a1, a2, a3 and a4 are objects. L is the list
502     * (a1,a2,a3,a4).
503     */
504    public static <C> LIST<C> LIST4(C a, C b, C c, C d) {
505        LIST<C> L = new LIST<C>();
506        L.list.addFirst(d);
507        L.list.addFirst(c);
508        L.list.addFirst(b);
509        L.list.addFirst(a);
510        return L;
511    }
512
513
514    /**
515     * List, 5 elements. a1,a2,a3,a4 and a5 are objects. L is the list
516     * (a1,a2,a3,a4,a5).
517     */
518    public static <C> LIST<C> LIST5(C a, C b, C c, C d, C e) {
519        LIST<C> L = new LIST<C>();
520        L.list.addFirst(e);
521        L.list.addFirst(d);
522        L.list.addFirst(c);
523        L.list.addFirst(b);
524        L.list.addFirst(a);
525        return L;
526    }
527
528
529    /**
530     * Order. L is a list. maximal depth of L.
531     */
532    public static <C> int ORDER(LIST<C> L) {
533        if (isNull(L)) {
534            return 0;
535        }
536        int n = 0;
537        for (C a : L.list) {
538            if (a instanceof LIST) {
539                LIST<C> LP = null;
540                try {
541                    LP = (LIST<C>) a;
542                } catch (ClassCastException e) {
543                }
544                if (!isNull(LP)) {
545                    int o = ORDER(LP);
546                    if (o > n) { // max
547                        n = o;
548                    }
549                }
550            }
551        }
552        return n + 1;
553    }
554
555
556}