001// ***** This file is automatically generated from Quant.java.jpp and QuantBody.java.jpp.
002
003package daikon;
004
005import java.lang.reflect.Array;
006import java.lang.reflect.Field;
007import java.util.AbstractCollection;
008import java.util.Arrays;
009import java.util.Collection;
010import java.util.Iterator;
011
012import org.plumelib.util.ArraysPlume;
013import org.plumelib.util.Intern;
014import org.plumelib.util.FuzzyFloat;
015
016import org.checkerframework.checker.interning.qual.Interned;
017import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
018import org.checkerframework.checker.nullness.qual.Nullable;
019import org.checkerframework.checker.nullness.qual.PolyNull;
020import org.checkerframework.checker.signedness.qual.Signed;
021import org.checkerframework.dataflow.qual.Pure;
022import org.checkerframework.dataflow.qual.SideEffectFree;
023
024/**
025 * The Quant library provides routines that operate on arrays and collections.
026 *
027 * <p>These routines are used by the Java family of output formats. This allows invariants to be
028 * output as snippets of executable (Java) code. For example, an invariant like
029 * <pre>a[] elements &ge; 1</pre>
030 * is output (in the Java, JML, and DBC formats) as something like
031 *
032 * <pre>daikon.Quant.eltsGTE(a, 1)</pre>
033 *
034 * <h2>Naming</h2>
035 *
036 * The library methods have names of the following forms, where OP indicates an operation: Equal,
037 * NotEqual, GT (greater than), GTE (greater than or equal to), LT, LTE.
038 * <ul>
039 * <li>pairwiseOP. Apply OP to corresponding elements of two arrays:
040 *     a[0] OP b[0], a[1] OP b[1], etc.
041 * <li>eltsOP. Apply OP to each element of one array, and a scalar:
042 *     a[0] OP x, a[1] OP x, etc.
043 * <li>eltwiseOP: Apply OP to adjacent elements of one array:
044 *     a[0] OP a[1], a[1] OP a[2], etc.
045 * <li>lexOP: Determine lexical ordering:
046 *     compare two arrays pairwise, stopping as soon as the result is known.
047 * <li>eltsOPindex: Apply op to array elements and their indices:
048 *     a[0] OP 0, a[1] OP 1, etc.
049 * </ul>
050 *
051 * <h2>Equality semantics</h2>
052 *
053 * <p>Whenever a method involves comparing two elements for equality, this is always "==" equality
054 * (even for Objects and Strings).
055 *
056 * <h2>No exceptions thrown</h2>
057 *
058 * <p>The library strives not to throw exceptions, even if illegal arguments are passed to the
059 * routines. This has two consequences.
060 *
061 * <p>First, each predicate (boolean method) returns false when invoked on an illegal argument such
062 * as a null collection (array or Collection).
063 *
064 * <p>Second, each accessor method returns a default "bad" value if inovked on an illegal argument.
065 * For example, the default value for the double type is Double.NaN.
066 *
067 * <p>The rationale for the decision to never throw exceptions is that we wish to be able to invoke
068 * the Quant methods at run time without distrubing execution of a program, and without forcing
069 * clients to write a try .. catch block around each invocation.
070 *
071 * <p>A downside of the decision is that if the default value is returned, it may be impossible for
072 * a client to determine whether the method really returned that value, or whether the invocation
073 * involved an illegal argument. To avoid this problem, it is generally better to use a Quant
074 * library predicate rather than returning a value and then testing it externally.
075 */
076public final class Quant {
077  private Quant() { throw new Error("do not instantiate"); }
078
079  public static FuzzyFloat fuzzy = new FuzzyFloat();
080
081  /**
082   * Returns the size of the array or collection. If the argument is null or not an array or
083   * collection, returns a default value (Integer.MAX_VALUE). Thus, for an array a, this never
084   * throws an exception, though a.length may.
085   */
086  // Not called from Quant; provided only for external use.
087  @Pure
088  public static int size(Object o) {
089    if (o == null) {
090      return Integer.MAX_VALUE; // return default value
091    }
092    java.lang.Class<?> c = o.getClass();
093    if (c.isArray()) {
094      return java.lang.reflect.Array.getLength(o);
095    } else if (o instanceof Collection<?>) {
096      return ((Collection<?>)o).size();
097    } else {
098      return Integer.MAX_VALUE; // return default value
099    }
100  }
101
102  /** Returns the size of the collection.
103   * If the argument is null, returns a default value (Integer.MAX_VALUE).
104   */
105  // Not called from Quant; provided only for external use.
106  @Pure
107  public static int size(Collection<?> o) {
108    if (o == null) {
109      return Integer.MAX_VALUE; // return default value
110    }
111    return o.size();
112  }
113
114  /** True iff the sequence contains no null elements. */
115  @EnsuresNonNullIf(result=true, expression="#1")
116  @Pure
117  public static boolean eltsNonNull(Object[] seq1) {
118    if (seq1 == null) {
119      return false;
120    }
121    for (int i = 0 ; i < seq1.length ; i++) {
122      if (seq1[i] == null) {
123        return false;
124      }
125    }
126    return true;
127  }
128
129  ///////////////////////////////////////////////////////////////////////////
130  /// Methods for "boolean" (from QuantBody.java.jpp)
131  ///
132
133  /**
134   * Returns the ith element of the array or collection argument. If the argument is null or not an
135   * array or collection, returns a default value (false).
136   */
137
138  @EnsuresNonNullIf(result=true, expression="#1")
139
140  @Pure
141  public static boolean getElement_boolean(Object o, long i) {
142    if (o == null) {
143      return false; // return default value
144    }
145    java.lang.Class<?> c = o.getClass();
146    if (c.isArray()) {
147      return java.lang.reflect.Array.getBoolean(o, (int)i);
148    } else if (o instanceof java.util.AbstractCollection<?>) {
149      return java.lang.reflect.Array.getBoolean(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
150    } else {
151      return false; // return default value
152    }
153  }
154
155  @EnsuresNonNullIf(result=true, expression="#1")
156
157  @Pure
158  public static boolean getElement_boolean(boolean[] arr, long i) {
159    if (arr == null) {
160      return false; // return default value
161    }
162    return arr[(int)i];
163  }
164
165  private static boolean eq(boolean x, boolean y) {
166    return x == y;
167  }
168
169  private static boolean ne(boolean x, boolean y) {
170    return x != y;
171  }
172
173  /** True iff both sequences are non-null and have the same length. */
174  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
175  @Pure
176  public static boolean sameLength(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
177    return ((seq1 != null)
178            && (seq2 != null)
179            && seq1.length == seq2.length);
180  }
181
182  /**
183   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
184   *
185   * <p>If either array is null, returns null. If either array is empty, returns only those
186   * elements in the other array. If both arrays are empty, returns a new empty array.
187   */
188  @SideEffectFree
189  public static boolean @PolyNull [] concat(boolean @PolyNull [] seq1, boolean @PolyNull [] seq2) {
190    if (seq1 == null) {
191      return null;
192    }
193    if (seq2 == null) {
194      return null;
195    }
196    return ArraysPlume.concat(seq1, seq2);
197  }
198
199  /**
200   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
201   * assurances about the order or repetition of elements: elements may be repeated, and their
202   * order may be different from the order of elements in seq1 and seq2.
203   */
204  @SideEffectFree
205  public static boolean @PolyNull [] union(boolean @PolyNull [] seq1, boolean @PolyNull [] seq2) {
206    if (seq1 == null) {
207      return null;
208    }
209    if (seq2 == null) {
210      return null;
211    }
212    return concat(seq1, seq2);
213  }
214
215  /**
216   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
217   * gives no assurances about the order or repetition of elements: elements may be repeated, and
218   * their order may be different from the order of elements in seq1 and seq2.
219   */
220  @Pure
221  public static boolean @PolyNull [] intersection(boolean @PolyNull [] seq1, boolean @PolyNull [] seq2) {
222    if (seq1 == null) {
223      return null;
224    }
225    if (seq2 == null) {
226      return null;
227    }
228    boolean[] intermediate = new boolean[Math.min(seq1.length, seq2.length)];
229    int length = 0;
230    for (int i = 0 ; i < seq1.length ; i++) {
231      if (memberOf(seq1[i], seq2) ) {
232        intermediate[length++] = seq1[i];
233      }
234    }
235    return ArraysPlume.subarray(intermediate, 0, length);
236  }
237
238  /**
239   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
240   * no assurances about the order or repetition of elements: elements may be repeated, and their
241   * order may be different from the order of elements in seq1 and seq2.
242   */
243  @Pure
244  public static boolean @PolyNull [] setDiff(boolean @PolyNull [] seq1, boolean @PolyNull [] seq2) {
245    if (seq1 == null) {
246      return null;
247    }
248    if (seq2 == null) {
249      return null;
250    }
251    boolean[] intermediate = new boolean[seq1.length];
252    int length = 0;
253    for (int i = 0 ; i < seq1.length ; i++) {
254      if (!memberOf(seq1[i], seq2)) {
255        intermediate[length++] = seq1[i];
256      }
257    }
258    return ArraysPlume.subarray(intermediate, 0, length);
259  }
260
261  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
262  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
263  @Pure
264  public static boolean setEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
265    if (seq1 == null) {
266      return false;
267    }
268    if (seq2 == null) {
269      return false;
270    }
271    for (int i = 0; i < seq1.length ; i++) {
272      if (!memberOf(seq1[i], seq2) ) {
273        return false;
274      }
275    }
276    for (int i = 0; i < seq2.length ; i++) {
277      if (!memberOf(seq2[i], seq1) ) {
278        return false;
279      }
280    }
281    return true;
282  }
283
284  /** True iff seq1 is the reverse of seq2.
285   *
286   * Meaning (in pseudo-FOL):
287   *
288   * <pre>
289   * /\ seq1.length == seq2.length
290   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
291   * </pre>
292   *
293   */
294  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
295  @Pure
296  public static boolean isReverse(boolean[] seq1, boolean[] seq2) {
297    if (!sameLength(seq1, seq2)) {
298      return false;
299    }
300    assert seq1 != null && seq2 != null; // because sameLength() = true
301    int length = seq1.length;
302    for (int i = 0 ; i < length ; i++) {
303      if (ne(seq1[i], seq2[length - i - 1])) {
304        return false;
305      }
306    }
307    return true;
308  }
309
310  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
311  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
312  @Pure
313  public static boolean subsetOf(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
314    if (seq1 == null) {
315      return false;
316    }
317    if (seq2 == null) {
318      return false;
319    }
320    for (int i = 0 ; i < seq1.length ; i++) {
321      if (!memberOf(seq1[i], seq2)) {
322        return false;
323      }
324    }
325    return true;
326  }
327
328  /** Returns true iff seq contains no duplicate elements. */
329  @EnsuresNonNullIf(result=true, expression="#1")
330  @Pure
331  public static boolean noDups(boolean @Nullable [] seq) {
332    if (seq == null) {
333      return false;
334    }
335    return ArraysPlume.noDuplicates(seq);
336  }
337
338 /** Returns true iff elt is in array arr. */
339  @EnsuresNonNullIf(result=true, expression="#2")
340  @Pure
341  public static boolean memberOf(boolean elt, boolean @Nullable [] arr) {
342    if (arr == null) {
343      return false;
344    }
345    for (int i = 0 ; i < arr.length ; i++) {
346      if (eq(arr[i], elt)) {
347        return true;
348      }
349    }
350    return false;
351  }
352
353  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
354  @Pure
355  public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, int start, int end) {
356    if (seq == null) {
357      return null;
358    }
359    int sliceStart = start;
360    int sliceEnd = end;
361    if (start < 0) {
362      return new boolean[] { };
363    }
364    if (end > seq.length - 1) {
365      return new boolean[] { };
366    }
367    if (sliceStart > sliceEnd) {
368      return new boolean[] { };
369    }
370    int length = sliceEnd - sliceStart + 1;
371    return ArraysPlume.subarray(seq, sliceStart, length);
372  }
373
374  @Pure
375  public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, long start, int end) {
376    return slice(seq, (int)start, end);
377  }
378  @Pure
379  public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, int start, long end) {
380    return slice(seq, start, (int)end);
381  }
382  @Pure
383  public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, long start, long end) {
384    return slice(seq, (int)start, (int)end);
385  }
386
387  /** True iff all elements in arr equal elt.
388   *
389   * Meaning (in pseudo-FOL):
390   *
391   * forall i in { 0..arr.length-1 } : arr[i] == elt
392   *
393   */
394  @EnsuresNonNullIf(result=true, expression="#1")
395  @Pure
396  public static boolean eltsEqual(boolean @Nullable [] arr, boolean elt) {
397    if (arr == null) {
398      return false;
399    }
400    for (int i = 0 ; i < arr.length ; i++) {
401      if (ne(arr[i], elt)) {
402        return false;
403      }
404    }
405    return true;
406  }
407
408  /** True iff every element in arr does not equal elt.
409   *
410   * Meaning (in pseudo-FOL):
411   *
412   * forall i in { 0..arr.length-1 } : arr[i] != elt
413   *
414   */
415  @EnsuresNonNullIf(result=true, expression="#1")
416  @Pure
417  public static boolean eltsNotEqual(boolean @Nullable [] arr, boolean elt) {
418    if (arr == null) {
419      return false;
420    }
421    for (int i = 0 ; i < arr.length ; i++) {
422      if (eq(arr[i], elt)) {
423        return false;
424      }
425    }
426    return true;
427  }
428
429  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
430   *
431   * Meaning (in pseudo-FOL):
432   *
433   * /\ seq1.length == se2.length
434   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
435   *
436   */
437
438  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
439  @Pure
440  public static boolean pairwiseEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
441    if (!sameLength(seq1, seq2)) {
442      return false;
443    }
444    assert seq1 != null && seq2 != null; // because sameLength() = true
445    for (int i = 0 ; i < seq1.length ; i++) {
446      if (ne(seq1[i], seq2[i])) {
447        return false;
448      }
449    }
450    return true;
451  }
452
453  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
454   *
455   * Meaning (in pseudo-FOL):
456   *
457   * /\ seq1.length == se2.length
458   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
459   *
460   */
461  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
462  @Pure
463  public static boolean pairwiseNotEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
464    if (!sameLength(seq1, seq2)) {
465      return false;
466    }
467    assert seq1 != null && seq2 != null; // because sameLength() = true
468    for (int i = 0 ; i < seq1.length ; i++) {
469      if (eq(seq1[i], seq2[i])) {
470        return false;
471      }
472    }
473    return true;
474  }
475
476  /**
477   * Returns true iff seq1 is lexically equal to seq2.
478   * For equality, "lexically" and "pairwise" are the same.
479   */
480  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
481  @Pure
482  public static boolean lexEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
483    if (seq1 == null) {
484      return false;
485    }
486    if (seq2 == null) {
487      return false;
488    }
489    return pairwiseEqual(seq1, seq2);
490  }
491
492  /** Returns true iff seq1 is lexically not equal to seq2. */
493  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
494  @Pure
495  public static boolean lexNotEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) {
496    if (seq1 == null) {
497      return false;
498    }
499    if (seq2 == null) {
500      return false;
501    }
502    return !lexEqual(seq1, seq2);
503  }
504
505  /** True iff for all applicable i, every seq[i] == seq[i+1].
506   *
507   * Meaning (in pseudo-FOL):
508   *
509   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
510   *
511   */
512  @EnsuresNonNullIf(result=true, expression="#1")
513  @Pure
514  public static boolean eltwiseEqual(boolean @Nullable [] seq) {
515  if (seq == null) {
516    return false;
517  }
518    for (int i = 0 ; i < seq.length ; i++) {
519      if (i < seq.length - 1) {
520        if (ne(seq[i], seq[i + 1])) {
521          return false;
522        }
523      }
524    }
525    return true;
526  }
527
528  /** True iff for all applicable i, every seq[i] != seq[i+1].
529   *
530   * Meaning (in pseudo-FOL):
531   *
532   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
533   *
534   */
535  @EnsuresNonNullIf(result=true, expression="#1")
536  @Pure
537  public static boolean eltwiseNotEqual(boolean @Nullable [] seq) {
538  if (seq == null) {
539    return false;
540  }
541    for (int i = 0 ; i < seq.length ; i++) {
542      if (i < seq.length - 1) {
543        if (eq(seq[i], seq[i + 1])) {
544          return false;
545        }
546      }
547    }
548    return true;
549  }
550
551  /// Deferencing (accessing) fields
552
553  /**
554   * collectboolean accepts an object and a list of fields (one of which is of array type, and the
555   * rest of which are not), and produces an array in which the original object has had the given
556   * fields accessed.
557   *
558   * <p>Daikon creates invariants over "variables" such as the following.
559   *
560   * <dl>
561   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
562   *              for all y's in array x.arr.</dd>
563   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
564   *              for all x's in array arr.</dd>
565   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
566   * </dl>
567   *
568   * <p>The collectboolean() method does this collecting work.
569   *
570   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
571   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
572   * elements that result from following the fields, one of which is assumed to be an array.
573   *
574   * <p>
575   * requires: fieldStr.length() &gt; 0 and object != null
576   * <p>
577   * requires: fieldStr contains only field names, no "[]" strings.
578   * <p>
579   * requires: the method only works for field sequences with exactly one field representing an
580   * array. For example, the collection a[].b[].c will fail.
581   *
582   * @return if the resulting collection is of non-primitive type, then returns an array of type
583   * Object[]. Returns null if any array or field access causes an exception.
584   */
585
586  @SideEffectFree
587  public static boolean @Nullable [] collectboolean(@Nullable Object object, @Nullable String fieldStr) {
588
589    if (object == null) {
590      return null;
591    }
592    if (fieldStr == null) {
593      return null;
594    }
595
596    // assert fieldStr != null && !"".equals(fieldStr);
597    String[] fieldNames = fieldStr.split("\\.");
598    boolean[] retval = collectboolean(object, fieldNames, 0);
599    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
600    return retval;
601  }
602
603  /** Helper method for collectboolean(Object, String).
604   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
605   * @see collectboolean(Object, String)
606   */
607  // @PolyNull does not work for return type, because null is returned on error.
608  @SideEffectFree
609  private static boolean @Nullable [] collectboolean(@Nullable Object object,
610                                                   String[] fields, int fieldsStartIdx) {
611
612    if (object == null) {
613      return null;
614    }
615    assert (fields != null);
616    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
617
618    Object fieldObj;
619    try {
620      Field field = (object instanceof java.lang.Class<?>)
621        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
622        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
623      field.setAccessible(true);
624      // Class cls = field.getType();
625      fieldObj = field.get(object);
626      // System.out.println("***fieldObj="+fieldObj);
627
628    } catch (Exception e) {
629      return null;
630
631    }
632
633    if (fieldObj == null) {
634      return null;
635    }
636
637    // base case: just accessed the last field
638    if (fields.length - 1 == fieldsStartIdx) {
639
640      if (fieldObj.getClass().isArray()) {
641        // last field is an array
642        return (boolean[])fieldObj;
643      } else {
644        // This hack should be removed in favor of, at "oneEltArray = ..."
645        // below, calling a version of collectboolean_field that throws an
646        // error.  Then, this case becomes a run-time error.  -MDE
647
648        // Just one element; return a one-element array.
649        // assert cls.equals(Boolean.TYPE);
650        return new boolean[] { ((Boolean)fieldObj).booleanValue() };
651      }
652    } else {
653      // recursive case: more fields to access after this one
654
655      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
656
657        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
658        boolean[] intermediate = new boolean[collection.size()];
659        int index = 0;
660        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
661          Object obj = i.next();
662          boolean[] oneEltArray = collectboolean(obj, fields, fieldsStartIdx + 1);
663          if (oneEltArray == null) {
664            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
665          }
666          // assert oneEltArray.length == 1;
667          intermediate[index++] = oneEltArray[0];
668        }
669        return intermediate;
670      } else if (fieldObj.getClass().isArray()) {
671
672        // collect elements across array
673        boolean[] intermediate = new boolean[Array.getLength(fieldObj)];
674        for (int i = 0 ; i < intermediate.length ; i++) {
675          Object obj = Array.get(fieldObj, i);
676          boolean[] oneEltArray = collectboolean(obj, fields, fieldsStartIdx + 1);
677          if (oneEltArray == null) {
678            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
679          }
680          // assert oneEltArray.length == 1;
681          intermediate[i] = oneEltArray[0];
682        }
683        return intermediate;
684      } else {
685
686        return collectboolean(fieldObj, fields, fieldsStartIdx + 1);
687      }
688    }
689  }
690
691  /**
692   * Returns the results of dereferencing the fields for 'object'. For example, the call
693   *
694   * <pre>collectboolean_field(x, "f.g.h")</pre>
695   *
696   * has the same value as
697   *
698   * <pre>x.f.g.h</pre>.
699   * Returns a default value if any field access causes an exception.
700   */
701  @SideEffectFree
702  public static boolean collectboolean_field(Object object, String fieldStr) {
703
704    if (object == null) {
705      return false; // return default value
706    }
707    if (fieldStr == null) {
708      return false; // return default value
709    }
710
711    String[] fieldNames = fieldStr.split("\\.");
712
713    // Holds the intermediate (and final) result
714    Object fieldObj = object;
715
716    for (int i = 0 ; i < fieldNames.length ; i++) {
717
718      String fieldName = fieldNames[i];
719
720      try {
721        Field field =
722          (fieldObj instanceof java.lang.Class<?>)
723          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
724          : fieldObj.getClass().getDeclaredField(fieldName);
725        field.setAccessible(true);
726        fieldObj = field.get(fieldObj);
727
728        if (fieldObj == null) {
729          return false; // return default value
730        }
731
732      } catch (Exception e) {
733        return false; // return default value
734
735      }
736
737    }
738
739    return ((Boolean)fieldObj).booleanValue();
740  }
741
742  ///////////////////////////////////////////////////////////////////////////
743  /// Methods for "byte" (from QuantBody.java.jpp)
744  ///
745
746  /**
747   * Returns the ith element of the array or collection argument. If the argument is null or not an
748   * array or collection, returns a default value (Byte.MAX_VALUE).
749   */
750
751  @Pure
752  public static byte getElement_byte(Object o, long i) {
753    if (o == null) {
754      return Byte.MAX_VALUE; // return default value
755    }
756    java.lang.Class<?> c = o.getClass();
757    if (c.isArray()) {
758      return java.lang.reflect.Array.getByte(o, (int)i);
759    } else if (o instanceof java.util.AbstractCollection<?>) {
760      return java.lang.reflect.Array.getByte(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
761    } else {
762      return Byte.MAX_VALUE; // return default value
763    }
764  }
765
766  @Pure
767  public static byte getElement_byte(byte[] arr, long i) {
768    if (arr == null) {
769      return Byte.MAX_VALUE; // return default value
770    }
771    return arr[(int)i];
772  }
773
774  private static boolean eq(byte x, byte y) {
775    return x == y;
776  }
777
778  private static boolean ne(byte x, byte y) {
779    return x != y;
780  }
781
782  private static boolean lt(byte x, byte y) {
783    return x < y;
784  }
785
786  private static boolean lte(byte x, byte y) {
787    return x <= y;
788  }
789
790  private static boolean gt(byte x, byte y) {
791    return x > y;
792  }
793
794  private static boolean gte(byte x, byte y) {
795    return x >= y;
796  }
797
798  /** True iff both sequences are non-null and have the same length. */
799  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
800  @Pure
801  public static boolean sameLength(byte @Nullable [] seq1, byte @Nullable [] seq2) {
802    return ((seq1 != null)
803            && (seq2 != null)
804            && seq1.length == seq2.length);
805  }
806
807  /** True iff both sequences are non-null and have the same length. */
808  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
809  @Pure
810  public static boolean sameLength(byte @Nullable [] seq1, int @Nullable [] seq2) {
811    return ((seq1 != null)
812            && (seq2 != null)
813            && seq1.length == seq2.length);
814  }
815
816  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
817   *
818   * Meaning (in pseudo-FOL):
819   *
820   * <pre>
821   * /\ seq1.length == seq2.length
822   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
823   * </pre>
824   *
825   */
826  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
827  @Pure
828  public static boolean pairwiseDivides(byte[] seq1, byte[] seq2) {
829    if (!sameLength(seq1, seq2)) {
830      return false;
831    }
832    assert seq1 != null && seq2 != null; // because sameLength() = true
833    for (int i = 0 ; i < seq1.length ; i++) {
834      if (ne(seq1[i] % seq2[i], 0)) {
835        return false;
836      }
837    }
838    return true;
839  }
840  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
841  @Pure
842  public static boolean pairwiseDivides(byte[] seq1, int[] seq2) {
843    if (!sameLength(seq1, seq2)) {
844      return false;
845    }
846    assert seq1 != null && seq2 != null; // because sameLength() = true
847    for (int i = 0 ; i < seq1.length ; i++) {
848      if (ne(seq1[i] % seq2[i], 0)) {
849        return false;
850      }
851    }
852    return true;
853  }
854
855  /**
856   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
857   *
858   * Meaning (in pseudo-FOL):
859   *
860   * <pre>
861   * /\ seq1.length == seq2.length
862   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
863   * </pre>
864   *
865   */
866  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
867  @Pure
868  public static boolean pairwiseSquare(byte[] seq1, byte[] seq2) {
869    if (!sameLength(seq1, seq2)) {
870      return false;
871    }
872    assert seq1 != null && seq2 != null; // because sameLength() = true
873    for (int i = 0 ; i < seq1.length ; i++) {
874      if (ne(seq1[i], seq2[i] * seq2[i])) {
875        return false;
876      }
877    }
878    return true;
879  }
880  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
881  @Pure
882  public static boolean pairwiseSquare(byte[] seq1, int[] seq2) {
883    if (!sameLength(seq1, seq2)) {
884      return false;
885    }
886    assert seq1 != null && seq2 != null; // because sameLength() = true
887    for (int i = 0 ; i < seq1.length ; i++) {
888
889      if (ne(seq1[i], seq2[i] * seq2[i])) {
890
891        return false;
892      }
893    }
894    return true;
895  }
896
897  /**
898   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
899   *
900   * <p>If either array is null, returns null. If either array is empty, returns only those
901   * elements in the other array. If both arrays are empty, returns a new empty array.
902   */
903  @SideEffectFree
904  public static byte @PolyNull [] concat(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
905    if (seq1 == null) {
906      return null;
907    }
908    if (seq2 == null) {
909      return null;
910    }
911    return ArraysPlume.concat(seq1, seq2);
912  }
913
914  @SideEffectFree
915  public static int @PolyNull [] concat(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
916    if (seq1 == null) {
917      return null;
918    }
919    if (seq2 == null) {
920      return null;
921    }
922    // Cannot just use ArraysPlume.concat because the two arrays
923    // have different types.  This essentially inlines that method.
924    int newLength = seq1.length + seq2.length;
925    int[] retval = new int[newLength];
926
927    for (int j = 0 ; j < seq1.length ; j++) {
928      retval[j] = seq1[j];
929    }
930    System.arraycopy(seq2, 0, retval, seq1.length, seq2.length);
931
932    return retval;
933  }
934
935  /**
936   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
937   * assurances about the order or repetition of elements: elements may be repeated, and their
938   * order may be different from the order of elements in seq1 and seq2.
939   */
940  @SideEffectFree
941  public static byte @PolyNull [] union(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
942    if (seq1 == null) {
943      return null;
944    }
945    if (seq2 == null) {
946      return null;
947    }
948    return concat(seq1, seq2);
949  }
950
951  @Pure
952  public static int @PolyNull [] union(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
953    if (seq1 == null) {
954      return null;
955    }
956    if (seq2 == null) {
957      return null;
958    }
959    return concat(seq1, seq2);
960  }
961
962  /**
963   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
964   * gives no assurances about the order or repetition of elements: elements may be repeated, and
965   * their order may be different from the order of elements in seq1 and seq2.
966   */
967  @Pure
968  public static byte @PolyNull [] intersection(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
969    if (seq1 == null) {
970      return null;
971    }
972    if (seq2 == null) {
973      return null;
974    }
975    byte[] intermediate = new byte[Math.min(seq1.length, seq2.length)];
976    int length = 0;
977    for (int i = 0 ; i < seq1.length ; i++) {
978      if (memberOf(seq1[i], seq2) ) {
979        intermediate[length++] = seq1[i];
980      }
981    }
982    return ArraysPlume.subarray(intermediate, 0, length);
983  }
984
985  @Pure
986  public static int @PolyNull [] intersection(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
987    if (seq1 == null) {
988      return null;
989    }
990    if (seq2 == null) {
991      return null;
992    }
993    int[] intermediate = new int[Math.min(seq1.length, seq2.length)];
994    int length = 0;
995    for (int i = 0 ; i < seq1.length ; i++) {
996      if (memberOf(seq1[i], seq2) ) {
997        intermediate[length++] = seq1[i];
998      }
999    }
1000    return ArraysPlume.subarray(intermediate, 0, length);
1001  }
1002
1003  /**
1004   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
1005   * no assurances about the order or repetition of elements: elements may be repeated, and their
1006   * order may be different from the order of elements in seq1 and seq2.
1007   */
1008  @Pure
1009  public static byte @PolyNull [] setDiff(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
1010    if (seq1 == null) {
1011      return null;
1012    }
1013    if (seq2 == null) {
1014      return null;
1015    }
1016    byte[] intermediate = new byte[seq1.length];
1017    int length = 0;
1018    for (int i = 0 ; i < seq1.length ; i++) {
1019      if (!memberOf(seq1[i], seq2)) {
1020        intermediate[length++] = seq1[i];
1021      }
1022    }
1023    return ArraysPlume.subarray(intermediate, 0, length);
1024  }
1025
1026  @Pure
1027  public static int @PolyNull [] setDiff(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
1028    if (seq1 == null) {
1029      return null;
1030    }
1031    if (seq2 == null) {
1032      return null;
1033    }
1034    int[] intermediate = new int[seq1.length];
1035    int length = 0;
1036    for (int i = 0 ; i < seq1.length ; i++) {
1037      if (!memberOf(seq1[i], seq2)) {
1038        intermediate[length++] = seq1[i];
1039      }
1040    }
1041    return ArraysPlume.subarray(intermediate, 0, length);
1042  }
1043
1044  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
1045  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1046  @Pure
1047  public static boolean setEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1048    if (seq1 == null) {
1049      return false;
1050    }
1051    if (seq2 == null) {
1052      return false;
1053    }
1054    for (int i = 0; i < seq1.length ; i++) {
1055      if (!memberOf(seq1[i], seq2) ) {
1056        return false;
1057      }
1058    }
1059    for (int i = 0; i < seq2.length ; i++) {
1060      if (!memberOf(seq2[i], seq1) ) {
1061        return false;
1062      }
1063    }
1064    return true;
1065  }
1066
1067  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1068  @Pure
1069  public static boolean setEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1070    if (seq1 == null) {
1071      return false;
1072    }
1073    if (seq2 == null) {
1074      return false;
1075    }
1076    for (int i = 0; i < seq1.length ; i++) {
1077      if (!memberOf(seq1[i], seq2) ) {
1078        return false;
1079      }
1080    }
1081    for (int i = 0; i < seq2.length ; i++) {
1082      if (!memberOf(seq2[i], seq1) ) {
1083        return false;
1084      }
1085    }
1086    return true;
1087  }
1088
1089  /** True iff seq1 is the reverse of seq2.
1090   *
1091   * Meaning (in pseudo-FOL):
1092   *
1093   * <pre>
1094   * /\ seq1.length == seq2.length
1095   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
1096   * </pre>
1097   *
1098   */
1099  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1100  @Pure
1101  public static boolean isReverse(byte[] seq1, byte[] seq2) {
1102    if (!sameLength(seq1, seq2)) {
1103      return false;
1104    }
1105    assert seq1 != null && seq2 != null; // because sameLength() = true
1106    int length = seq1.length;
1107    for (int i = 0 ; i < length ; i++) {
1108      if (ne(seq1[i], seq2[length - i - 1])) {
1109        return false;
1110      }
1111    }
1112    return true;
1113  }
1114
1115  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1116  @Pure
1117  public static boolean isReverse(byte @Nullable [] seq1, int @Nullable [] seq2) {
1118    if (!sameLength(seq1, seq2)) {
1119      return false;
1120    }
1121    assert seq1 != null && seq2 != null; // because sameLength() = true
1122    int length = seq1.length;
1123    for (int i = 0 ; i < length ; i++) {
1124      if (ne(seq1[i], seq2[length - i - 1])) {
1125        return false;
1126      }
1127    }
1128    return true;
1129  }
1130
1131  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
1132  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1133  @Pure
1134  public static boolean subsetOf(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1135    if (seq1 == null) {
1136      return false;
1137    }
1138    if (seq2 == null) {
1139      return false;
1140    }
1141    for (int i = 0 ; i < seq1.length ; i++) {
1142      if (!memberOf(seq1[i], seq2)) {
1143        return false;
1144      }
1145    }
1146    return true;
1147  }
1148
1149  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1150  @Pure
1151  public static boolean subsetOf(byte @Nullable [] seq1, int @Nullable [] seq2) {
1152    if (seq1 == null) {
1153      return false;
1154    }
1155    if (seq2 == null) {
1156      return false;
1157    }
1158    for (int i = 0 ; i < seq1.length ; i++) {
1159      if (!memberOf(seq1[i], seq2)) {
1160        return false;
1161      }
1162    }
1163    return true;
1164  }
1165
1166  /** Returns true iff seq contains no duplicate elements. */
1167  @EnsuresNonNullIf(result=true, expression="#1")
1168  @Pure
1169  public static boolean noDups(byte @Nullable [] seq) {
1170    if (seq == null) {
1171      return false;
1172    }
1173    return ArraysPlume.noDuplicates(seq);
1174  }
1175
1176 /** Returns true iff elt is in array arr. */
1177  @EnsuresNonNullIf(result=true, expression="#2")
1178  @Pure
1179  public static boolean memberOf(byte elt, byte @Nullable [] arr) {
1180    if (arr == null) {
1181      return false;
1182    }
1183    for (int i = 0 ; i < arr.length ; i++) {
1184      if (eq(arr[i], elt)) {
1185        return true;
1186      }
1187    }
1188    return false;
1189  }
1190
1191  @EnsuresNonNullIf(result=true, expression="#2")
1192  @Pure
1193  public static boolean memberOf(byte elt, int @Nullable [] arr) {
1194    if (arr == null) {
1195      return false;
1196    }
1197    for (int i = 0 ; i < arr.length ; i++) {
1198      if (eq(arr[i], elt)) {
1199        return true;
1200      }
1201    }
1202    return false;
1203  }
1204
1205  @EnsuresNonNullIf(result=true, expression="#2")
1206  @Pure
1207  public static boolean memberOf(long elt, byte @Nullable [] arr) {
1208    if (arr == null) {
1209      return false;
1210    }
1211    for (int i = 0 ; i < arr.length ; i++) {
1212      if (eq(arr[i], elt)) {
1213        return true;
1214      }
1215    }
1216    return false;
1217  }
1218
1219  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
1220  @Pure
1221  public static byte @PolyNull [] slice(byte @PolyNull [] seq, int start, int end) {
1222    if (seq == null) {
1223      return null;
1224    }
1225    int sliceStart = start;
1226    int sliceEnd = end;
1227    if (start < 0) {
1228      return new byte[] { };
1229    }
1230    if (end > seq.length - 1) {
1231      return new byte[] { };
1232    }
1233    if (sliceStart > sliceEnd) {
1234      return new byte[] { };
1235    }
1236    int length = sliceEnd - sliceStart + 1;
1237    return ArraysPlume.subarray(seq, sliceStart, length);
1238  }
1239
1240  @Pure
1241  public static byte @PolyNull [] slice(byte @PolyNull [] seq, long start, int end) {
1242    return slice(seq, (int)start, end);
1243  }
1244  @Pure
1245  public static byte @PolyNull [] slice(byte @PolyNull [] seq, int start, long end) {
1246    return slice(seq, start, (int)end);
1247  }
1248  @Pure
1249  public static byte @PolyNull [] slice(byte @PolyNull [] seq, long start, long end) {
1250    return slice(seq, (int)start, (int)end);
1251  }
1252
1253  /** True iff all elements in arr equal elt.
1254   *
1255   * Meaning (in pseudo-FOL):
1256   *
1257   * forall i in { 0..arr.length-1 } : arr[i] == elt
1258   *
1259   */
1260  @EnsuresNonNullIf(result=true, expression="#1")
1261  @Pure
1262  public static boolean eltsEqual(byte @Nullable [] arr, byte elt) {
1263    if (arr == null) {
1264      return false;
1265    }
1266    for (int i = 0 ; i < arr.length ; i++) {
1267      if (ne(arr[i], elt)) {
1268        return false;
1269      }
1270    }
1271    return true;
1272  }
1273
1274  @EnsuresNonNullIf(result=true, expression="#1")
1275  @Pure
1276  public static boolean eltsEqual(byte @Nullable [] arr, int elt) {
1277    if (arr == null) {
1278      return false;
1279    }
1280    for (int i = 0 ; i < arr.length ; i++) {
1281      if (ne(arr[i], elt)) {
1282        return false;
1283      }
1284    }
1285    return true;
1286  }
1287
1288  /** True iff every element in arr does not equal elt.
1289   *
1290   * Meaning (in pseudo-FOL):
1291   *
1292   * forall i in { 0..arr.length-1 } : arr[i] != elt
1293   *
1294   */
1295  @EnsuresNonNullIf(result=true, expression="#1")
1296  @Pure
1297  public static boolean eltsNotEqual(byte @Nullable [] arr, byte elt) {
1298    if (arr == null) {
1299      return false;
1300    }
1301    for (int i = 0 ; i < arr.length ; i++) {
1302      if (eq(arr[i], elt)) {
1303        return false;
1304      }
1305    }
1306    return true;
1307  }
1308
1309  @EnsuresNonNullIf(result=true, expression="#1")
1310  @Pure
1311  public static boolean eltsNotEqual(byte @Nullable [] arr, int elt) {
1312    if (arr == null) {
1313      return false;
1314    }
1315    for (int i = 0 ; i < arr.length ; i++) {
1316      if (eq(arr[i], elt)) {
1317        return false;
1318      }
1319    }
1320    return true;
1321  }
1322
1323  /** True iff every element in arr is greater than elt.
1324   *
1325   * Meaning (in pseudo-FOL):
1326   *
1327   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
1328   *
1329   */
1330  @EnsuresNonNullIf(result=true, expression="#1")
1331  @Pure
1332  public static boolean eltsGT(byte @Nullable [] arr, byte elt) {
1333    if (arr == null) {
1334      return false;
1335    }
1336    for (int i = 0 ; i < arr.length ; i++) {
1337      if (lte(arr[i], elt)) {
1338        return false;
1339      }
1340    }
1341    return true;
1342  }
1343
1344  @EnsuresNonNullIf(result=true, expression="#1")
1345  @Pure
1346  public static boolean eltsGT(byte @Nullable [] arr, int elt) {
1347    if (arr == null) {
1348      return false;
1349    }
1350    for (int i = 0 ; i < arr.length ; i++) {
1351      if (lte(arr[i], elt)) {
1352        return false;
1353      }
1354    }
1355    return true;
1356  }
1357
1358  /** True iff every element in arr is greater than or equal to elt.
1359   *
1360   * Meaning (in pseudo-FOL):
1361   *
1362   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
1363   *
1364   */
1365  @EnsuresNonNullIf(result=true, expression="#1")
1366  @Pure
1367  public static boolean eltsGTE(byte @Nullable [] arr, byte elt) {
1368    if (arr == null) {
1369      return false;
1370    }
1371    for (int i = 0 ; i < arr.length ; i++) {
1372      if (lt(arr[i], elt)) {
1373        return false;
1374      }
1375    }
1376    return true;
1377  }
1378
1379  @EnsuresNonNullIf(result=true, expression="#1")
1380  @Pure
1381  public static boolean eltsGTE(byte @Nullable [] arr, int elt) {
1382    if (arr == null) {
1383      return false;
1384    }
1385    for (int i = 0 ; i < arr.length ; i++) {
1386      if (lt(arr[i], elt)) {
1387        return false;
1388      }
1389    }
1390    return true;
1391  }
1392
1393  /** True iff every element in arr is less than elt.
1394   *
1395   * Meaning (in pseudo-FOL):
1396   *
1397   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
1398   *
1399   */
1400  @EnsuresNonNullIf(result=true, expression="#1")
1401  @Pure
1402  public static boolean eltsLT(byte @Nullable [] arr, byte elt) {
1403    if (arr == null) {
1404      return false;
1405    }
1406    for (int i = 0 ; i < arr.length ; i++) {
1407      if (gte(arr[i], elt)) {
1408        return false;
1409      }
1410    }
1411    return true;
1412  }
1413
1414  @EnsuresNonNullIf(result=true, expression="#1")
1415  @Pure
1416  public static boolean eltsLT(byte @Nullable [] arr, int elt) {
1417    if (arr == null) {
1418      return false;
1419    }
1420    for (int i = 0 ; i < arr.length ; i++) {
1421      if (gte(arr[i], elt)) {
1422        return false;
1423      }
1424    }
1425    return true;
1426  }
1427
1428  /** True iff every element in arr is less than or equal to elt.
1429   *
1430   * Meaning (in pseudo-FOL):
1431   *
1432   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
1433   *
1434   */
1435  @EnsuresNonNullIf(result=true, expression="#1")
1436  @Pure
1437  public static boolean eltsLTE(byte @Nullable [] arr, byte elt) {
1438    if (arr == null) {
1439      return false;
1440    }
1441    for (int i = 0 ; i < arr.length ; i++) {
1442      if (gt(arr[i], elt)) {
1443        return false;
1444      }
1445    }
1446    return true;
1447  }
1448
1449  @EnsuresNonNullIf(result=true, expression="#1")
1450  @Pure
1451  public static boolean eltsLTE(byte @Nullable [] arr, int elt) {
1452    if (arr == null) {
1453      return false;
1454    }
1455    for (int i = 0 ; i < arr.length ; i++) {
1456      if (gt(arr[i], elt)) {
1457        return false;
1458      }
1459    }
1460    return true;
1461  }
1462
1463  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
1464   *
1465   * Meaning (in pseudo-FOL):
1466   *
1467   * /\ seq1.length == se2.length
1468   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
1469   *
1470   */
1471
1472  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1473  @Pure
1474  public static boolean pairwiseEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1475    if (!sameLength(seq1, seq2)) {
1476      return false;
1477    }
1478    assert seq1 != null && seq2 != null; // because sameLength() = true
1479    for (int i = 0 ; i < seq1.length ; i++) {
1480      if (ne(seq1[i], seq2[i])) {
1481        return false;
1482      }
1483    }
1484    return true;
1485  }
1486
1487  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1488  @Pure
1489  public static boolean pairwiseEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1490    if (!sameLength(seq1, seq2)) {
1491      return false;
1492    }
1493    assert seq1 != null && seq2 != null; // because sameLength() = true
1494    for (int i = 0 ; i < seq1.length ; i++) {
1495      if (ne(seq1[i], seq2[i])) {
1496        return false;
1497      }
1498    }
1499    return true;
1500  }
1501
1502  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
1503   *
1504   * Meaning (in pseudo-FOL):
1505   *
1506   * /\ seq1.length == se2.length
1507   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
1508   *
1509   */
1510  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1511  @Pure
1512  public static boolean pairwiseNotEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1513    if (!sameLength(seq1, seq2)) {
1514      return false;
1515    }
1516    assert seq1 != null && seq2 != null; // because sameLength() = true
1517    for (int i = 0 ; i < seq1.length ; i++) {
1518      if (eq(seq1[i], seq2[i])) {
1519        return false;
1520      }
1521    }
1522    return true;
1523  }
1524
1525  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1526  @Pure
1527  public static boolean pairwiseNotEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1528    if (!sameLength(seq1, seq2)) {
1529      return false;
1530    }
1531    assert seq1 != null && seq2 != null; // because sameLength() = true
1532    for (int i = 0 ; i < seq1.length ; i++) {
1533      if (eq(seq1[i], seq2[i])) {
1534        return false;
1535      }
1536    }
1537    return true;
1538  }
1539
1540  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
1541   *
1542   * Meaning (in pseudo-FOL):
1543   *
1544   * /\ seq1.length == se2.length
1545   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
1546   *
1547   */
1548  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1549  @Pure
1550  public static boolean pairwiseLT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1551    if (!sameLength(seq1, seq2)) {
1552      return false;
1553    }
1554    assert seq1 != null && seq2 != null; // because sameLength() = true
1555    for (int i = 0 ; i < seq1.length ; i++) {
1556      if (gte(seq1[i], seq2[i])) {
1557        return false;
1558      }
1559    }
1560    return true;
1561  }
1562
1563  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1564  @Pure
1565  public static boolean pairwiseLT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1566    if (!sameLength(seq1, seq2)) {
1567      return false;
1568    }
1569    assert seq1 != null && seq2 != null; // because sameLength() = true
1570    for (int i = 0 ; i < seq1.length ; i++) {
1571      if (gte(seq1[i], seq2[i])) {
1572        return false;
1573      }
1574    }
1575    return true;
1576  }
1577
1578  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
1579   * Meaning (in pseudo-FOL):
1580   *
1581   * /\ seq1.length == se2.length
1582   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
1583   *
1584   */
1585  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1586  @Pure
1587  public static boolean pairwiseLTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1588    if (!sameLength(seq1, seq2)) {
1589      return false;
1590    }
1591    assert seq1 != null && seq2 != null; // because sameLength() = true
1592    for (int i = 0 ; i < seq1.length ; i++) {
1593      if (gt(seq1[i], seq2[i])) {
1594        return false;
1595      }
1596    }
1597    return true;
1598  }
1599
1600  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1601  @Pure
1602  public static boolean pairwiseLTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1603    if (!sameLength(seq1, seq2)) {
1604      return false;
1605    }
1606    assert seq1 != null && seq2 != null; // because sameLength() = true
1607    for (int i = 0 ; i < seq1.length ; i++) {
1608      if (gt(seq1[i], seq2[i])) {
1609        return false;
1610      }
1611    }
1612    return true;
1613  }
1614
1615  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
1616   * Meaning (in pseudo-FOL):
1617   *
1618   * /\ seq1.length == se2.length
1619   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
1620   *
1621   */
1622  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1623  @Pure
1624  public static boolean pairwiseGT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1625    if (!sameLength(seq1, seq2)) {
1626      return false;
1627    }
1628    assert seq1 != null && seq2 != null; // because sameLength() = true
1629    for (int i = 0 ; i < seq1.length ; i++) {
1630      if (lte(seq1[i], seq2[i])) {
1631        return false;
1632      }
1633    }
1634    return true;
1635  }
1636
1637  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1638  @Pure
1639  public static boolean pairwiseGT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1640    if (!sameLength(seq1, seq2)) {
1641      return false;
1642    }
1643    assert seq1 != null && seq2 != null; // because sameLength() = true
1644    for (int i = 0 ; i < seq1.length ; i++) {
1645      if (lte(seq1[i], seq2[i])) {
1646        return false;
1647      }
1648    }
1649    return true;
1650  }
1651
1652  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
1653   * Meaning (in pseudo-FOL):
1654   *
1655   * /\ seq1.length == se2.length
1656   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
1657   *
1658   */
1659  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1660  @Pure
1661  public static boolean pairwiseGTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1662    if (!sameLength(seq1, seq2)) {
1663      return false;
1664    }
1665    assert seq1 != null && seq2 != null; // because sameLength() = true
1666    for (int i = 0 ; i < seq1.length ; i++) {
1667      if (lt(seq1[i], seq2[i])) {
1668        return false;
1669      }
1670    }
1671    return true;
1672  }
1673
1674  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1675  @Pure
1676  public static boolean pairwiseGTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1677    if (!sameLength(seq1, seq2)) {
1678      return false;
1679    }
1680    assert seq1 != null && seq2 != null; // because sameLength() = true
1681    for (int i = 0 ; i < seq1.length ; i++) {
1682      if (lt(seq1[i], seq2[i])) {
1683        return false;
1684      }
1685    }
1686    return true;
1687  }
1688
1689  /**
1690   * Returns true iff seq1 is lexically equal to seq2.
1691   * For equality, "lexically" and "pairwise" are the same.
1692   */
1693  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1694  @Pure
1695  public static boolean lexEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1696    if (seq1 == null) {
1697      return false;
1698    }
1699    if (seq2 == null) {
1700      return false;
1701    }
1702    return pairwiseEqual(seq1, seq2);
1703  }
1704
1705  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1706  @Pure
1707  public static boolean lexEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1708    if (seq1 == null) {
1709      return false;
1710    }
1711    if (seq2 == null) {
1712      return false;
1713    }
1714    return pairwiseEqual(seq1, seq2);
1715  }
1716
1717  /** Returns true iff seq1 is lexically not equal to seq2. */
1718  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1719  @Pure
1720  public static boolean lexNotEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1721    if (seq1 == null) {
1722      return false;
1723    }
1724    if (seq2 == null) {
1725      return false;
1726    }
1727    return !lexEqual(seq1, seq2);
1728  }
1729
1730  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1731  @Pure
1732  public static boolean lexNotEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1733    if (seq1 == null) {
1734      return false;
1735    }
1736    if (seq2 == null) {
1737      return false;
1738    }
1739    return !lexEqual(seq1, seq2);
1740  }
1741
1742  /** Returns true iff seq1 is lexically &lt;  seq2. */
1743  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1744  @Pure
1745  public static boolean lexLT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1746    if (seq1 == null) {
1747      return false;
1748    }
1749    if (seq2 == null) {
1750      return false;
1751    }
1752    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1753    for (int i = 0 ; i < minlength ; i++) {
1754      if (gt(seq1[i], seq2[i])) {
1755        return false;
1756      } else if (lt(seq1[i], seq2[i])) {
1757        return true;
1758      }
1759    }
1760    if (seq1.length >= seq2.length) {
1761      return false;
1762    }
1763    return true;
1764  }
1765
1766  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1767  @Pure
1768  public static boolean lexLT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1769    if (seq1 == null) {
1770      return false;
1771    }
1772    if (seq2 == null) {
1773      return false;
1774    }
1775    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1776    for (int i = 0 ; i < minlength ; i++) {
1777      if (gt(seq1[i], seq2[i])) {
1778        return false;
1779        } else if (lt(seq1[i], seq2[i])) {
1780          return true;
1781        }
1782      }
1783      if (seq1.length >= seq2.length) {
1784        return false;
1785      }
1786      return true;
1787    }
1788
1789  /** Returns true iff seq1 is lexically &le; to seq2. */
1790  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1791  @Pure
1792  public static boolean lexLTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1793    if (seq1 == null) {
1794      return false;
1795    }
1796    if (seq2 == null) {
1797      return false;
1798    }
1799    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1800    for (int i = 0 ; i < minlength ; i++) {
1801      if (gt(seq1[i], seq2[i])) {
1802        return false;
1803      } else if (lt(seq1[i], seq2[i])) {
1804        return true;
1805      }
1806    }
1807    if (seq1.length > seq2.length) {
1808      return false;
1809    }
1810    return true;
1811  }
1812
1813  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1814  @Pure
1815  public static boolean lexLTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1816  if (seq1 == null) {
1817    return false;
1818  }
1819  if (seq2 == null) {
1820    return false;
1821  }
1822    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1823    for (int i = 0 ; i < minlength ; i++) {
1824      if (gt(seq1[i], seq2[i])) {
1825        return false;
1826      } else if (lt(seq1[i], seq2[i])) {
1827        return true;
1828      }
1829    }
1830    if (seq1.length > seq2.length) {
1831      return false;
1832    }
1833    return true;
1834  }
1835
1836  /** Returns true iff seq1 is lexically &gt; to seq2. */
1837  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1838  @Pure
1839  public static boolean lexGT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1840  if (seq1 == null) {
1841    return false;
1842  }
1843  if (seq2 == null) {
1844    return false;
1845  }
1846    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1847    for (int i = 0 ; i < minlength ; i++) {
1848      if (lt(seq1[i], seq2[i])) {
1849        return false;
1850      } else if (gt(seq1[i], seq2[i])) {
1851        return true;
1852      }
1853    }
1854    if (seq1.length <= seq2.length) {
1855      return false;
1856    }
1857    return true;
1858  }
1859
1860  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1861  @Pure
1862  public static boolean lexGT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1863  if (seq1 == null) {
1864    return false;
1865  }
1866  if (seq2 == null) {
1867    return false;
1868  }
1869    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1870    for (int i = 0 ; i < minlength ; i++) {
1871      if (lt(seq1[i], seq2[i])) {
1872        return false;
1873      } else if (gt(seq1[i], seq2[i])) {
1874        return true;
1875      }
1876    }
1877    if (seq1.length <= seq2.length) {
1878      return false;
1879    }
1880    return true;
1881  }
1882
1883  /** Returns true iff seq1 is lexically &ge; to seq2. */
1884  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1885  @Pure
1886  public static boolean lexGTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1887  if (seq1 == null) {
1888    return false;
1889  }
1890  if (seq2 == null) {
1891    return false;
1892  }
1893    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1894    for (int i = 0 ; i < minlength ; i++) {
1895      if (lt(seq1[i], seq2[i])) {
1896        return false;
1897      } else if (gt(seq1[i], seq2[i])) {
1898        return true;
1899      }
1900    }
1901    if (seq1.length < seq2.length) {
1902      return false;
1903    }
1904    return true;
1905  }
1906
1907  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1908  @Pure
1909  public static boolean lexGTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1910  if (seq1 == null) {
1911    return false;
1912  }
1913  if (seq2 == null) {
1914    return false;
1915  }
1916    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1917    for (int i = 0 ; i < minlength ; i++) {
1918      if (lt(seq1[i], seq2[i])) {
1919        return false;
1920      } else if (gt(seq1[i], seq2[i])) {
1921        return true;
1922      }
1923    }
1924    if (seq1.length < seq2.length) {
1925      return false;
1926    }
1927    return true;
1928  }
1929
1930  /** True iff for all applicable i, every seq[i] == seq[i+1].
1931   *
1932   * Meaning (in pseudo-FOL):
1933   *
1934   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
1935   *
1936   */
1937  @EnsuresNonNullIf(result=true, expression="#1")
1938  @Pure
1939  public static boolean eltwiseEqual(byte @Nullable [] seq) {
1940  if (seq == null) {
1941    return false;
1942  }
1943    for (int i = 0 ; i < seq.length ; i++) {
1944      if (i < seq.length - 1) {
1945        if (ne(seq[i], seq[i + 1])) {
1946          return false;
1947        }
1948      }
1949    }
1950    return true;
1951  }
1952
1953  /** True iff for all applicable i, every seq[i] != seq[i+1].
1954   *
1955   * Meaning (in pseudo-FOL):
1956   *
1957   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
1958   *
1959   */
1960  @EnsuresNonNullIf(result=true, expression="#1")
1961  @Pure
1962  public static boolean eltwiseNotEqual(byte @Nullable [] seq) {
1963  if (seq == null) {
1964    return false;
1965  }
1966    for (int i = 0 ; i < seq.length ; i++) {
1967      if (i < seq.length - 1) {
1968        if (eq(seq[i], seq[i + 1])) {
1969          return false;
1970        }
1971      }
1972    }
1973    return true;
1974  }
1975
1976  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
1977   *
1978   * Meaning (in pseudo-FOL):
1979   *
1980   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
1981   *
1982   */
1983  @EnsuresNonNullIf(result=true, expression="#1")
1984  @Pure
1985  public static boolean eltwiseLT(byte @Nullable [] seq) {
1986  if (seq == null) {
1987    return false;
1988  }
1989    for (int i = 0 ; i < seq.length ; i++) {
1990      if (i < seq.length - 1) {
1991        if (gte(seq[i], seq[i + 1])) {
1992          return false;
1993        }
1994      }
1995    }
1996    return true;
1997  }
1998
1999  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
2000   *
2001   * Meaning (in pseudo-FOL):
2002   *
2003   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
2004   *
2005   */
2006  @EnsuresNonNullIf(result=true, expression="#1")
2007  @Pure
2008  public static boolean eltwiseLTE(byte @Nullable [] seq) {
2009  if (seq == null) {
2010    return false;
2011  }
2012    for (int i = 0 ; i < seq.length ; i++) {
2013      if (i < seq.length - 1) {
2014        if (gt(seq[i], seq[i + 1])) {
2015          return false;
2016        }
2017      }
2018    }
2019    return true;
2020  }
2021
2022  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
2023   *
2024   * Meaning (in pseudo-FOL):
2025   *
2026   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
2027   *
2028   */
2029  @EnsuresNonNullIf(result=true, expression="#1")
2030  @Pure
2031  public static boolean eltwiseGT(byte @Nullable [] seq) {
2032  if (seq == null) {
2033    return false;
2034  }
2035    for (int i = 0 ; i < seq.length ; i++) {
2036      if (i < seq.length - 1) {
2037        if (lte(seq[i], seq[i + 1])) {
2038          return false;
2039        }
2040      }
2041    }
2042    return true;
2043  }
2044
2045  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
2046   *
2047   * Meaning (in pseudo-FOL):
2048   *
2049   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
2050   *
2051   */
2052  @EnsuresNonNullIf(result=true, expression="#1")
2053  @Pure
2054  public static boolean eltwiseGTE(byte @Nullable [] seq) {
2055  if (seq == null) {
2056    return false;
2057  }
2058    for (int i = 0 ; i < seq.length ; i++) {
2059      if (i < seq.length - 1) {
2060        if (lt(seq[i], seq[i + 1])) {
2061          return false;
2062        }
2063      }
2064    }
2065    return true;
2066  }
2067
2068  /** True iff for all applicable i, every seq[i] == i.
2069   *
2070   * Meaning (in pseudo-FOL):
2071   *
2072   * forall i in { 0..seq.length-1 } : seq[i] == i
2073   *
2074   */
2075  @EnsuresNonNullIf(result=true, expression="#1")
2076  @Pure
2077  public static boolean eltsEqualIndex(byte @Nullable [] seq) {
2078  if (seq == null) {
2079    return false;
2080  }
2081    for (int i = 0 ; i < seq.length ; i++) {
2082      if (ne(seq[i], i)) {
2083        return false;
2084      }
2085    }
2086    return true;
2087  }
2088
2089  /** True iff for all applicable i, every seq[i] != i.
2090   *
2091   * Meaning (in pseudo-FOL):
2092   *
2093   * forall i in { 0..seq.length-1 } : seq[i] != i
2094   *
2095   */
2096  @EnsuresNonNullIf(result=true, expression="#1")
2097  @Pure
2098  public static boolean eltsNotEqualIndex(byte @Nullable [] seq) {
2099  if (seq == null) {
2100    return false;
2101  }
2102    for (int i = 0 ; i < seq.length ; i++) {
2103      if (eq(seq[i], i)) {
2104        return false;
2105      }
2106    }
2107    return true;
2108  }
2109
2110  /** True iff for all applicable i, every seq[i] &lt; i.
2111   *
2112   * Meaning (in pseudo-FOL):
2113   *
2114   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
2115   *
2116   */
2117  @EnsuresNonNullIf(result=true, expression="#1")
2118  @Pure
2119  public static boolean eltsLtIndex(byte @Nullable [] seq) {
2120  if (seq == null) {
2121    return false;
2122  }
2123    for (int i = 0 ; i < seq.length ; i++) {
2124      if (gte(seq[i], i)) {
2125        return false;
2126      }
2127    }
2128    return true;
2129  }
2130
2131  /** True iff for all applicable i, every seq[i] &le; i.
2132   *
2133   * Meaning (in pseudo-FOL):
2134   *
2135   * forall i in { 0..seq.length-1 } : seq[i] &le; i
2136   *
2137   */
2138  @EnsuresNonNullIf(result=true, expression="#1")
2139  @Pure
2140  public static boolean eltsLteIndex(byte @Nullable [] seq) {
2141  if (seq == null) {
2142    return false;
2143  }
2144    for (int i = 0 ; i < seq.length ; i++) {
2145      if (gt(seq[i], i)) {
2146        return false;
2147      }
2148    }
2149    return true;
2150  }
2151
2152  /** True iff for all applicable i, every seq[i] &gt; i.
2153   *
2154   * Meaning (in pseudo-FOL):
2155   *
2156   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
2157   *
2158   */
2159  @EnsuresNonNullIf(result=true, expression="#1")
2160  @Pure
2161  public static boolean eltsGtIndex(byte @Nullable [] seq) {
2162  if (seq == null) {
2163    return false;
2164  }
2165    for (int i = 0 ; i < seq.length ; i++) {
2166      if (lte(seq[i], i)) {
2167        return false;
2168      }
2169    }
2170    return true;
2171  }
2172
2173  /** True iff for all applicable i, every seq[i] &ge; i.
2174   *
2175   * Meaning (in pseudo-FOL):
2176   *
2177   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
2178   *
2179   */
2180  @EnsuresNonNullIf(result=true, expression="#1")
2181  @Pure
2182  public static boolean eltsGteIndex(byte @Nullable [] seq) {
2183  if (seq == null) {
2184    return false;
2185  }
2186    for (int i = 0 ; i < seq.length ; i++) {
2187      if (lt(seq[i], i)) {
2188        return false;
2189      }
2190    }
2191    return true;
2192  }
2193
2194  /// Deferencing (accessing) fields
2195
2196  /**
2197   * collectbyte accepts an object and a list of fields (one of which is of array type, and the
2198   * rest of which are not), and produces an array in which the original object has had the given
2199   * fields accessed.
2200   *
2201   * <p>Daikon creates invariants over "variables" such as the following.
2202   *
2203   * <dl>
2204   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
2205   *              for all y's in array x.arr.</dd>
2206   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
2207   *              for all x's in array arr.</dd>
2208   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
2209   * </dl>
2210   *
2211   * <p>The collectbyte() method does this collecting work.
2212   *
2213   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
2214   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
2215   * elements that result from following the fields, one of which is assumed to be an array.
2216   *
2217   * <p>
2218   * requires: fieldStr.length() &gt; 0 and object != null
2219   * <p>
2220   * requires: fieldStr contains only field names, no "[]" strings.
2221   * <p>
2222   * requires: the method only works for field sequences with exactly one field representing an
2223   * array. For example, the collection a[].b[].c will fail.
2224   *
2225   * @return if the resulting collection is of non-primitive type, then returns an array of type
2226   * Object[]. Returns null if any array or field access causes an exception.
2227   */
2228
2229  @SideEffectFree
2230  public static byte @Nullable [] collectbyte(@Nullable Object object, @Nullable String fieldStr) {
2231
2232    if (object == null) {
2233      return null;
2234    }
2235    if (fieldStr == null) {
2236      return null;
2237    }
2238
2239    // assert fieldStr != null && !"".equals(fieldStr);
2240    String[] fieldNames = fieldStr.split("\\.");
2241    byte[] retval = collectbyte(object, fieldNames, 0);
2242    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
2243    return retval;
2244  }
2245
2246  /** Helper method for collectbyte(Object, String).
2247   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
2248   * @see collectbyte(Object, String)
2249   */
2250  // @PolyNull does not work for return type, because null is returned on error.
2251  @SideEffectFree
2252  private static byte @Nullable [] collectbyte(@Nullable Object object,
2253                                                   String[] fields, int fieldsStartIdx) {
2254
2255    if (object == null) {
2256      return null;
2257    }
2258    assert (fields != null);
2259    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
2260
2261    Object fieldObj;
2262    try {
2263      Field field = (object instanceof java.lang.Class<?>)
2264        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
2265        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
2266      field.setAccessible(true);
2267      // Class cls = field.getType();
2268      fieldObj = field.get(object);
2269      // System.out.println("***fieldObj="+fieldObj);
2270
2271    } catch (Exception e) {
2272      return null;
2273
2274    }
2275
2276    if (fieldObj == null) {
2277      return null;
2278    }
2279
2280    // base case: just accessed the last field
2281    if (fields.length - 1 == fieldsStartIdx) {
2282
2283      if (fieldObj.getClass().isArray()) {
2284        // last field is an array
2285        return (byte[])fieldObj;
2286      } else {
2287        // This hack should be removed in favor of, at "oneEltArray = ..."
2288        // below, calling a version of collectbyte_field that throws an
2289        // error.  Then, this case becomes a run-time error.  -MDE
2290
2291        // Just one element; return a one-element array.
2292        // assert cls.equals(Byte.TYPE);
2293        return new byte[] { ((Byte)fieldObj).byteValue() };
2294      }
2295    } else {
2296      // recursive case: more fields to access after this one
2297
2298      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
2299
2300        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
2301        byte[] intermediate = new byte[collection.size()];
2302        int index = 0;
2303        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
2304          Object obj = i.next();
2305          byte[] oneEltArray = collectbyte(obj, fields, fieldsStartIdx + 1);
2306          if (oneEltArray == null) {
2307            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
2308          }
2309          // assert oneEltArray.length == 1;
2310          intermediate[index++] = oneEltArray[0];
2311        }
2312        return intermediate;
2313      } else if (fieldObj.getClass().isArray()) {
2314
2315        // collect elements across array
2316        byte[] intermediate = new byte[Array.getLength(fieldObj)];
2317        for (int i = 0 ; i < intermediate.length ; i++) {
2318          Object obj = Array.get(fieldObj, i);
2319          byte[] oneEltArray = collectbyte(obj, fields, fieldsStartIdx + 1);
2320          if (oneEltArray == null) {
2321            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
2322          }
2323          // assert oneEltArray.length == 1;
2324          intermediate[i] = oneEltArray[0];
2325        }
2326        return intermediate;
2327      } else {
2328
2329        return collectbyte(fieldObj, fields, fieldsStartIdx + 1);
2330      }
2331    }
2332  }
2333
2334  /**
2335   * Returns the results of dereferencing the fields for 'object'. For example, the call
2336   *
2337   * <pre>collectbyte_field(x, "f.g.h")</pre>
2338   *
2339   * has the same value as
2340   *
2341   * <pre>x.f.g.h</pre>.
2342   * Returns a default value if any field access causes an exception.
2343   */
2344  @SideEffectFree
2345  public static byte collectbyte_field(Object object, String fieldStr) {
2346
2347    if (object == null) {
2348      return Byte.MAX_VALUE; // return default value
2349    }
2350    if (fieldStr == null) {
2351      return Byte.MAX_VALUE; // return default value
2352    }
2353
2354    String[] fieldNames = fieldStr.split("\\.");
2355
2356    // Holds the intermediate (and final) result
2357    Object fieldObj = object;
2358
2359    for (int i = 0 ; i < fieldNames.length ; i++) {
2360
2361      String fieldName = fieldNames[i];
2362
2363      try {
2364        Field field =
2365          (fieldObj instanceof java.lang.Class<?>)
2366          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
2367          : fieldObj.getClass().getDeclaredField(fieldName);
2368        field.setAccessible(true);
2369        fieldObj = field.get(fieldObj);
2370
2371        if (fieldObj == null) {
2372          return Byte.MAX_VALUE; // return default value
2373        }
2374
2375      } catch (Exception e) {
2376        return Byte.MAX_VALUE; // return default value
2377
2378      }
2379
2380    }
2381
2382    return ((Byte)fieldObj).byteValue();
2383  }
2384
2385  ///////////////////////////////////////////////////////////////////////////
2386  /// Methods for "char" (from QuantBody.java.jpp)
2387  ///
2388
2389  /**
2390   * Returns the ith element of the array or collection argument. If the argument is null or not an
2391   * array or collection, returns a default value (Character.MAX_VALUE).
2392   */
2393
2394  @Pure
2395  public static char getElement_char(Object o, long i) {
2396    if (o == null) {
2397      return Character.MAX_VALUE; // return default value
2398    }
2399    java.lang.Class<?> c = o.getClass();
2400    if (c.isArray()) {
2401      return java.lang.reflect.Array.getChar(o, (int)i);
2402    } else if (o instanceof java.util.AbstractCollection<?>) {
2403      return java.lang.reflect.Array.getChar(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
2404    } else {
2405      return Character.MAX_VALUE; // return default value
2406    }
2407  }
2408
2409  @Pure
2410  public static char getElement_char(char[] arr, long i) {
2411    if (arr == null) {
2412      return Character.MAX_VALUE; // return default value
2413    }
2414    return arr[(int)i];
2415  }
2416
2417  private static boolean eq(char x, char y) {
2418    return x == y;
2419  }
2420
2421  private static boolean ne(char x, char y) {
2422    return x != y;
2423  }
2424
2425  private static boolean lt(char x, char y) {
2426    return x < y;
2427  }
2428
2429  private static boolean lte(char x, char y) {
2430    return x <= y;
2431  }
2432
2433  private static boolean gt(char x, char y) {
2434    return x > y;
2435  }
2436
2437  private static boolean gte(char x, char y) {
2438    return x >= y;
2439  }
2440
2441  /** True iff both sequences are non-null and have the same length. */
2442  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
2443  @Pure
2444  public static boolean sameLength(char @Nullable [] seq1, char @Nullable [] seq2) {
2445    return ((seq1 != null)
2446            && (seq2 != null)
2447            && seq1.length == seq2.length);
2448  }
2449
2450  /**
2451   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
2452   *
2453   * <p>If either array is null, returns null. If either array is empty, returns only those
2454   * elements in the other array. If both arrays are empty, returns a new empty array.
2455   */
2456  @SideEffectFree
2457  public static char @PolyNull [] concat(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2458    if (seq1 == null) {
2459      return null;
2460    }
2461    if (seq2 == null) {
2462      return null;
2463    }
2464    return ArraysPlume.concat(seq1, seq2);
2465  }
2466
2467  /**
2468   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
2469   * assurances about the order or repetition of elements: elements may be repeated, and their
2470   * order may be different from the order of elements in seq1 and seq2.
2471   */
2472  @SideEffectFree
2473  public static char @PolyNull [] union(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2474    if (seq1 == null) {
2475      return null;
2476    }
2477    if (seq2 == null) {
2478      return null;
2479    }
2480    return concat(seq1, seq2);
2481  }
2482
2483  /**
2484   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
2485   * gives no assurances about the order or repetition of elements: elements may be repeated, and
2486   * their order may be different from the order of elements in seq1 and seq2.
2487   */
2488  @Pure
2489  public static char @PolyNull [] intersection(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2490    if (seq1 == null) {
2491      return null;
2492    }
2493    if (seq2 == null) {
2494      return null;
2495    }
2496    char[] intermediate = new char[Math.min(seq1.length, seq2.length)];
2497    int length = 0;
2498    for (int i = 0 ; i < seq1.length ; i++) {
2499      if (memberOf(seq1[i], seq2) ) {
2500        intermediate[length++] = seq1[i];
2501      }
2502    }
2503    return ArraysPlume.subarray(intermediate, 0, length);
2504  }
2505
2506  /**
2507   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
2508   * no assurances about the order or repetition of elements: elements may be repeated, and their
2509   * order may be different from the order of elements in seq1 and seq2.
2510   */
2511  @Pure
2512  public static char @PolyNull [] setDiff(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2513    if (seq1 == null) {
2514      return null;
2515    }
2516    if (seq2 == null) {
2517      return null;
2518    }
2519    char[] intermediate = new char[seq1.length];
2520    int length = 0;
2521    for (int i = 0 ; i < seq1.length ; i++) {
2522      if (!memberOf(seq1[i], seq2)) {
2523        intermediate[length++] = seq1[i];
2524      }
2525    }
2526    return ArraysPlume.subarray(intermediate, 0, length);
2527  }
2528
2529  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
2530  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2531  @Pure
2532  public static boolean setEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2533    if (seq1 == null) {
2534      return false;
2535    }
2536    if (seq2 == null) {
2537      return false;
2538    }
2539    for (int i = 0; i < seq1.length ; i++) {
2540      if (!memberOf(seq1[i], seq2) ) {
2541        return false;
2542      }
2543    }
2544    for (int i = 0; i < seq2.length ; i++) {
2545      if (!memberOf(seq2[i], seq1) ) {
2546        return false;
2547      }
2548    }
2549    return true;
2550  }
2551
2552  /** True iff seq1 is the reverse of seq2.
2553   *
2554   * Meaning (in pseudo-FOL):
2555   *
2556   * <pre>
2557   * /\ seq1.length == seq2.length
2558   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
2559   * </pre>
2560   *
2561   */
2562  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2563  @Pure
2564  public static boolean isReverse(char[] seq1, char[] seq2) {
2565    if (!sameLength(seq1, seq2)) {
2566      return false;
2567    }
2568    assert seq1 != null && seq2 != null; // because sameLength() = true
2569    int length = seq1.length;
2570    for (int i = 0 ; i < length ; i++) {
2571      if (ne(seq1[i], seq2[length - i - 1])) {
2572        return false;
2573      }
2574    }
2575    return true;
2576  }
2577
2578  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
2579  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2580  @Pure
2581  public static boolean subsetOf(char @Nullable [] seq1, char @Nullable [] seq2) {
2582    if (seq1 == null) {
2583      return false;
2584    }
2585    if (seq2 == null) {
2586      return false;
2587    }
2588    for (int i = 0 ; i < seq1.length ; i++) {
2589      if (!memberOf(seq1[i], seq2)) {
2590        return false;
2591      }
2592    }
2593    return true;
2594  }
2595
2596  /** Returns true iff seq contains no duplicate elements. */
2597  @EnsuresNonNullIf(result=true, expression="#1")
2598  @Pure
2599  public static boolean noDups(char @Nullable [] seq) {
2600    if (seq == null) {
2601      return false;
2602    }
2603    return ArraysPlume.noDuplicates(seq);
2604  }
2605
2606 /** Returns true iff elt is in array arr. */
2607  @EnsuresNonNullIf(result=true, expression="#2")
2608  @Pure
2609  public static boolean memberOf(char elt, char @Nullable [] arr) {
2610    if (arr == null) {
2611      return false;
2612    }
2613    for (int i = 0 ; i < arr.length ; i++) {
2614      if (eq(arr[i], elt)) {
2615        return true;
2616      }
2617    }
2618    return false;
2619  }
2620
2621  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
2622  @Pure
2623  public static char @PolyNull [] slice(char @PolyNull [] seq, int start, int end) {
2624    if (seq == null) {
2625      return null;
2626    }
2627    int sliceStart = start;
2628    int sliceEnd = end;
2629    if (start < 0) {
2630      return new char[] { };
2631    }
2632    if (end > seq.length - 1) {
2633      return new char[] { };
2634    }
2635    if (sliceStart > sliceEnd) {
2636      return new char[] { };
2637    }
2638    int length = sliceEnd - sliceStart + 1;
2639    return ArraysPlume.subarray(seq, sliceStart, length);
2640  }
2641
2642  @Pure
2643  public static char @PolyNull [] slice(char @PolyNull [] seq, long start, int end) {
2644    return slice(seq, (int)start, end);
2645  }
2646  @Pure
2647  public static char @PolyNull [] slice(char @PolyNull [] seq, int start, long end) {
2648    return slice(seq, start, (int)end);
2649  }
2650  @Pure
2651  public static char @PolyNull [] slice(char @PolyNull [] seq, long start, long end) {
2652    return slice(seq, (int)start, (int)end);
2653  }
2654
2655  /** True iff all elements in arr equal elt.
2656   *
2657   * Meaning (in pseudo-FOL):
2658   *
2659   * forall i in { 0..arr.length-1 } : arr[i] == elt
2660   *
2661   */
2662  @EnsuresNonNullIf(result=true, expression="#1")
2663  @Pure
2664  public static boolean eltsEqual(char @Nullable [] arr, char elt) {
2665    if (arr == null) {
2666      return false;
2667    }
2668    for (int i = 0 ; i < arr.length ; i++) {
2669      if (ne(arr[i], elt)) {
2670        return false;
2671      }
2672    }
2673    return true;
2674  }
2675
2676  /** True iff every element in arr does not equal elt.
2677   *
2678   * Meaning (in pseudo-FOL):
2679   *
2680   * forall i in { 0..arr.length-1 } : arr[i] != elt
2681   *
2682   */
2683  @EnsuresNonNullIf(result=true, expression="#1")
2684  @Pure
2685  public static boolean eltsNotEqual(char @Nullable [] arr, char elt) {
2686    if (arr == null) {
2687      return false;
2688    }
2689    for (int i = 0 ; i < arr.length ; i++) {
2690      if (eq(arr[i], elt)) {
2691        return false;
2692      }
2693    }
2694    return true;
2695  }
2696
2697  /** True iff every element in arr is greater than elt.
2698   *
2699   * Meaning (in pseudo-FOL):
2700   *
2701   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
2702   *
2703   */
2704  @EnsuresNonNullIf(result=true, expression="#1")
2705  @Pure
2706  public static boolean eltsGT(char @Nullable [] arr, char elt) {
2707    if (arr == null) {
2708      return false;
2709    }
2710    for (int i = 0 ; i < arr.length ; i++) {
2711      if (lte(arr[i], elt)) {
2712        return false;
2713      }
2714    }
2715    return true;
2716  }
2717
2718  /** True iff every element in arr is greater than or equal to elt.
2719   *
2720   * Meaning (in pseudo-FOL):
2721   *
2722   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
2723   *
2724   */
2725  @EnsuresNonNullIf(result=true, expression="#1")
2726  @Pure
2727  public static boolean eltsGTE(char @Nullable [] arr, char elt) {
2728    if (arr == null) {
2729      return false;
2730    }
2731    for (int i = 0 ; i < arr.length ; i++) {
2732      if (lt(arr[i], elt)) {
2733        return false;
2734      }
2735    }
2736    return true;
2737  }
2738
2739  /** True iff every element in arr is less than elt.
2740   *
2741   * Meaning (in pseudo-FOL):
2742   *
2743   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
2744   *
2745   */
2746  @EnsuresNonNullIf(result=true, expression="#1")
2747  @Pure
2748  public static boolean eltsLT(char @Nullable [] arr, char elt) {
2749    if (arr == null) {
2750      return false;
2751    }
2752    for (int i = 0 ; i < arr.length ; i++) {
2753      if (gte(arr[i], elt)) {
2754        return false;
2755      }
2756    }
2757    return true;
2758  }
2759
2760  /** True iff every element in arr is less than or equal to elt.
2761   *
2762   * Meaning (in pseudo-FOL):
2763   *
2764   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
2765   *
2766   */
2767  @EnsuresNonNullIf(result=true, expression="#1")
2768  @Pure
2769  public static boolean eltsLTE(char @Nullable [] arr, char elt) {
2770    if (arr == null) {
2771      return false;
2772    }
2773    for (int i = 0 ; i < arr.length ; i++) {
2774      if (gt(arr[i], elt)) {
2775        return false;
2776      }
2777    }
2778    return true;
2779  }
2780
2781  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
2782   *
2783   * Meaning (in pseudo-FOL):
2784   *
2785   * /\ seq1.length == se2.length
2786   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
2787   *
2788   */
2789
2790  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2791  @Pure
2792  public static boolean pairwiseEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2793    if (!sameLength(seq1, seq2)) {
2794      return false;
2795    }
2796    assert seq1 != null && seq2 != null; // because sameLength() = true
2797    for (int i = 0 ; i < seq1.length ; i++) {
2798      if (ne(seq1[i], seq2[i])) {
2799        return false;
2800      }
2801    }
2802    return true;
2803  }
2804
2805  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
2806   *
2807   * Meaning (in pseudo-FOL):
2808   *
2809   * /\ seq1.length == se2.length
2810   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
2811   *
2812   */
2813  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2814  @Pure
2815  public static boolean pairwiseNotEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2816    if (!sameLength(seq1, seq2)) {
2817      return false;
2818    }
2819    assert seq1 != null && seq2 != null; // because sameLength() = true
2820    for (int i = 0 ; i < seq1.length ; i++) {
2821      if (eq(seq1[i], seq2[i])) {
2822        return false;
2823      }
2824    }
2825    return true;
2826  }
2827
2828  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
2829   *
2830   * Meaning (in pseudo-FOL):
2831   *
2832   * /\ seq1.length == se2.length
2833   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
2834   *
2835   */
2836  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2837  @Pure
2838  public static boolean pairwiseLT(char @Nullable [] seq1, char @Nullable [] seq2) {
2839    if (!sameLength(seq1, seq2)) {
2840      return false;
2841    }
2842    assert seq1 != null && seq2 != null; // because sameLength() = true
2843    for (int i = 0 ; i < seq1.length ; i++) {
2844      if (gte(seq1[i], seq2[i])) {
2845        return false;
2846      }
2847    }
2848    return true;
2849  }
2850
2851  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
2852   * Meaning (in pseudo-FOL):
2853   *
2854   * /\ seq1.length == se2.length
2855   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
2856   *
2857   */
2858  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2859  @Pure
2860  public static boolean pairwiseLTE(char @Nullable [] seq1, char @Nullable [] seq2) {
2861    if (!sameLength(seq1, seq2)) {
2862      return false;
2863    }
2864    assert seq1 != null && seq2 != null; // because sameLength() = true
2865    for (int i = 0 ; i < seq1.length ; i++) {
2866      if (gt(seq1[i], seq2[i])) {
2867        return false;
2868      }
2869    }
2870    return true;
2871  }
2872
2873  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
2874   * Meaning (in pseudo-FOL):
2875   *
2876   * /\ seq1.length == se2.length
2877   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
2878   *
2879   */
2880  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2881  @Pure
2882  public static boolean pairwiseGT(char @Nullable [] seq1, char @Nullable [] seq2) {
2883    if (!sameLength(seq1, seq2)) {
2884      return false;
2885    }
2886    assert seq1 != null && seq2 != null; // because sameLength() = true
2887    for (int i = 0 ; i < seq1.length ; i++) {
2888      if (lte(seq1[i], seq2[i])) {
2889        return false;
2890      }
2891    }
2892    return true;
2893  }
2894
2895  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
2896   * Meaning (in pseudo-FOL):
2897   *
2898   * /\ seq1.length == se2.length
2899   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
2900   *
2901   */
2902  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2903  @Pure
2904  public static boolean pairwiseGTE(char @Nullable [] seq1, char @Nullable [] seq2) {
2905    if (!sameLength(seq1, seq2)) {
2906      return false;
2907    }
2908    assert seq1 != null && seq2 != null; // because sameLength() = true
2909    for (int i = 0 ; i < seq1.length ; i++) {
2910      if (lt(seq1[i], seq2[i])) {
2911        return false;
2912      }
2913    }
2914    return true;
2915  }
2916
2917  /**
2918   * Returns true iff seq1 is lexically equal to seq2.
2919   * For equality, "lexically" and "pairwise" are the same.
2920   */
2921  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2922  @Pure
2923  public static boolean lexEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2924    if (seq1 == null) {
2925      return false;
2926    }
2927    if (seq2 == null) {
2928      return false;
2929    }
2930    return pairwiseEqual(seq1, seq2);
2931  }
2932
2933  /** Returns true iff seq1 is lexically not equal to seq2. */
2934  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2935  @Pure
2936  public static boolean lexNotEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2937    if (seq1 == null) {
2938      return false;
2939    }
2940    if (seq2 == null) {
2941      return false;
2942    }
2943    return !lexEqual(seq1, seq2);
2944  }
2945
2946  /** Returns true iff seq1 is lexically &lt;  seq2. */
2947  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2948  @Pure
2949  public static boolean lexLT(char @Nullable [] seq1, char @Nullable [] seq2) {
2950    if (seq1 == null) {
2951      return false;
2952    }
2953    if (seq2 == null) {
2954      return false;
2955    }
2956    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
2957    for (int i = 0 ; i < minlength ; i++) {
2958      if (gt(seq1[i], seq2[i])) {
2959        return false;
2960      } else if (lt(seq1[i], seq2[i])) {
2961        return true;
2962      }
2963    }
2964    if (seq1.length >= seq2.length) {
2965      return false;
2966    }
2967    return true;
2968  }
2969
2970  /** Returns true iff seq1 is lexically &le; to seq2. */
2971  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2972  @Pure
2973  public static boolean lexLTE(char @Nullable [] seq1, char @Nullable [] seq2) {
2974    if (seq1 == null) {
2975      return false;
2976    }
2977    if (seq2 == null) {
2978      return false;
2979    }
2980    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
2981    for (int i = 0 ; i < minlength ; i++) {
2982      if (gt(seq1[i], seq2[i])) {
2983        return false;
2984      } else if (lt(seq1[i], seq2[i])) {
2985        return true;
2986      }
2987    }
2988    if (seq1.length > seq2.length) {
2989      return false;
2990    }
2991    return true;
2992  }
2993
2994  /** Returns true iff seq1 is lexically &gt; to seq2. */
2995  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2996  @Pure
2997  public static boolean lexGT(char @Nullable [] seq1, char @Nullable [] seq2) {
2998  if (seq1 == null) {
2999    return false;
3000  }
3001  if (seq2 == null) {
3002    return false;
3003  }
3004    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
3005    for (int i = 0 ; i < minlength ; i++) {
3006      if (lt(seq1[i], seq2[i])) {
3007        return false;
3008      } else if (gt(seq1[i], seq2[i])) {
3009        return true;
3010      }
3011    }
3012    if (seq1.length <= seq2.length) {
3013      return false;
3014    }
3015    return true;
3016  }
3017
3018  /** Returns true iff seq1 is lexically &ge; to seq2. */
3019  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3020  @Pure
3021  public static boolean lexGTE(char @Nullable [] seq1, char @Nullable [] seq2) {
3022  if (seq1 == null) {
3023    return false;
3024  }
3025  if (seq2 == null) {
3026    return false;
3027  }
3028    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
3029    for (int i = 0 ; i < minlength ; i++) {
3030      if (lt(seq1[i], seq2[i])) {
3031        return false;
3032      } else if (gt(seq1[i], seq2[i])) {
3033        return true;
3034      }
3035    }
3036    if (seq1.length < seq2.length) {
3037      return false;
3038    }
3039    return true;
3040  }
3041
3042  /** True iff for all applicable i, every seq[i] == seq[i+1].
3043   *
3044   * Meaning (in pseudo-FOL):
3045   *
3046   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
3047   *
3048   */
3049  @EnsuresNonNullIf(result=true, expression="#1")
3050  @Pure
3051  public static boolean eltwiseEqual(char @Nullable [] seq) {
3052  if (seq == null) {
3053    return false;
3054  }
3055    for (int i = 0 ; i < seq.length ; i++) {
3056      if (i < seq.length - 1) {
3057        if (ne(seq[i], seq[i + 1])) {
3058          return false;
3059        }
3060      }
3061    }
3062    return true;
3063  }
3064
3065  /** True iff for all applicable i, every seq[i] != seq[i+1].
3066   *
3067   * Meaning (in pseudo-FOL):
3068   *
3069   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
3070   *
3071   */
3072  @EnsuresNonNullIf(result=true, expression="#1")
3073  @Pure
3074  public static boolean eltwiseNotEqual(char @Nullable [] seq) {
3075  if (seq == null) {
3076    return false;
3077  }
3078    for (int i = 0 ; i < seq.length ; i++) {
3079      if (i < seq.length - 1) {
3080        if (eq(seq[i], seq[i + 1])) {
3081          return false;
3082        }
3083      }
3084    }
3085    return true;
3086  }
3087
3088  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
3089   *
3090   * Meaning (in pseudo-FOL):
3091   *
3092   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
3093   *
3094   */
3095  @EnsuresNonNullIf(result=true, expression="#1")
3096  @Pure
3097  public static boolean eltwiseLT(char @Nullable [] seq) {
3098  if (seq == null) {
3099    return false;
3100  }
3101    for (int i = 0 ; i < seq.length ; i++) {
3102      if (i < seq.length - 1) {
3103        if (gte(seq[i], seq[i + 1])) {
3104          return false;
3105        }
3106      }
3107    }
3108    return true;
3109  }
3110
3111  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
3112   *
3113   * Meaning (in pseudo-FOL):
3114   *
3115   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
3116   *
3117   */
3118  @EnsuresNonNullIf(result=true, expression="#1")
3119  @Pure
3120  public static boolean eltwiseLTE(char @Nullable [] seq) {
3121  if (seq == null) {
3122    return false;
3123  }
3124    for (int i = 0 ; i < seq.length ; i++) {
3125      if (i < seq.length - 1) {
3126        if (gt(seq[i], seq[i + 1])) {
3127          return false;
3128        }
3129      }
3130    }
3131    return true;
3132  }
3133
3134  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
3135   *
3136   * Meaning (in pseudo-FOL):
3137   *
3138   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
3139   *
3140   */
3141  @EnsuresNonNullIf(result=true, expression="#1")
3142  @Pure
3143  public static boolean eltwiseGT(char @Nullable [] seq) {
3144  if (seq == null) {
3145    return false;
3146  }
3147    for (int i = 0 ; i < seq.length ; i++) {
3148      if (i < seq.length - 1) {
3149        if (lte(seq[i], seq[i + 1])) {
3150          return false;
3151        }
3152      }
3153    }
3154    return true;
3155  }
3156
3157  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
3158   *
3159   * Meaning (in pseudo-FOL):
3160   *
3161   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
3162   *
3163   */
3164  @EnsuresNonNullIf(result=true, expression="#1")
3165  @Pure
3166  public static boolean eltwiseGTE(char @Nullable [] seq) {
3167  if (seq == null) {
3168    return false;
3169  }
3170    for (int i = 0 ; i < seq.length ; i++) {
3171      if (i < seq.length - 1) {
3172        if (lt(seq[i], seq[i + 1])) {
3173          return false;
3174        }
3175      }
3176    }
3177    return true;
3178  }
3179
3180  /** True iff for all applicable i, every seq[i] == i.
3181   *
3182   * Meaning (in pseudo-FOL):
3183   *
3184   * forall i in { 0..seq.length-1 } : seq[i] == i
3185   *
3186   */
3187  @EnsuresNonNullIf(result=true, expression="#1")
3188  @Pure
3189  public static boolean eltsEqualIndex(char @Nullable [] seq) {
3190  if (seq == null) {
3191    return false;
3192  }
3193    for (int i = 0 ; i < seq.length ; i++) {
3194      if (ne(seq[i], i)) {
3195        return false;
3196      }
3197    }
3198    return true;
3199  }
3200
3201  /** True iff for all applicable i, every seq[i] != i.
3202   *
3203   * Meaning (in pseudo-FOL):
3204   *
3205   * forall i in { 0..seq.length-1 } : seq[i] != i
3206   *
3207   */
3208  @EnsuresNonNullIf(result=true, expression="#1")
3209  @Pure
3210  public static boolean eltsNotEqualIndex(char @Nullable [] seq) {
3211  if (seq == null) {
3212    return false;
3213  }
3214    for (int i = 0 ; i < seq.length ; i++) {
3215      if (eq(seq[i], i)) {
3216        return false;
3217      }
3218    }
3219    return true;
3220  }
3221
3222  /** True iff for all applicable i, every seq[i] &lt; i.
3223   *
3224   * Meaning (in pseudo-FOL):
3225   *
3226   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
3227   *
3228   */
3229  @EnsuresNonNullIf(result=true, expression="#1")
3230  @Pure
3231  public static boolean eltsLtIndex(char @Nullable [] seq) {
3232  if (seq == null) {
3233    return false;
3234  }
3235    for (int i = 0 ; i < seq.length ; i++) {
3236      if (gte(seq[i], i)) {
3237        return false;
3238      }
3239    }
3240    return true;
3241  }
3242
3243  /** True iff for all applicable i, every seq[i] &le; i.
3244   *
3245   * Meaning (in pseudo-FOL):
3246   *
3247   * forall i in { 0..seq.length-1 } : seq[i] &le; i
3248   *
3249   */
3250  @EnsuresNonNullIf(result=true, expression="#1")
3251  @Pure
3252  public static boolean eltsLteIndex(char @Nullable [] seq) {
3253  if (seq == null) {
3254    return false;
3255  }
3256    for (int i = 0 ; i < seq.length ; i++) {
3257      if (gt(seq[i], i)) {
3258        return false;
3259      }
3260    }
3261    return true;
3262  }
3263
3264  /** True iff for all applicable i, every seq[i] &gt; i.
3265   *
3266   * Meaning (in pseudo-FOL):
3267   *
3268   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
3269   *
3270   */
3271  @EnsuresNonNullIf(result=true, expression="#1")
3272  @Pure
3273  public static boolean eltsGtIndex(char @Nullable [] seq) {
3274  if (seq == null) {
3275    return false;
3276  }
3277    for (int i = 0 ; i < seq.length ; i++) {
3278      if (lte(seq[i], i)) {
3279        return false;
3280      }
3281    }
3282    return true;
3283  }
3284
3285  /** True iff for all applicable i, every seq[i] &ge; i.
3286   *
3287   * Meaning (in pseudo-FOL):
3288   *
3289   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
3290   *
3291   */
3292  @EnsuresNonNullIf(result=true, expression="#1")
3293  @Pure
3294  public static boolean eltsGteIndex(char @Nullable [] seq) {
3295  if (seq == null) {
3296    return false;
3297  }
3298    for (int i = 0 ; i < seq.length ; i++) {
3299      if (lt(seq[i], i)) {
3300        return false;
3301      }
3302    }
3303    return true;
3304  }
3305
3306  /// Deferencing (accessing) fields
3307
3308  /**
3309   * collectchar accepts an object and a list of fields (one of which is of array type, and the
3310   * rest of which are not), and produces an array in which the original object has had the given
3311   * fields accessed.
3312   *
3313   * <p>Daikon creates invariants over "variables" such as the following.
3314   *
3315   * <dl>
3316   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
3317   *              for all y's in array x.arr.</dd>
3318   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
3319   *              for all x's in array arr.</dd>
3320   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
3321   * </dl>
3322   *
3323   * <p>The collectchar() method does this collecting work.
3324   *
3325   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
3326   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
3327   * elements that result from following the fields, one of which is assumed to be an array.
3328   *
3329   * <p>
3330   * requires: fieldStr.length() &gt; 0 and object != null
3331   * <p>
3332   * requires: fieldStr contains only field names, no "[]" strings.
3333   * <p>
3334   * requires: the method only works for field sequences with exactly one field representing an
3335   * array. For example, the collection a[].b[].c will fail.
3336   *
3337   * @return if the resulting collection is of non-primitive type, then returns an array of type
3338   * Object[]. Returns null if any array or field access causes an exception.
3339   */
3340
3341  @SideEffectFree
3342  public static char @Nullable [] collectchar(@Nullable Object object, @Nullable String fieldStr) {
3343
3344    if (object == null) {
3345      return null;
3346    }
3347    if (fieldStr == null) {
3348      return null;
3349    }
3350
3351    // assert fieldStr != null && !"".equals(fieldStr);
3352    String[] fieldNames = fieldStr.split("\\.");
3353    char[] retval = collectchar(object, fieldNames, 0);
3354    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
3355    return retval;
3356  }
3357
3358  /** Helper method for collectchar(Object, String).
3359   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
3360   * @see collectchar(Object, String)
3361   */
3362  // @PolyNull does not work for return type, because null is returned on error.
3363  @SideEffectFree
3364  private static char @Nullable [] collectchar(@Nullable Object object,
3365                                                   String[] fields, int fieldsStartIdx) {
3366
3367    if (object == null) {
3368      return null;
3369    }
3370    assert (fields != null);
3371    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
3372
3373    Object fieldObj;
3374    try {
3375      Field field = (object instanceof java.lang.Class<?>)
3376        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
3377        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
3378      field.setAccessible(true);
3379      // Class cls = field.getType();
3380      fieldObj = field.get(object);
3381      // System.out.println("***fieldObj="+fieldObj);
3382
3383    } catch (Exception e) {
3384      return null;
3385
3386    }
3387
3388    if (fieldObj == null) {
3389      return null;
3390    }
3391
3392    // base case: just accessed the last field
3393    if (fields.length - 1 == fieldsStartIdx) {
3394
3395      if (fieldObj.getClass().isArray()) {
3396        // last field is an array
3397        return (char[])fieldObj;
3398      } else {
3399        // This hack should be removed in favor of, at "oneEltArray = ..."
3400        // below, calling a version of collectchar_field that throws an
3401        // error.  Then, this case becomes a run-time error.  -MDE
3402
3403        // Just one element; return a one-element array.
3404        // assert cls.equals(Character.TYPE);
3405        return new char[] { ((Character)fieldObj).charValue() };
3406      }
3407    } else {
3408      // recursive case: more fields to access after this one
3409
3410      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
3411
3412        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
3413        char[] intermediate = new char[collection.size()];
3414        int index = 0;
3415        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
3416          Object obj = i.next();
3417          char[] oneEltArray = collectchar(obj, fields, fieldsStartIdx + 1);
3418          if (oneEltArray == null) {
3419            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
3420          }
3421          // assert oneEltArray.length == 1;
3422          intermediate[index++] = oneEltArray[0];
3423        }
3424        return intermediate;
3425      } else if (fieldObj.getClass().isArray()) {
3426
3427        // collect elements across array
3428        char[] intermediate = new char[Array.getLength(fieldObj)];
3429        for (int i = 0 ; i < intermediate.length ; i++) {
3430          Object obj = Array.get(fieldObj, i);
3431          char[] oneEltArray = collectchar(obj, fields, fieldsStartIdx + 1);
3432          if (oneEltArray == null) {
3433            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
3434          }
3435          // assert oneEltArray.length == 1;
3436          intermediate[i] = oneEltArray[0];
3437        }
3438        return intermediate;
3439      } else {
3440
3441        return collectchar(fieldObj, fields, fieldsStartIdx + 1);
3442      }
3443    }
3444  }
3445
3446  /**
3447   * Returns the results of dereferencing the fields for 'object'. For example, the call
3448   *
3449   * <pre>collectchar_field(x, "f.g.h")</pre>
3450   *
3451   * has the same value as
3452   *
3453   * <pre>x.f.g.h</pre>.
3454   * Returns a default value if any field access causes an exception.
3455   */
3456  @SideEffectFree
3457  public static char collectchar_field(Object object, String fieldStr) {
3458
3459    if (object == null) {
3460      return Character.MAX_VALUE; // return default value
3461    }
3462    if (fieldStr == null) {
3463      return Character.MAX_VALUE; // return default value
3464    }
3465
3466    String[] fieldNames = fieldStr.split("\\.");
3467
3468    // Holds the intermediate (and final) result
3469    Object fieldObj = object;
3470
3471    for (int i = 0 ; i < fieldNames.length ; i++) {
3472
3473      String fieldName = fieldNames[i];
3474
3475      try {
3476        Field field =
3477          (fieldObj instanceof java.lang.Class<?>)
3478          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
3479          : fieldObj.getClass().getDeclaredField(fieldName);
3480        field.setAccessible(true);
3481        fieldObj = field.get(fieldObj);
3482
3483        if (fieldObj == null) {
3484          return Character.MAX_VALUE; // return default value
3485        }
3486
3487      } catch (Exception e) {
3488        return Character.MAX_VALUE; // return default value
3489
3490      }
3491
3492    }
3493
3494    return ((Character)fieldObj).charValue();
3495  }
3496
3497  ///////////////////////////////////////////////////////////////////////////
3498  /// Methods for "double" (from QuantBody.java.jpp)
3499  ///
3500
3501  /**
3502   * Returns the ith element of the array or collection argument. If the argument is null or not an
3503   * array or collection, returns a default value (Double.NaN).
3504   */
3505
3506  @Pure
3507  public static double getElement_double(Object o, long i) {
3508    if (o == null) {
3509      return Double.NaN; // return default value
3510    }
3511    java.lang.Class<?> c = o.getClass();
3512    if (c.isArray()) {
3513      return java.lang.reflect.Array.getDouble(o, (int)i);
3514    } else if (o instanceof java.util.AbstractCollection<?>) {
3515      return java.lang.reflect.Array.getDouble(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
3516    } else {
3517      return Double.NaN; // return default value
3518    }
3519  }
3520
3521  @Pure
3522  public static double getElement_double(double[] arr, long i) {
3523    if (arr == null) {
3524      return Double.NaN; // return default value
3525    }
3526    return arr[(int)i];
3527  }
3528
3529  private static boolean eq(double x, double y) {
3530    return fuzzy.eq(x,y);
3531  }
3532
3533  private static boolean ne(double x, double y) {
3534    return fuzzy.ne(x,y);
3535  }
3536
3537  private static boolean lt(double x, double y) {
3538    return fuzzy.lt(x,y);
3539  }
3540
3541  private static boolean lte(double x, double y) {
3542    return fuzzy.lte(x,y);
3543  }
3544
3545  private static boolean gt(double x, double y) {
3546    return fuzzy.gt(x,y);
3547  }
3548
3549  private static boolean gte(double x, double y) {
3550    return fuzzy.gte(x,y);
3551  }
3552
3553  /** True iff both sequences are non-null and have the same length. */
3554  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
3555  @Pure
3556  public static boolean sameLength(double @Nullable [] seq1, double @Nullable [] seq2) {
3557    return ((seq1 != null)
3558            && (seq2 != null)
3559            && seq1.length == seq2.length);
3560  }
3561
3562  /** True iff both sequences are non-null and have the same length. */
3563  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
3564  @Pure
3565  public static boolean sameLength(double @Nullable [] seq1, float @Nullable [] seq2) {
3566    return ((seq1 != null)
3567            && (seq2 != null)
3568            && seq1.length == seq2.length);
3569  }
3570
3571  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
3572   *
3573   * Meaning (in pseudo-FOL):
3574   *
3575   * <pre>
3576   * /\ seq1.length == seq2.length
3577   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
3578   * </pre>
3579   *
3580   */
3581  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3582  @Pure
3583  public static boolean pairwiseDivides(double[] seq1, double[] seq2) {
3584    if (!sameLength(seq1, seq2)) {
3585      return false;
3586    }
3587    assert seq1 != null && seq2 != null; // because sameLength() = true
3588    for (int i = 0 ; i < seq1.length ; i++) {
3589      if (ne(seq1[i] % seq2[i], 0)) {
3590        return false;
3591      }
3592    }
3593    return true;
3594  }
3595  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3596  @Pure
3597  public static boolean pairwiseDivides(double[] seq1, float[] seq2) {
3598    if (!sameLength(seq1, seq2)) {
3599      return false;
3600    }
3601    assert seq1 != null && seq2 != null; // because sameLength() = true
3602    for (int i = 0 ; i < seq1.length ; i++) {
3603      if (ne(seq1[i] % seq2[i], 0)) {
3604        return false;
3605      }
3606    }
3607    return true;
3608  }
3609
3610  /**
3611   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
3612   *
3613   * Meaning (in pseudo-FOL):
3614   *
3615   * <pre>
3616   * /\ seq1.length == seq2.length
3617   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
3618   * </pre>
3619   *
3620   */
3621  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3622  @Pure
3623  public static boolean pairwiseSquare(double[] seq1, double[] seq2) {
3624    if (!sameLength(seq1, seq2)) {
3625      return false;
3626    }
3627    assert seq1 != null && seq2 != null; // because sameLength() = true
3628    for (int i = 0 ; i < seq1.length ; i++) {
3629      if (ne(seq1[i], seq2[i] * seq2[i])) {
3630        return false;
3631      }
3632    }
3633    return true;
3634  }
3635  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3636  @Pure
3637  public static boolean pairwiseSquare(double[] seq1, float[] seq2) {
3638    if (!sameLength(seq1, seq2)) {
3639      return false;
3640    }
3641    assert seq1 != null && seq2 != null; // because sameLength() = true
3642    for (int i = 0 ; i < seq1.length ; i++) {
3643
3644      if (ne(seq1[i], ((double) seq2[i]) * ((double) seq2[i]))) {
3645
3646        return false;
3647      }
3648    }
3649    return true;
3650  }
3651
3652  /**
3653   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
3654   *
3655   * <p>If either array is null, returns null. If either array is empty, returns only those
3656   * elements in the other array. If both arrays are empty, returns a new empty array.
3657   */
3658  @SideEffectFree
3659  public static double @PolyNull [] concat(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3660    if (seq1 == null) {
3661      return null;
3662    }
3663    if (seq2 == null) {
3664      return null;
3665    }
3666    return ArraysPlume.concat(seq1, seq2);
3667  }
3668
3669  @SideEffectFree
3670  public static double @PolyNull [] concat(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3671    if (seq1 == null) {
3672      return null;
3673    }
3674    if (seq2 == null) {
3675      return null;
3676    }
3677    // Cannot just use ArraysPlume.concat because the two arrays
3678    // have different types.  This essentially inlines that method.
3679    int newLength = seq1.length + seq2.length;
3680    double[] retval = new double[newLength];
3681
3682    System.arraycopy(seq1, 0, retval, 0, seq1.length);
3683    for (int j = 0 ; j < seq2.length ; j++) {
3684      retval[seq1.length + j] = seq2[j];
3685    }
3686
3687    return retval;
3688  }
3689
3690  /**
3691   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
3692   * assurances about the order or repetition of elements: elements may be repeated, and their
3693   * order may be different from the order of elements in seq1 and seq2.
3694   */
3695  @SideEffectFree
3696  public static double @PolyNull [] union(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3697    if (seq1 == null) {
3698      return null;
3699    }
3700    if (seq2 == null) {
3701      return null;
3702    }
3703    return concat(seq1, seq2);
3704  }
3705
3706  @Pure
3707  public static double @PolyNull [] union(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3708    if (seq1 == null) {
3709      return null;
3710    }
3711    if (seq2 == null) {
3712      return null;
3713    }
3714    return concat(seq1, seq2);
3715  }
3716
3717  /**
3718   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
3719   * gives no assurances about the order or repetition of elements: elements may be repeated, and
3720   * their order may be different from the order of elements in seq1 and seq2.
3721   */
3722  @Pure
3723  public static double @PolyNull [] intersection(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3724    if (seq1 == null) {
3725      return null;
3726    }
3727    if (seq2 == null) {
3728      return null;
3729    }
3730    double[] intermediate = new double[Math.min(seq1.length, seq2.length)];
3731    int length = 0;
3732    for (int i = 0 ; i < seq1.length ; i++) {
3733      if (memberOf(seq1[i], seq2) ) {
3734        intermediate[length++] = seq1[i];
3735      }
3736    }
3737    return ArraysPlume.subarray(intermediate, 0, length);
3738  }
3739
3740  @Pure
3741  public static double @PolyNull [] intersection(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3742    if (seq1 == null) {
3743      return null;
3744    }
3745    if (seq2 == null) {
3746      return null;
3747    }
3748    double[] intermediate = new double[Math.min(seq1.length, seq2.length)];
3749    int length = 0;
3750    for (int i = 0 ; i < seq1.length ; i++) {
3751      if (memberOf(seq1[i], seq2) ) {
3752        intermediate[length++] = seq1[i];
3753      }
3754    }
3755    return ArraysPlume.subarray(intermediate, 0, length);
3756  }
3757
3758  /**
3759   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
3760   * no assurances about the order or repetition of elements: elements may be repeated, and their
3761   * order may be different from the order of elements in seq1 and seq2.
3762   */
3763  @Pure
3764  public static double @PolyNull [] setDiff(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3765    if (seq1 == null) {
3766      return null;
3767    }
3768    if (seq2 == null) {
3769      return null;
3770    }
3771    double[] intermediate = new double[seq1.length];
3772    int length = 0;
3773    for (int i = 0 ; i < seq1.length ; i++) {
3774      if (!memberOf(seq1[i], seq2)) {
3775        intermediate[length++] = seq1[i];
3776      }
3777    }
3778    return ArraysPlume.subarray(intermediate, 0, length);
3779  }
3780
3781  @Pure
3782  public static double @PolyNull [] setDiff(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3783    if (seq1 == null) {
3784      return null;
3785    }
3786    if (seq2 == null) {
3787      return null;
3788    }
3789    double[] intermediate = new double[seq1.length];
3790    int length = 0;
3791    for (int i = 0 ; i < seq1.length ; i++) {
3792      if (!memberOf(seq1[i], seq2)) {
3793        intermediate[length++] = seq1[i];
3794      }
3795    }
3796    return ArraysPlume.subarray(intermediate, 0, length);
3797  }
3798
3799  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
3800  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3801  @Pure
3802  public static boolean setEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
3803    if (seq1 == null) {
3804      return false;
3805    }
3806    if (seq2 == null) {
3807      return false;
3808    }
3809    for (int i = 0; i < seq1.length ; i++) {
3810      if (!memberOf(seq1[i], seq2) ) {
3811        return false;
3812      }
3813    }
3814    for (int i = 0; i < seq2.length ; i++) {
3815      if (!memberOf(seq2[i], seq1) ) {
3816        return false;
3817      }
3818    }
3819    return true;
3820  }
3821
3822  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3823  @Pure
3824  public static boolean setEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
3825    if (seq1 == null) {
3826      return false;
3827    }
3828    if (seq2 == null) {
3829      return false;
3830    }
3831    for (int i = 0; i < seq1.length ; i++) {
3832      if (!memberOf(seq1[i], seq2) ) {
3833        return false;
3834      }
3835    }
3836    for (int i = 0; i < seq2.length ; i++) {
3837      if (!memberOf(seq2[i], seq1) ) {
3838        return false;
3839      }
3840    }
3841    return true;
3842  }
3843
3844  /** True iff seq1 is the reverse of seq2.
3845   *
3846   * Meaning (in pseudo-FOL):
3847   *
3848   * <pre>
3849   * /\ seq1.length == seq2.length
3850   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
3851   * </pre>
3852   *
3853   */
3854  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3855  @Pure
3856  public static boolean isReverse(double[] seq1, double[] seq2) {
3857    if (!sameLength(seq1, seq2)) {
3858      return false;
3859    }
3860    assert seq1 != null && seq2 != null; // because sameLength() = true
3861    int length = seq1.length;
3862    for (int i = 0 ; i < length ; i++) {
3863      if (ne(seq1[i], seq2[length - i - 1])) {
3864        return false;
3865      }
3866    }
3867    return true;
3868  }
3869
3870  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3871  @Pure
3872  public static boolean isReverse(double @Nullable [] seq1, float @Nullable [] seq2) {
3873    if (!sameLength(seq1, seq2)) {
3874      return false;
3875    }
3876    assert seq1 != null && seq2 != null; // because sameLength() = true
3877    int length = seq1.length;
3878    for (int i = 0 ; i < length ; i++) {
3879      if (ne(seq1[i], seq2[length - i - 1])) {
3880        return false;
3881      }
3882    }
3883    return true;
3884  }
3885
3886  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
3887  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3888  @Pure
3889  public static boolean subsetOf(double @Nullable [] seq1, double @Nullable [] seq2) {
3890    if (seq1 == null) {
3891      return false;
3892    }
3893    if (seq2 == null) {
3894      return false;
3895    }
3896    for (int i = 0 ; i < seq1.length ; i++) {
3897      if (!memberOf(seq1[i], seq2)) {
3898        return false;
3899      }
3900    }
3901    return true;
3902  }
3903
3904  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3905  @Pure
3906  public static boolean subsetOf(double @Nullable [] seq1, float @Nullable [] seq2) {
3907    if (seq1 == null) {
3908      return false;
3909    }
3910    if (seq2 == null) {
3911      return false;
3912    }
3913    for (int i = 0 ; i < seq1.length ; i++) {
3914      if (!memberOf(seq1[i], seq2)) {
3915        return false;
3916      }
3917    }
3918    return true;
3919  }
3920
3921  /** Returns true iff seq contains no duplicate elements. */
3922  @EnsuresNonNullIf(result=true, expression="#1")
3923  @Pure
3924  public static boolean noDups(double @Nullable [] seq) {
3925    if (seq == null) {
3926      return false;
3927    }
3928    return ArraysPlume.noDuplicates(seq);
3929  }
3930
3931 /** Returns true iff elt is in array arr. */
3932  @EnsuresNonNullIf(result=true, expression="#2")
3933  @Pure
3934  public static boolean memberOf(double elt, double @Nullable [] arr) {
3935    if (arr == null) {
3936      return false;
3937    }
3938    for (int i = 0 ; i < arr.length ; i++) {
3939      if (eq(arr[i], elt)) {
3940        return true;
3941      }
3942    }
3943    return false;
3944  }
3945
3946  @EnsuresNonNullIf(result=true, expression="#2")
3947  @Pure
3948  public static boolean memberOf(double elt, float @Nullable [] arr) {
3949    if (arr == null) {
3950      return false;
3951    }
3952    for (int i = 0 ; i < arr.length ; i++) {
3953      if (eq(arr[i], elt)) {
3954        return true;
3955      }
3956    }
3957    return false;
3958  }
3959
3960  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
3961  @Pure
3962  public static double @PolyNull [] slice(double @PolyNull [] seq, int start, int end) {
3963    if (seq == null) {
3964      return null;
3965    }
3966    int sliceStart = start;
3967    int sliceEnd = end;
3968    if (start < 0) {
3969      return new double[] { };
3970    }
3971    if (end > seq.length - 1) {
3972      return new double[] { };
3973    }
3974    if (sliceStart > sliceEnd) {
3975      return new double[] { };
3976    }
3977    int length = sliceEnd - sliceStart + 1;
3978    return ArraysPlume.subarray(seq, sliceStart, length);
3979  }
3980
3981  @Pure
3982  public static double @PolyNull [] slice(double @PolyNull [] seq, long start, int end) {
3983    return slice(seq, (int)start, end);
3984  }
3985  @Pure
3986  public static double @PolyNull [] slice(double @PolyNull [] seq, int start, long end) {
3987    return slice(seq, start, (int)end);
3988  }
3989  @Pure
3990  public static double @PolyNull [] slice(double @PolyNull [] seq, long start, long end) {
3991    return slice(seq, (int)start, (int)end);
3992  }
3993
3994  /** True iff all elements in arr equal elt.
3995   *
3996   * Meaning (in pseudo-FOL):
3997   *
3998   * forall i in { 0..arr.length-1 } : arr[i] == elt
3999   *
4000   */
4001  @EnsuresNonNullIf(result=true, expression="#1")
4002  @Pure
4003  public static boolean eltsEqual(double @Nullable [] arr, double elt) {
4004    if (arr == null) {
4005      return false;
4006    }
4007    for (int i = 0 ; i < arr.length ; i++) {
4008      if (ne(arr[i], elt)) {
4009        return false;
4010      }
4011    }
4012    return true;
4013  }
4014
4015  @EnsuresNonNullIf(result=true, expression="#1")
4016  @Pure
4017  public static boolean eltsEqual(double @Nullable [] arr, float elt) {
4018    if (arr == null) {
4019      return false;
4020    }
4021    for (int i = 0 ; i < arr.length ; i++) {
4022      if (ne(arr[i], elt)) {
4023        return false;
4024      }
4025    }
4026    return true;
4027  }
4028
4029  /** True iff every element in arr does not equal elt.
4030   *
4031   * Meaning (in pseudo-FOL):
4032   *
4033   * forall i in { 0..arr.length-1 } : arr[i] != elt
4034   *
4035   */
4036  @EnsuresNonNullIf(result=true, expression="#1")
4037  @Pure
4038  public static boolean eltsNotEqual(double @Nullable [] arr, double elt) {
4039    if (arr == null) {
4040      return false;
4041    }
4042    for (int i = 0 ; i < arr.length ; i++) {
4043      if (eq(arr[i], elt)) {
4044        return false;
4045      }
4046    }
4047    return true;
4048  }
4049
4050  @EnsuresNonNullIf(result=true, expression="#1")
4051  @Pure
4052  public static boolean eltsNotEqual(double @Nullable [] arr, float elt) {
4053    if (arr == null) {
4054      return false;
4055    }
4056    for (int i = 0 ; i < arr.length ; i++) {
4057      if (eq(arr[i], elt)) {
4058        return false;
4059      }
4060    }
4061    return true;
4062  }
4063
4064  /** True iff every element in arr is greater than elt.
4065   *
4066   * Meaning (in pseudo-FOL):
4067   *
4068   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
4069   *
4070   */
4071  @EnsuresNonNullIf(result=true, expression="#1")
4072  @Pure
4073  public static boolean eltsGT(double @Nullable [] arr, double elt) {
4074    if (arr == null) {
4075      return false;
4076    }
4077    for (int i = 0 ; i < arr.length ; i++) {
4078      if (lte(arr[i], elt)) {
4079        return false;
4080      }
4081    }
4082    return true;
4083  }
4084
4085  @EnsuresNonNullIf(result=true, expression="#1")
4086  @Pure
4087  public static boolean eltsGT(double @Nullable [] arr, float elt) {
4088    if (arr == null) {
4089      return false;
4090    }
4091    for (int i = 0 ; i < arr.length ; i++) {
4092      if (lte(arr[i], elt)) {
4093        return false;
4094      }
4095    }
4096    return true;
4097  }
4098
4099  /** True iff every element in arr is greater than or equal to elt.
4100   *
4101   * Meaning (in pseudo-FOL):
4102   *
4103   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
4104   *
4105   */
4106  @EnsuresNonNullIf(result=true, expression="#1")
4107  @Pure
4108  public static boolean eltsGTE(double @Nullable [] arr, double elt) {
4109    if (arr == null) {
4110      return false;
4111    }
4112    for (int i = 0 ; i < arr.length ; i++) {
4113      if (lt(arr[i], elt)) {
4114        return false;
4115      }
4116    }
4117    return true;
4118  }
4119
4120  @EnsuresNonNullIf(result=true, expression="#1")
4121  @Pure
4122  public static boolean eltsGTE(double @Nullable [] arr, float elt) {
4123    if (arr == null) {
4124      return false;
4125    }
4126    for (int i = 0 ; i < arr.length ; i++) {
4127      if (lt(arr[i], elt)) {
4128        return false;
4129      }
4130    }
4131    return true;
4132  }
4133
4134  /** True iff every element in arr is less than elt.
4135   *
4136   * Meaning (in pseudo-FOL):
4137   *
4138   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
4139   *
4140   */
4141  @EnsuresNonNullIf(result=true, expression="#1")
4142  @Pure
4143  public static boolean eltsLT(double @Nullable [] arr, double elt) {
4144    if (arr == null) {
4145      return false;
4146    }
4147    for (int i = 0 ; i < arr.length ; i++) {
4148      if (gte(arr[i], elt)) {
4149        return false;
4150      }
4151    }
4152    return true;
4153  }
4154
4155  @EnsuresNonNullIf(result=true, expression="#1")
4156  @Pure
4157  public static boolean eltsLT(double @Nullable [] arr, float elt) {
4158    if (arr == null) {
4159      return false;
4160    }
4161    for (int i = 0 ; i < arr.length ; i++) {
4162      if (gte(arr[i], elt)) {
4163        return false;
4164      }
4165    }
4166    return true;
4167  }
4168
4169  /** True iff every element in arr is less than or equal to elt.
4170   *
4171   * Meaning (in pseudo-FOL):
4172   *
4173   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
4174   *
4175   */
4176  @EnsuresNonNullIf(result=true, expression="#1")
4177  @Pure
4178  public static boolean eltsLTE(double @Nullable [] arr, double elt) {
4179    if (arr == null) {
4180      return false;
4181    }
4182    for (int i = 0 ; i < arr.length ; i++) {
4183      if (gt(arr[i], elt)) {
4184        return false;
4185      }
4186    }
4187    return true;
4188  }
4189
4190  @EnsuresNonNullIf(result=true, expression="#1")
4191  @Pure
4192  public static boolean eltsLTE(double @Nullable [] arr, float elt) {
4193    if (arr == null) {
4194      return false;
4195    }
4196    for (int i = 0 ; i < arr.length ; i++) {
4197      if (gt(arr[i], elt)) {
4198        return false;
4199      }
4200    }
4201    return true;
4202  }
4203
4204  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
4205   *
4206   * Meaning (in pseudo-FOL):
4207   *
4208   * /\ seq1.length == se2.length
4209   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
4210   *
4211   */
4212
4213  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4214  @Pure
4215  public static boolean pairwiseEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4216    if (!sameLength(seq1, seq2)) {
4217      return false;
4218    }
4219    assert seq1 != null && seq2 != null; // because sameLength() = true
4220    for (int i = 0 ; i < seq1.length ; i++) {
4221      if (Double.isNaN(seq1[i]) && Double.isNaN(seq2[i])) {
4222        continue;
4223      }
4224      if (ne(seq1[i], seq2[i])) {
4225        return false;
4226      }
4227    }
4228    return true;
4229  }
4230
4231  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4232  @Pure
4233  public static boolean pairwiseEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4234    if (!sameLength(seq1, seq2)) {
4235      return false;
4236    }
4237    assert seq1 != null && seq2 != null; // because sameLength() = true
4238    for (int i = 0 ; i < seq1.length ; i++) {
4239      if (ne(seq1[i], seq2[i])) {
4240        return false;
4241      }
4242    }
4243    return true;
4244  }
4245
4246  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
4247   *
4248   * Meaning (in pseudo-FOL):
4249   *
4250   * /\ seq1.length == se2.length
4251   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
4252   *
4253   */
4254  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4255  @Pure
4256  public static boolean pairwiseNotEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4257    if (!sameLength(seq1, seq2)) {
4258      return false;
4259    }
4260    assert seq1 != null && seq2 != null; // because sameLength() = true
4261    for (int i = 0 ; i < seq1.length ; i++) {
4262      if (eq(seq1[i], seq2[i])) {
4263        return false;
4264      }
4265    }
4266    return true;
4267  }
4268
4269  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4270  @Pure
4271  public static boolean pairwiseNotEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4272    if (!sameLength(seq1, seq2)) {
4273      return false;
4274    }
4275    assert seq1 != null && seq2 != null; // because sameLength() = true
4276    for (int i = 0 ; i < seq1.length ; i++) {
4277      if (eq(seq1[i], seq2[i])) {
4278        return false;
4279      }
4280    }
4281    return true;
4282  }
4283
4284  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
4285   *
4286   * Meaning (in pseudo-FOL):
4287   *
4288   * /\ seq1.length == se2.length
4289   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
4290   *
4291   */
4292  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4293  @Pure
4294  public static boolean pairwiseLT(double @Nullable [] seq1, double @Nullable [] seq2) {
4295    if (!sameLength(seq1, seq2)) {
4296      return false;
4297    }
4298    assert seq1 != null && seq2 != null; // because sameLength() = true
4299    for (int i = 0 ; i < seq1.length ; i++) {
4300      if (gte(seq1[i], seq2[i])) {
4301        return false;
4302      }
4303    }
4304    return true;
4305  }
4306
4307  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4308  @Pure
4309  public static boolean pairwiseLT(double @Nullable [] seq1, float @Nullable [] seq2) {
4310    if (!sameLength(seq1, seq2)) {
4311      return false;
4312    }
4313    assert seq1 != null && seq2 != null; // because sameLength() = true
4314    for (int i = 0 ; i < seq1.length ; i++) {
4315      if (gte(seq1[i], seq2[i])) {
4316        return false;
4317      }
4318    }
4319    return true;
4320  }
4321
4322  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
4323   * Meaning (in pseudo-FOL):
4324   *
4325   * /\ seq1.length == se2.length
4326   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
4327   *
4328   */
4329  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4330  @Pure
4331  public static boolean pairwiseLTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4332    if (!sameLength(seq1, seq2)) {
4333      return false;
4334    }
4335    assert seq1 != null && seq2 != null; // because sameLength() = true
4336    for (int i = 0 ; i < seq1.length ; i++) {
4337      if (gt(seq1[i], seq2[i])) {
4338        return false;
4339      }
4340    }
4341    return true;
4342  }
4343
4344  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4345  @Pure
4346  public static boolean pairwiseLTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4347    if (!sameLength(seq1, seq2)) {
4348      return false;
4349    }
4350    assert seq1 != null && seq2 != null; // because sameLength() = true
4351    for (int i = 0 ; i < seq1.length ; i++) {
4352      if (gt(seq1[i], seq2[i])) {
4353        return false;
4354      }
4355    }
4356    return true;
4357  }
4358
4359  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
4360   * Meaning (in pseudo-FOL):
4361   *
4362   * /\ seq1.length == se2.length
4363   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
4364   *
4365   */
4366  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4367  @Pure
4368  public static boolean pairwiseGT(double @Nullable [] seq1, double @Nullable [] seq2) {
4369    if (!sameLength(seq1, seq2)) {
4370      return false;
4371    }
4372    assert seq1 != null && seq2 != null; // because sameLength() = true
4373    for (int i = 0 ; i < seq1.length ; i++) {
4374      if (lte(seq1[i], seq2[i])) {
4375        return false;
4376      }
4377    }
4378    return true;
4379  }
4380
4381  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4382  @Pure
4383  public static boolean pairwiseGT(double @Nullable [] seq1, float @Nullable [] seq2) {
4384    if (!sameLength(seq1, seq2)) {
4385      return false;
4386    }
4387    assert seq1 != null && seq2 != null; // because sameLength() = true
4388    for (int i = 0 ; i < seq1.length ; i++) {
4389      if (lte(seq1[i], seq2[i])) {
4390        return false;
4391      }
4392    }
4393    return true;
4394  }
4395
4396  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
4397   * Meaning (in pseudo-FOL):
4398   *
4399   * /\ seq1.length == se2.length
4400   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
4401   *
4402   */
4403  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4404  @Pure
4405  public static boolean pairwiseGTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4406    if (!sameLength(seq1, seq2)) {
4407      return false;
4408    }
4409    assert seq1 != null && seq2 != null; // because sameLength() = true
4410    for (int i = 0 ; i < seq1.length ; i++) {
4411      if (lt(seq1[i], seq2[i])) {
4412        return false;
4413      }
4414    }
4415    return true;
4416  }
4417
4418  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4419  @Pure
4420  public static boolean pairwiseGTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4421    if (!sameLength(seq1, seq2)) {
4422      return false;
4423    }
4424    assert seq1 != null && seq2 != null; // because sameLength() = true
4425    for (int i = 0 ; i < seq1.length ; i++) {
4426      if (lt(seq1[i], seq2[i])) {
4427        return false;
4428      }
4429    }
4430    return true;
4431  }
4432
4433  /**
4434   * Returns true iff seq1 is lexically equal to seq2.
4435   * For equality, "lexically" and "pairwise" are the same.
4436   */
4437  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4438  @Pure
4439  public static boolean lexEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4440    if (seq1 == null) {
4441      return false;
4442    }
4443    if (seq2 == null) {
4444      return false;
4445    }
4446    return pairwiseEqual(seq1, seq2);
4447  }
4448
4449  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4450  @Pure
4451  public static boolean lexEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4452    if (seq1 == null) {
4453      return false;
4454    }
4455    if (seq2 == null) {
4456      return false;
4457    }
4458    return pairwiseEqual(seq1, seq2);
4459  }
4460
4461  /** Returns true iff seq1 is lexically not equal to seq2. */
4462  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4463  @Pure
4464  public static boolean lexNotEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4465    if (seq1 == null) {
4466      return false;
4467    }
4468    if (seq2 == null) {
4469      return false;
4470    }
4471    return !lexEqual(seq1, seq2);
4472  }
4473
4474  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4475  @Pure
4476  public static boolean lexNotEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4477    if (seq1 == null) {
4478      return false;
4479    }
4480    if (seq2 == null) {
4481      return false;
4482    }
4483    return !lexEqual(seq1, seq2);
4484  }
4485
4486  /** Returns true iff seq1 is lexically &lt;  seq2. */
4487  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4488  @Pure
4489  public static boolean lexLT(double @Nullable [] seq1, double @Nullable [] seq2) {
4490    if (seq1 == null) {
4491      return false;
4492    }
4493    if (seq2 == null) {
4494      return false;
4495    }
4496    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4497    for (int i = 0 ; i < minlength ; i++) {
4498      if (gt(seq1[i], seq2[i])) {
4499        return false;
4500      } else if (lt(seq1[i], seq2[i])) {
4501        return true;
4502      }
4503    }
4504    if (seq1.length >= seq2.length) {
4505      return false;
4506    }
4507    return true;
4508  }
4509
4510  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4511  @Pure
4512  public static boolean lexLT(double @Nullable [] seq1, float @Nullable [] seq2) {
4513    if (seq1 == null) {
4514      return false;
4515    }
4516    if (seq2 == null) {
4517      return false;
4518    }
4519    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4520    for (int i = 0 ; i < minlength ; i++) {
4521      if (gt(seq1[i], seq2[i])) {
4522        return false;
4523        } else if (lt(seq1[i], seq2[i])) {
4524          return true;
4525        }
4526      }
4527      if (seq1.length >= seq2.length) {
4528        return false;
4529      }
4530      return true;
4531    }
4532
4533  /** Returns true iff seq1 is lexically &le; to seq2. */
4534  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4535  @Pure
4536  public static boolean lexLTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4537    if (seq1 == null) {
4538      return false;
4539    }
4540    if (seq2 == null) {
4541      return false;
4542    }
4543    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4544    for (int i = 0 ; i < minlength ; i++) {
4545      if (gt(seq1[i], seq2[i])) {
4546        return false;
4547      } else if (lt(seq1[i], seq2[i])) {
4548        return true;
4549      }
4550    }
4551    if (seq1.length > seq2.length) {
4552      return false;
4553    }
4554    return true;
4555  }
4556
4557  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4558  @Pure
4559  public static boolean lexLTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4560  if (seq1 == null) {
4561    return false;
4562  }
4563  if (seq2 == null) {
4564    return false;
4565  }
4566    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4567    for (int i = 0 ; i < minlength ; i++) {
4568      if (gt(seq1[i], seq2[i])) {
4569        return false;
4570      } else if (lt(seq1[i], seq2[i])) {
4571        return true;
4572      }
4573    }
4574    if (seq1.length > seq2.length) {
4575      return false;
4576    }
4577    return true;
4578  }
4579
4580  /** Returns true iff seq1 is lexically &gt; to seq2. */
4581  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4582  @Pure
4583  public static boolean lexGT(double @Nullable [] seq1, double @Nullable [] seq2) {
4584  if (seq1 == null) {
4585    return false;
4586  }
4587  if (seq2 == null) {
4588    return false;
4589  }
4590    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4591    for (int i = 0 ; i < minlength ; i++) {
4592      if (lt(seq1[i], seq2[i])) {
4593        return false;
4594      } else if (gt(seq1[i], seq2[i])) {
4595        return true;
4596      }
4597    }
4598    if (seq1.length <= seq2.length) {
4599      return false;
4600    }
4601    return true;
4602  }
4603
4604  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4605  @Pure
4606  public static boolean lexGT(double @Nullable [] seq1, float @Nullable [] seq2) {
4607  if (seq1 == null) {
4608    return false;
4609  }
4610  if (seq2 == null) {
4611    return false;
4612  }
4613    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4614    for (int i = 0 ; i < minlength ; i++) {
4615      if (lt(seq1[i], seq2[i])) {
4616        return false;
4617      } else if (gt(seq1[i], seq2[i])) {
4618        return true;
4619      }
4620    }
4621    if (seq1.length <= seq2.length) {
4622      return false;
4623    }
4624    return true;
4625  }
4626
4627  /** Returns true iff seq1 is lexically &ge; to seq2. */
4628  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4629  @Pure
4630  public static boolean lexGTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4631  if (seq1 == null) {
4632    return false;
4633  }
4634  if (seq2 == null) {
4635    return false;
4636  }
4637    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4638    for (int i = 0 ; i < minlength ; i++) {
4639      if (lt(seq1[i], seq2[i])) {
4640        return false;
4641      } else if (gt(seq1[i], seq2[i])) {
4642        return true;
4643      }
4644    }
4645    if (seq1.length < seq2.length) {
4646      return false;
4647    }
4648    return true;
4649  }
4650
4651  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4652  @Pure
4653  public static boolean lexGTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4654  if (seq1 == null) {
4655    return false;
4656  }
4657  if (seq2 == null) {
4658    return false;
4659  }
4660    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4661    for (int i = 0 ; i < minlength ; i++) {
4662      if (lt(seq1[i], seq2[i])) {
4663        return false;
4664      } else if (gt(seq1[i], seq2[i])) {
4665        return true;
4666      }
4667    }
4668    if (seq1.length < seq2.length) {
4669      return false;
4670    }
4671    return true;
4672  }
4673
4674  /** True iff for all applicable i, every seq[i] == seq[i+1].
4675   *
4676   * Meaning (in pseudo-FOL):
4677   *
4678   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
4679   *
4680   */
4681  @EnsuresNonNullIf(result=true, expression="#1")
4682  @Pure
4683  public static boolean eltwiseEqual(double @Nullable [] seq) {
4684  if (seq == null) {
4685    return false;
4686  }
4687    for (int i = 0 ; i < seq.length ; i++) {
4688      if (i < seq.length - 1) {
4689        if (ne(seq[i], seq[i + 1])) {
4690          return false;
4691        }
4692      }
4693    }
4694    return true;
4695  }
4696
4697  /** True iff for all applicable i, every seq[i] != seq[i+1].
4698   *
4699   * Meaning (in pseudo-FOL):
4700   *
4701   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
4702   *
4703   */
4704  @EnsuresNonNullIf(result=true, expression="#1")
4705  @Pure
4706  public static boolean eltwiseNotEqual(double @Nullable [] seq) {
4707  if (seq == null) {
4708    return false;
4709  }
4710    for (int i = 0 ; i < seq.length ; i++) {
4711      if (i < seq.length - 1) {
4712        if (eq(seq[i], seq[i + 1])) {
4713          return false;
4714        }
4715      }
4716    }
4717    return true;
4718  }
4719
4720  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
4721   *
4722   * Meaning (in pseudo-FOL):
4723   *
4724   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
4725   *
4726   */
4727  @EnsuresNonNullIf(result=true, expression="#1")
4728  @Pure
4729  public static boolean eltwiseLT(double @Nullable [] seq) {
4730  if (seq == null) {
4731    return false;
4732  }
4733    for (int i = 0 ; i < seq.length ; i++) {
4734      if (i < seq.length - 1) {
4735        if (gte(seq[i], seq[i + 1])) {
4736          return false;
4737        }
4738      }
4739    }
4740    return true;
4741  }
4742
4743  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
4744   *
4745   * Meaning (in pseudo-FOL):
4746   *
4747   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
4748   *
4749   */
4750  @EnsuresNonNullIf(result=true, expression="#1")
4751  @Pure
4752  public static boolean eltwiseLTE(double @Nullable [] seq) {
4753  if (seq == null) {
4754    return false;
4755  }
4756    for (int i = 0 ; i < seq.length ; i++) {
4757      if (i < seq.length - 1) {
4758        if (gt(seq[i], seq[i + 1])) {
4759          return false;
4760        }
4761      }
4762    }
4763    return true;
4764  }
4765
4766  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
4767   *
4768   * Meaning (in pseudo-FOL):
4769   *
4770   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
4771   *
4772   */
4773  @EnsuresNonNullIf(result=true, expression="#1")
4774  @Pure
4775  public static boolean eltwiseGT(double @Nullable [] seq) {
4776  if (seq == null) {
4777    return false;
4778  }
4779    for (int i = 0 ; i < seq.length ; i++) {
4780      if (i < seq.length - 1) {
4781        if (lte(seq[i], seq[i + 1])) {
4782          return false;
4783        }
4784      }
4785    }
4786    return true;
4787  }
4788
4789  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
4790   *
4791   * Meaning (in pseudo-FOL):
4792   *
4793   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
4794   *
4795   */
4796  @EnsuresNonNullIf(result=true, expression="#1")
4797  @Pure
4798  public static boolean eltwiseGTE(double @Nullable [] seq) {
4799  if (seq == null) {
4800    return false;
4801  }
4802    for (int i = 0 ; i < seq.length ; i++) {
4803      if (i < seq.length - 1) {
4804        if (lt(seq[i], seq[i + 1])) {
4805          return false;
4806        }
4807      }
4808    }
4809    return true;
4810  }
4811
4812  /** True iff for all applicable i, every seq[i] == i.
4813   *
4814   * Meaning (in pseudo-FOL):
4815   *
4816   * forall i in { 0..seq.length-1 } : seq[i] == i
4817   *
4818   */
4819  @EnsuresNonNullIf(result=true, expression="#1")
4820  @Pure
4821  public static boolean eltsEqualIndex(double @Nullable [] seq) {
4822  if (seq == null) {
4823    return false;
4824  }
4825    for (int i = 0 ; i < seq.length ; i++) {
4826      if (ne(seq[i], i)) {
4827        return false;
4828      }
4829    }
4830    return true;
4831  }
4832
4833  /** True iff for all applicable i, every seq[i] != i.
4834   *
4835   * Meaning (in pseudo-FOL):
4836   *
4837   * forall i in { 0..seq.length-1 } : seq[i] != i
4838   *
4839   */
4840  @EnsuresNonNullIf(result=true, expression="#1")
4841  @Pure
4842  public static boolean eltsNotEqualIndex(double @Nullable [] seq) {
4843  if (seq == null) {
4844    return false;
4845  }
4846    for (int i = 0 ; i < seq.length ; i++) {
4847      if (eq(seq[i], i)) {
4848        return false;
4849      }
4850    }
4851    return true;
4852  }
4853
4854  /** True iff for all applicable i, every seq[i] &lt; i.
4855   *
4856   * Meaning (in pseudo-FOL):
4857   *
4858   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
4859   *
4860   */
4861  @EnsuresNonNullIf(result=true, expression="#1")
4862  @Pure
4863  public static boolean eltsLtIndex(double @Nullable [] seq) {
4864  if (seq == null) {
4865    return false;
4866  }
4867    for (int i = 0 ; i < seq.length ; i++) {
4868      if (gte(seq[i], i)) {
4869        return false;
4870      }
4871    }
4872    return true;
4873  }
4874
4875  /** True iff for all applicable i, every seq[i] &le; i.
4876   *
4877   * Meaning (in pseudo-FOL):
4878   *
4879   * forall i in { 0..seq.length-1 } : seq[i] &le; i
4880   *
4881   */
4882  @EnsuresNonNullIf(result=true, expression="#1")
4883  @Pure
4884  public static boolean eltsLteIndex(double @Nullable [] seq) {
4885  if (seq == null) {
4886    return false;
4887  }
4888    for (int i = 0 ; i < seq.length ; i++) {
4889      if (gt(seq[i], i)) {
4890        return false;
4891      }
4892    }
4893    return true;
4894  }
4895
4896  /** True iff for all applicable i, every seq[i] &gt; i.
4897   *
4898   * Meaning (in pseudo-FOL):
4899   *
4900   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
4901   *
4902   */
4903  @EnsuresNonNullIf(result=true, expression="#1")
4904  @Pure
4905  public static boolean eltsGtIndex(double @Nullable [] seq) {
4906  if (seq == null) {
4907    return false;
4908  }
4909    for (int i = 0 ; i < seq.length ; i++) {
4910      if (lte(seq[i], i)) {
4911        return false;
4912      }
4913    }
4914    return true;
4915  }
4916
4917  /** True iff for all applicable i, every seq[i] &ge; i.
4918   *
4919   * Meaning (in pseudo-FOL):
4920   *
4921   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
4922   *
4923   */
4924  @EnsuresNonNullIf(result=true, expression="#1")
4925  @Pure
4926  public static boolean eltsGteIndex(double @Nullable [] seq) {
4927  if (seq == null) {
4928    return false;
4929  }
4930    for (int i = 0 ; i < seq.length ; i++) {
4931      if (lt(seq[i], i)) {
4932        return false;
4933      }
4934    }
4935    return true;
4936  }
4937
4938  /// Deferencing (accessing) fields
4939
4940  /**
4941   * collectdouble accepts an object and a list of fields (one of which is of array type, and the
4942   * rest of which are not), and produces an array in which the original object has had the given
4943   * fields accessed.
4944   *
4945   * <p>Daikon creates invariants over "variables" such as the following.
4946   *
4947   * <dl>
4948   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
4949   *              for all y's in array x.arr.</dd>
4950   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
4951   *              for all x's in array arr.</dd>
4952   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
4953   * </dl>
4954   *
4955   * <p>The collectdouble() method does this collecting work.
4956   *
4957   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
4958   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
4959   * elements that result from following the fields, one of which is assumed to be an array.
4960   *
4961   * <p>
4962   * requires: fieldStr.length() &gt; 0 and object != null
4963   * <p>
4964   * requires: fieldStr contains only field names, no "[]" strings.
4965   * <p>
4966   * requires: the method only works for field sequences with exactly one field representing an
4967   * array. For example, the collection a[].b[].c will fail.
4968   *
4969   * @return if the resulting collection is of non-primitive type, then returns an array of type
4970   * Object[]. Returns null if any array or field access causes an exception.
4971   */
4972
4973  @SideEffectFree
4974  public static double @Nullable [] collectdouble(@Nullable Object object, @Nullable String fieldStr) {
4975
4976    if (object == null) {
4977      return null;
4978    }
4979    if (fieldStr == null) {
4980      return null;
4981    }
4982
4983    // assert fieldStr != null && !"".equals(fieldStr);
4984    String[] fieldNames = fieldStr.split("\\.");
4985    double[] retval = collectdouble(object, fieldNames, 0);
4986    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
4987    return retval;
4988  }
4989
4990  /** Helper method for collectdouble(Object, String).
4991   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
4992   * @see collectdouble(Object, String)
4993   */
4994  // @PolyNull does not work for return type, because null is returned on error.
4995  @SideEffectFree
4996  private static double @Nullable [] collectdouble(@Nullable Object object,
4997                                                   String[] fields, int fieldsStartIdx) {
4998
4999    if (object == null) {
5000      return null;
5001    }
5002    assert (fields != null);
5003    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
5004
5005    Object fieldObj;
5006    try {
5007      Field field = (object instanceof java.lang.Class<?>)
5008        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
5009        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
5010      field.setAccessible(true);
5011      // Class cls = field.getType();
5012      fieldObj = field.get(object);
5013      // System.out.println("***fieldObj="+fieldObj);
5014
5015    } catch (Exception e) {
5016      return null;
5017
5018    }
5019
5020    if (fieldObj == null) {
5021      return null;
5022    }
5023
5024    // base case: just accessed the last field
5025    if (fields.length - 1 == fieldsStartIdx) {
5026
5027      if (fieldObj.getClass().isArray()) {
5028        // last field is an array
5029        return (double[])fieldObj;
5030      } else {
5031        // This hack should be removed in favor of, at "oneEltArray = ..."
5032        // below, calling a version of collectdouble_field that throws an
5033        // error.  Then, this case becomes a run-time error.  -MDE
5034
5035        // Just one element; return a one-element array.
5036        // assert cls.equals(Double.TYPE);
5037        return new double[] { ((Double)fieldObj).doubleValue() };
5038      }
5039    } else {
5040      // recursive case: more fields to access after this one
5041
5042      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
5043
5044        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
5045        double[] intermediate = new double[collection.size()];
5046        int index = 0;
5047        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
5048          Object obj = i.next();
5049          double[] oneEltArray = collectdouble(obj, fields, fieldsStartIdx + 1);
5050          if (oneEltArray == null) {
5051            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
5052          }
5053          // assert oneEltArray.length == 1;
5054          intermediate[index++] = oneEltArray[0];
5055        }
5056        return intermediate;
5057      } else if (fieldObj.getClass().isArray()) {
5058
5059        // collect elements across array
5060        double[] intermediate = new double[Array.getLength(fieldObj)];
5061        for (int i = 0 ; i < intermediate.length ; i++) {
5062          Object obj = Array.get(fieldObj, i);
5063          double[] oneEltArray = collectdouble(obj, fields, fieldsStartIdx + 1);
5064          if (oneEltArray == null) {
5065            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
5066          }
5067          // assert oneEltArray.length == 1;
5068          intermediate[i] = oneEltArray[0];
5069        }
5070        return intermediate;
5071      } else {
5072
5073        return collectdouble(fieldObj, fields, fieldsStartIdx + 1);
5074      }
5075    }
5076  }
5077
5078  /**
5079   * Returns the results of dereferencing the fields for 'object'. For example, the call
5080   *
5081   * <pre>collectdouble_field(x, "f.g.h")</pre>
5082   *
5083   * has the same value as
5084   *
5085   * <pre>x.f.g.h</pre>.
5086   * Returns a default value if any field access causes an exception.
5087   */
5088  @SideEffectFree
5089  public static double collectdouble_field(Object object, String fieldStr) {
5090
5091    if (object == null) {
5092      return Double.NaN; // return default value
5093    }
5094    if (fieldStr == null) {
5095      return Double.NaN; // return default value
5096    }
5097
5098    String[] fieldNames = fieldStr.split("\\.");
5099
5100    // Holds the intermediate (and final) result
5101    Object fieldObj = object;
5102
5103    for (int i = 0 ; i < fieldNames.length ; i++) {
5104
5105      String fieldName = fieldNames[i];
5106
5107      try {
5108        Field field =
5109          (fieldObj instanceof java.lang.Class<?>)
5110          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
5111          : fieldObj.getClass().getDeclaredField(fieldName);
5112        field.setAccessible(true);
5113        fieldObj = field.get(fieldObj);
5114
5115        if (fieldObj == null) {
5116          return Double.NaN; // return default value
5117        }
5118
5119      } catch (Exception e) {
5120        return Double.NaN; // return default value
5121
5122      }
5123
5124    }
5125
5126    return ((Double)fieldObj).doubleValue();
5127  }
5128
5129  ///////////////////////////////////////////////////////////////////////////
5130  /// Methods for "float" (from QuantBody.java.jpp)
5131  ///
5132
5133  /**
5134   * Returns the ith element of the array or collection argument. If the argument is null or not an
5135   * array or collection, returns a default value (Float.NaN).
5136   */
5137
5138  @Pure
5139  public static float getElement_float(Object o, long i) {
5140    if (o == null) {
5141      return Float.NaN; // return default value
5142    }
5143    java.lang.Class<?> c = o.getClass();
5144    if (c.isArray()) {
5145      return java.lang.reflect.Array.getFloat(o, (int)i);
5146    } else if (o instanceof java.util.AbstractCollection<?>) {
5147      return java.lang.reflect.Array.getFloat(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
5148    } else {
5149      return Float.NaN; // return default value
5150    }
5151  }
5152
5153  @Pure
5154  public static float getElement_float(float[] arr, long i) {
5155    if (arr == null) {
5156      return Float.NaN; // return default value
5157    }
5158    return arr[(int)i];
5159  }
5160
5161  private static boolean eq(float x, float y) {
5162    return fuzzy.eq(x,y);
5163  }
5164
5165  private static boolean ne(float x, float y) {
5166    return fuzzy.ne(x,y);
5167  }
5168
5169  private static boolean lt(float x, float y) {
5170    return fuzzy.lt(x,y);
5171  }
5172
5173  private static boolean lte(float x, float y) {
5174    return fuzzy.lte(x,y);
5175  }
5176
5177  private static boolean gt(float x, float y) {
5178    return fuzzy.gt(x,y);
5179  }
5180
5181  private static boolean gte(float x, float y) {
5182    return fuzzy.gte(x,y);
5183  }
5184
5185  /** True iff both sequences are non-null and have the same length. */
5186  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
5187  @Pure
5188  public static boolean sameLength(float @Nullable [] seq1, float @Nullable [] seq2) {
5189    return ((seq1 != null)
5190            && (seq2 != null)
5191            && seq1.length == seq2.length);
5192  }
5193
5194  /** True iff both sequences are non-null and have the same length. */
5195  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
5196  @Pure
5197  public static boolean sameLength(float @Nullable [] seq1, double @Nullable [] seq2) {
5198    return ((seq1 != null)
5199            && (seq2 != null)
5200            && seq1.length == seq2.length);
5201  }
5202
5203  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
5204   *
5205   * Meaning (in pseudo-FOL):
5206   *
5207   * <pre>
5208   * /\ seq1.length == seq2.length
5209   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
5210   * </pre>
5211   *
5212   */
5213  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5214  @Pure
5215  public static boolean pairwiseDivides(float[] seq1, float[] seq2) {
5216    if (!sameLength(seq1, seq2)) {
5217      return false;
5218    }
5219    assert seq1 != null && seq2 != null; // because sameLength() = true
5220    for (int i = 0 ; i < seq1.length ; i++) {
5221      if (ne(seq1[i] % seq2[i], 0)) {
5222        return false;
5223      }
5224    }
5225    return true;
5226  }
5227  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5228  @Pure
5229  public static boolean pairwiseDivides(float[] seq1, double[] seq2) {
5230    if (!sameLength(seq1, seq2)) {
5231      return false;
5232    }
5233    assert seq1 != null && seq2 != null; // because sameLength() = true
5234    for (int i = 0 ; i < seq1.length ; i++) {
5235      if (ne(seq1[i] % seq2[i], 0)) {
5236        return false;
5237      }
5238    }
5239    return true;
5240  }
5241
5242  /**
5243   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
5244   *
5245   * Meaning (in pseudo-FOL):
5246   *
5247   * <pre>
5248   * /\ seq1.length == seq2.length
5249   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
5250   * </pre>
5251   *
5252   */
5253  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5254  @Pure
5255  public static boolean pairwiseSquare(float[] seq1, float[] seq2) {
5256    if (!sameLength(seq1, seq2)) {
5257      return false;
5258    }
5259    assert seq1 != null && seq2 != null; // because sameLength() = true
5260    for (int i = 0 ; i < seq1.length ; i++) {
5261      if (ne(seq1[i], seq2[i] * seq2[i])) {
5262        return false;
5263      }
5264    }
5265    return true;
5266  }
5267  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5268  @Pure
5269  public static boolean pairwiseSquare(float[] seq1, double[] seq2) {
5270    if (!sameLength(seq1, seq2)) {
5271      return false;
5272    }
5273    assert seq1 != null && seq2 != null; // because sameLength() = true
5274    for (int i = 0 ; i < seq1.length ; i++) {
5275
5276      if (ne(seq1[i], seq2[i] * seq2[i])) {
5277
5278        return false;
5279      }
5280    }
5281    return true;
5282  }
5283
5284  /**
5285   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
5286   *
5287   * <p>If either array is null, returns null. If either array is empty, returns only those
5288   * elements in the other array. If both arrays are empty, returns a new empty array.
5289   */
5290  @SideEffectFree
5291  public static float @PolyNull [] concat(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5292    if (seq1 == null) {
5293      return null;
5294    }
5295    if (seq2 == null) {
5296      return null;
5297    }
5298    return ArraysPlume.concat(seq1, seq2);
5299  }
5300
5301  @SideEffectFree
5302  public static double @PolyNull [] concat(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5303    if (seq1 == null) {
5304      return null;
5305    }
5306    if (seq2 == null) {
5307      return null;
5308    }
5309    // Cannot just use ArraysPlume.concat because the two arrays
5310    // have different types.  This essentially inlines that method.
5311    int newLength = seq1.length + seq2.length;
5312    double[] retval = new double[newLength];
5313
5314    for (int j = 0 ; j < seq1.length ; j++) {
5315      retval[j] = seq1[j];
5316    }
5317    System.arraycopy(seq2, 0, retval, seq1.length, seq2.length);
5318
5319    return retval;
5320  }
5321
5322  /**
5323   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
5324   * assurances about the order or repetition of elements: elements may be repeated, and their
5325   * order may be different from the order of elements in seq1 and seq2.
5326   */
5327  @SideEffectFree
5328  public static float @PolyNull [] union(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5329    if (seq1 == null) {
5330      return null;
5331    }
5332    if (seq2 == null) {
5333      return null;
5334    }
5335    return concat(seq1, seq2);
5336  }
5337
5338  @Pure
5339  public static double @PolyNull [] union(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5340    if (seq1 == null) {
5341      return null;
5342    }
5343    if (seq2 == null) {
5344      return null;
5345    }
5346    return concat(seq1, seq2);
5347  }
5348
5349  /**
5350   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
5351   * gives no assurances about the order or repetition of elements: elements may be repeated, and
5352   * their order may be different from the order of elements in seq1 and seq2.
5353   */
5354  @Pure
5355  public static float @PolyNull [] intersection(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5356    if (seq1 == null) {
5357      return null;
5358    }
5359    if (seq2 == null) {
5360      return null;
5361    }
5362    float[] intermediate = new float[Math.min(seq1.length, seq2.length)];
5363    int length = 0;
5364    for (int i = 0 ; i < seq1.length ; i++) {
5365      if (memberOf(seq1[i], seq2) ) {
5366        intermediate[length++] = seq1[i];
5367      }
5368    }
5369    return ArraysPlume.subarray(intermediate, 0, length);
5370  }
5371
5372  @Pure
5373  public static double @PolyNull [] intersection(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5374    if (seq1 == null) {
5375      return null;
5376    }
5377    if (seq2 == null) {
5378      return null;
5379    }
5380    double[] intermediate = new double[Math.min(seq1.length, seq2.length)];
5381    int length = 0;
5382    for (int i = 0 ; i < seq1.length ; i++) {
5383      if (memberOf(seq1[i], seq2) ) {
5384        intermediate[length++] = seq1[i];
5385      }
5386    }
5387    return ArraysPlume.subarray(intermediate, 0, length);
5388  }
5389
5390  /**
5391   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
5392   * no assurances about the order or repetition of elements: elements may be repeated, and their
5393   * order may be different from the order of elements in seq1 and seq2.
5394   */
5395  @Pure
5396  public static float @PolyNull [] setDiff(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5397    if (seq1 == null) {
5398      return null;
5399    }
5400    if (seq2 == null) {
5401      return null;
5402    }
5403    float[] intermediate = new float[seq1.length];
5404    int length = 0;
5405    for (int i = 0 ; i < seq1.length ; i++) {
5406      if (!memberOf(seq1[i], seq2)) {
5407        intermediate[length++] = seq1[i];
5408      }
5409    }
5410    return ArraysPlume.subarray(intermediate, 0, length);
5411  }
5412
5413  @Pure
5414  public static double @PolyNull [] setDiff(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5415    if (seq1 == null) {
5416      return null;
5417    }
5418    if (seq2 == null) {
5419      return null;
5420    }
5421    double[] intermediate = new double[seq1.length];
5422    int length = 0;
5423    for (int i = 0 ; i < seq1.length ; i++) {
5424      if (!memberOf(seq1[i], seq2)) {
5425        intermediate[length++] = seq1[i];
5426      }
5427    }
5428    return ArraysPlume.subarray(intermediate, 0, length);
5429  }
5430
5431  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
5432  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5433  @Pure
5434  public static boolean setEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
5435    if (seq1 == null) {
5436      return false;
5437    }
5438    if (seq2 == null) {
5439      return false;
5440    }
5441    for (int i = 0; i < seq1.length ; i++) {
5442      if (!memberOf(seq1[i], seq2) ) {
5443        return false;
5444      }
5445    }
5446    for (int i = 0; i < seq2.length ; i++) {
5447      if (!memberOf(seq2[i], seq1) ) {
5448        return false;
5449      }
5450    }
5451    return true;
5452  }
5453
5454  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5455  @Pure
5456  public static boolean setEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
5457    if (seq1 == null) {
5458      return false;
5459    }
5460    if (seq2 == null) {
5461      return false;
5462    }
5463    for (int i = 0; i < seq1.length ; i++) {
5464      if (!memberOf(seq1[i], seq2) ) {
5465        return false;
5466      }
5467    }
5468    for (int i = 0; i < seq2.length ; i++) {
5469      if (!memberOf(seq2[i], seq1) ) {
5470        return false;
5471      }
5472    }
5473    return true;
5474  }
5475
5476  /** True iff seq1 is the reverse of seq2.
5477   *
5478   * Meaning (in pseudo-FOL):
5479   *
5480   * <pre>
5481   * /\ seq1.length == seq2.length
5482   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
5483   * </pre>
5484   *
5485   */
5486  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5487  @Pure
5488  public static boolean isReverse(float[] seq1, float[] seq2) {
5489    if (!sameLength(seq1, seq2)) {
5490      return false;
5491    }
5492    assert seq1 != null && seq2 != null; // because sameLength() = true
5493    int length = seq1.length;
5494    for (int i = 0 ; i < length ; i++) {
5495      if (ne(seq1[i], seq2[length - i - 1])) {
5496        return false;
5497      }
5498    }
5499    return true;
5500  }
5501
5502  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5503  @Pure
5504  public static boolean isReverse(float @Nullable [] seq1, double @Nullable [] seq2) {
5505    if (!sameLength(seq1, seq2)) {
5506      return false;
5507    }
5508    assert seq1 != null && seq2 != null; // because sameLength() = true
5509    int length = seq1.length;
5510    for (int i = 0 ; i < length ; i++) {
5511      if (ne(seq1[i], seq2[length - i - 1])) {
5512        return false;
5513      }
5514    }
5515    return true;
5516  }
5517
5518  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
5519  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5520  @Pure
5521  public static boolean subsetOf(float @Nullable [] seq1, float @Nullable [] seq2) {
5522    if (seq1 == null) {
5523      return false;
5524    }
5525    if (seq2 == null) {
5526      return false;
5527    }
5528    for (int i = 0 ; i < seq1.length ; i++) {
5529      if (!memberOf(seq1[i], seq2)) {
5530        return false;
5531      }
5532    }
5533    return true;
5534  }
5535
5536  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5537  @Pure
5538  public static boolean subsetOf(float @Nullable [] seq1, double @Nullable [] seq2) {
5539    if (seq1 == null) {
5540      return false;
5541    }
5542    if (seq2 == null) {
5543      return false;
5544    }
5545    for (int i = 0 ; i < seq1.length ; i++) {
5546      if (!memberOf(seq1[i], seq2)) {
5547        return false;
5548      }
5549    }
5550    return true;
5551  }
5552
5553  /** Returns true iff seq contains no duplicate elements. */
5554  @EnsuresNonNullIf(result=true, expression="#1")
5555  @Pure
5556  public static boolean noDups(float @Nullable [] seq) {
5557    if (seq == null) {
5558      return false;
5559    }
5560    return ArraysPlume.noDuplicates(seq);
5561  }
5562
5563 /** Returns true iff elt is in array arr. */
5564  @EnsuresNonNullIf(result=true, expression="#2")
5565  @Pure
5566  public static boolean memberOf(float elt, float @Nullable [] arr) {
5567    if (arr == null) {
5568      return false;
5569    }
5570    for (int i = 0 ; i < arr.length ; i++) {
5571      if (eq(arr[i], elt)) {
5572        return true;
5573      }
5574    }
5575    return false;
5576  }
5577
5578  @EnsuresNonNullIf(result=true, expression="#2")
5579  @Pure
5580  public static boolean memberOf(float elt, double @Nullable [] arr) {
5581    if (arr == null) {
5582      return false;
5583    }
5584    for (int i = 0 ; i < arr.length ; i++) {
5585      if (eq(arr[i], elt)) {
5586        return true;
5587      }
5588    }
5589    return false;
5590  }
5591
5592  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
5593  @Pure
5594  public static float @PolyNull [] slice(float @PolyNull [] seq, int start, int end) {
5595    if (seq == null) {
5596      return null;
5597    }
5598    int sliceStart = start;
5599    int sliceEnd = end;
5600    if (start < 0) {
5601      return new float[] { };
5602    }
5603    if (end > seq.length - 1) {
5604      return new float[] { };
5605    }
5606    if (sliceStart > sliceEnd) {
5607      return new float[] { };
5608    }
5609    int length = sliceEnd - sliceStart + 1;
5610    return ArraysPlume.subarray(seq, sliceStart, length);
5611  }
5612
5613  @Pure
5614  public static float @PolyNull [] slice(float @PolyNull [] seq, long start, int end) {
5615    return slice(seq, (int)start, end);
5616  }
5617  @Pure
5618  public static float @PolyNull [] slice(float @PolyNull [] seq, int start, long end) {
5619    return slice(seq, start, (int)end);
5620  }
5621  @Pure
5622  public static float @PolyNull [] slice(float @PolyNull [] seq, long start, long end) {
5623    return slice(seq, (int)start, (int)end);
5624  }
5625
5626  /** True iff all elements in arr equal elt.
5627   *
5628   * Meaning (in pseudo-FOL):
5629   *
5630   * forall i in { 0..arr.length-1 } : arr[i] == elt
5631   *
5632   */
5633  @EnsuresNonNullIf(result=true, expression="#1")
5634  @Pure
5635  public static boolean eltsEqual(float @Nullable [] arr, float elt) {
5636    if (arr == null) {
5637      return false;
5638    }
5639    for (int i = 0 ; i < arr.length ; i++) {
5640      if (ne(arr[i], elt)) {
5641        return false;
5642      }
5643    }
5644    return true;
5645  }
5646
5647  @EnsuresNonNullIf(result=true, expression="#1")
5648  @Pure
5649  public static boolean eltsEqual(float @Nullable [] arr, double elt) {
5650    if (arr == null) {
5651      return false;
5652    }
5653    for (int i = 0 ; i < arr.length ; i++) {
5654      if (ne(arr[i], elt)) {
5655        return false;
5656      }
5657    }
5658    return true;
5659  }
5660
5661  /** True iff every element in arr does not equal elt.
5662   *
5663   * Meaning (in pseudo-FOL):
5664   *
5665   * forall i in { 0..arr.length-1 } : arr[i] != elt
5666   *
5667   */
5668  @EnsuresNonNullIf(result=true, expression="#1")
5669  @Pure
5670  public static boolean eltsNotEqual(float @Nullable [] arr, float elt) {
5671    if (arr == null) {
5672      return false;
5673    }
5674    for (int i = 0 ; i < arr.length ; i++) {
5675      if (eq(arr[i], elt)) {
5676        return false;
5677      }
5678    }
5679    return true;
5680  }
5681
5682  @EnsuresNonNullIf(result=true, expression="#1")
5683  @Pure
5684  public static boolean eltsNotEqual(float @Nullable [] arr, double elt) {
5685    if (arr == null) {
5686      return false;
5687    }
5688    for (int i = 0 ; i < arr.length ; i++) {
5689      if (eq(arr[i], elt)) {
5690        return false;
5691      }
5692    }
5693    return true;
5694  }
5695
5696  /** True iff every element in arr is greater than elt.
5697   *
5698   * Meaning (in pseudo-FOL):
5699   *
5700   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
5701   *
5702   */
5703  @EnsuresNonNullIf(result=true, expression="#1")
5704  @Pure
5705  public static boolean eltsGT(float @Nullable [] arr, float elt) {
5706    if (arr == null) {
5707      return false;
5708    }
5709    for (int i = 0 ; i < arr.length ; i++) {
5710      if (lte(arr[i], elt)) {
5711        return false;
5712      }
5713    }
5714    return true;
5715  }
5716
5717  @EnsuresNonNullIf(result=true, expression="#1")
5718  @Pure
5719  public static boolean eltsGT(float @Nullable [] arr, double elt) {
5720    if (arr == null) {
5721      return false;
5722    }
5723    for (int i = 0 ; i < arr.length ; i++) {
5724      if (lte(arr[i], elt)) {
5725        return false;
5726      }
5727    }
5728    return true;
5729  }
5730
5731  /** True iff every element in arr is greater than or equal to elt.
5732   *
5733   * Meaning (in pseudo-FOL):
5734   *
5735   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
5736   *
5737   */
5738  @EnsuresNonNullIf(result=true, expression="#1")
5739  @Pure
5740  public static boolean eltsGTE(float @Nullable [] arr, float elt) {
5741    if (arr == null) {
5742      return false;
5743    }
5744    for (int i = 0 ; i < arr.length ; i++) {
5745      if (lt(arr[i], elt)) {
5746        return false;
5747      }
5748    }
5749    return true;
5750  }
5751
5752  @EnsuresNonNullIf(result=true, expression="#1")
5753  @Pure
5754  public static boolean eltsGTE(float @Nullable [] arr, double elt) {
5755    if (arr == null) {
5756      return false;
5757    }
5758    for (int i = 0 ; i < arr.length ; i++) {
5759      if (lt(arr[i], elt)) {
5760        return false;
5761      }
5762    }
5763    return true;
5764  }
5765
5766  /** True iff every element in arr is less than elt.
5767   *
5768   * Meaning (in pseudo-FOL):
5769   *
5770   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
5771   *
5772   */
5773  @EnsuresNonNullIf(result=true, expression="#1")
5774  @Pure
5775  public static boolean eltsLT(float @Nullable [] arr, float elt) {
5776    if (arr == null) {
5777      return false;
5778    }
5779    for (int i = 0 ; i < arr.length ; i++) {
5780      if (gte(arr[i], elt)) {
5781        return false;
5782      }
5783    }
5784    return true;
5785  }
5786
5787  @EnsuresNonNullIf(result=true, expression="#1")
5788  @Pure
5789  public static boolean eltsLT(float @Nullable [] arr, double elt) {
5790    if (arr == null) {
5791      return false;
5792    }
5793    for (int i = 0 ; i < arr.length ; i++) {
5794      if (gte(arr[i], elt)) {
5795        return false;
5796      }
5797    }
5798    return true;
5799  }
5800
5801  /** True iff every element in arr is less than or equal to elt.
5802   *
5803   * Meaning (in pseudo-FOL):
5804   *
5805   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
5806   *
5807   */
5808  @EnsuresNonNullIf(result=true, expression="#1")
5809  @Pure
5810  public static boolean eltsLTE(float @Nullable [] arr, float elt) {
5811    if (arr == null) {
5812      return false;
5813    }
5814    for (int i = 0 ; i < arr.length ; i++) {
5815      if (gt(arr[i], elt)) {
5816        return false;
5817      }
5818    }
5819    return true;
5820  }
5821
5822  @EnsuresNonNullIf(result=true, expression="#1")
5823  @Pure
5824  public static boolean eltsLTE(float @Nullable [] arr, double elt) {
5825    if (arr == null) {
5826      return false;
5827    }
5828    for (int i = 0 ; i < arr.length ; i++) {
5829      if (gt(arr[i], elt)) {
5830        return false;
5831      }
5832    }
5833    return true;
5834  }
5835
5836  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
5837   *
5838   * Meaning (in pseudo-FOL):
5839   *
5840   * /\ seq1.length == se2.length
5841   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
5842   *
5843   */
5844
5845  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5846  @Pure
5847  public static boolean pairwiseEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
5848    if (!sameLength(seq1, seq2)) {
5849      return false;
5850    }
5851    assert seq1 != null && seq2 != null; // because sameLength() = true
5852    for (int i = 0 ; i < seq1.length ; i++) {
5853      if (Float.isNaN(seq1[i]) && Float.isNaN(seq2[i])) {
5854        continue;
5855      }
5856      if (ne(seq1[i], seq2[i])) {
5857        return false;
5858      }
5859    }
5860    return true;
5861  }
5862
5863  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5864  @Pure
5865  public static boolean pairwiseEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
5866    if (!sameLength(seq1, seq2)) {
5867      return false;
5868    }
5869    assert seq1 != null && seq2 != null; // because sameLength() = true
5870    for (int i = 0 ; i < seq1.length ; i++) {
5871      if (ne(seq1[i], seq2[i])) {
5872        return false;
5873      }
5874    }
5875    return true;
5876  }
5877
5878  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
5879   *
5880   * Meaning (in pseudo-FOL):
5881   *
5882   * /\ seq1.length == se2.length
5883   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
5884   *
5885   */
5886  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5887  @Pure
5888  public static boolean pairwiseNotEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
5889    if (!sameLength(seq1, seq2)) {
5890      return false;
5891    }
5892    assert seq1 != null && seq2 != null; // because sameLength() = true
5893    for (int i = 0 ; i < seq1.length ; i++) {
5894      if (eq(seq1[i], seq2[i])) {
5895        return false;
5896      }
5897    }
5898    return true;
5899  }
5900
5901  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5902  @Pure
5903  public static boolean pairwiseNotEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
5904    if (!sameLength(seq1, seq2)) {
5905      return false;
5906    }
5907    assert seq1 != null && seq2 != null; // because sameLength() = true
5908    for (int i = 0 ; i < seq1.length ; i++) {
5909      if (eq(seq1[i], seq2[i])) {
5910        return false;
5911      }
5912    }
5913    return true;
5914  }
5915
5916  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
5917   *
5918   * Meaning (in pseudo-FOL):
5919   *
5920   * /\ seq1.length == se2.length
5921   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
5922   *
5923   */
5924  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5925  @Pure
5926  public static boolean pairwiseLT(float @Nullable [] seq1, float @Nullable [] seq2) {
5927    if (!sameLength(seq1, seq2)) {
5928      return false;
5929    }
5930    assert seq1 != null && seq2 != null; // because sameLength() = true
5931    for (int i = 0 ; i < seq1.length ; i++) {
5932      if (gte(seq1[i], seq2[i])) {
5933        return false;
5934      }
5935    }
5936    return true;
5937  }
5938
5939  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5940  @Pure
5941  public static boolean pairwiseLT(float @Nullable [] seq1, double @Nullable [] seq2) {
5942    if (!sameLength(seq1, seq2)) {
5943      return false;
5944    }
5945    assert seq1 != null && seq2 != null; // because sameLength() = true
5946    for (int i = 0 ; i < seq1.length ; i++) {
5947      if (gte(seq1[i], seq2[i])) {
5948        return false;
5949      }
5950    }
5951    return true;
5952  }
5953
5954  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
5955   * Meaning (in pseudo-FOL):
5956   *
5957   * /\ seq1.length == se2.length
5958   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
5959   *
5960   */
5961  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5962  @Pure
5963  public static boolean pairwiseLTE(float @Nullable [] seq1, float @Nullable [] seq2) {
5964    if (!sameLength(seq1, seq2)) {
5965      return false;
5966    }
5967    assert seq1 != null && seq2 != null; // because sameLength() = true
5968    for (int i = 0 ; i < seq1.length ; i++) {
5969      if (gt(seq1[i], seq2[i])) {
5970        return false;
5971      }
5972    }
5973    return true;
5974  }
5975
5976  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5977  @Pure
5978  public static boolean pairwiseLTE(float @Nullable [] seq1, double @Nullable [] seq2) {
5979    if (!sameLength(seq1, seq2)) {
5980      return false;
5981    }
5982    assert seq1 != null && seq2 != null; // because sameLength() = true
5983    for (int i = 0 ; i < seq1.length ; i++) {
5984      if (gt(seq1[i], seq2[i])) {
5985        return false;
5986      }
5987    }
5988    return true;
5989  }
5990
5991  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
5992   * Meaning (in pseudo-FOL):
5993   *
5994   * /\ seq1.length == se2.length
5995   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
5996   *
5997   */
5998  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5999  @Pure
6000  public static boolean pairwiseGT(float @Nullable [] seq1, float @Nullable [] seq2) {
6001    if (!sameLength(seq1, seq2)) {
6002      return false;
6003    }
6004    assert seq1 != null && seq2 != null; // because sameLength() = true
6005    for (int i = 0 ; i < seq1.length ; i++) {
6006      if (lte(seq1[i], seq2[i])) {
6007        return false;
6008      }
6009    }
6010    return true;
6011  }
6012
6013  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6014  @Pure
6015  public static boolean pairwiseGT(float @Nullable [] seq1, double @Nullable [] seq2) {
6016    if (!sameLength(seq1, seq2)) {
6017      return false;
6018    }
6019    assert seq1 != null && seq2 != null; // because sameLength() = true
6020    for (int i = 0 ; i < seq1.length ; i++) {
6021      if (lte(seq1[i], seq2[i])) {
6022        return false;
6023      }
6024    }
6025    return true;
6026  }
6027
6028  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
6029   * Meaning (in pseudo-FOL):
6030   *
6031   * /\ seq1.length == se2.length
6032   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
6033   *
6034   */
6035  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6036  @Pure
6037  public static boolean pairwiseGTE(float @Nullable [] seq1, float @Nullable [] seq2) {
6038    if (!sameLength(seq1, seq2)) {
6039      return false;
6040    }
6041    assert seq1 != null && seq2 != null; // because sameLength() = true
6042    for (int i = 0 ; i < seq1.length ; i++) {
6043      if (lt(seq1[i], seq2[i])) {
6044        return false;
6045      }
6046    }
6047    return true;
6048  }
6049
6050  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6051  @Pure
6052  public static boolean pairwiseGTE(float @Nullable [] seq1, double @Nullable [] seq2) {
6053    if (!sameLength(seq1, seq2)) {
6054      return false;
6055    }
6056    assert seq1 != null && seq2 != null; // because sameLength() = true
6057    for (int i = 0 ; i < seq1.length ; i++) {
6058      if (lt(seq1[i], seq2[i])) {
6059        return false;
6060      }
6061    }
6062    return true;
6063  }
6064
6065  /**
6066   * Returns true iff seq1 is lexically equal to seq2.
6067   * For equality, "lexically" and "pairwise" are the same.
6068   */
6069  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6070  @Pure
6071  public static boolean lexEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
6072    if (seq1 == null) {
6073      return false;
6074    }
6075    if (seq2 == null) {
6076      return false;
6077    }
6078    return pairwiseEqual(seq1, seq2);
6079  }
6080
6081  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6082  @Pure
6083  public static boolean lexEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
6084    if (seq1 == null) {
6085      return false;
6086    }
6087    if (seq2 == null) {
6088      return false;
6089    }
6090    return pairwiseEqual(seq1, seq2);
6091  }
6092
6093  /** Returns true iff seq1 is lexically not equal to seq2. */
6094  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6095  @Pure
6096  public static boolean lexNotEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
6097    if (seq1 == null) {
6098      return false;
6099    }
6100    if (seq2 == null) {
6101      return false;
6102    }
6103    return !lexEqual(seq1, seq2);
6104  }
6105
6106  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6107  @Pure
6108  public static boolean lexNotEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
6109    if (seq1 == null) {
6110      return false;
6111    }
6112    if (seq2 == null) {
6113      return false;
6114    }
6115    return !lexEqual(seq1, seq2);
6116  }
6117
6118  /** Returns true iff seq1 is lexically &lt;  seq2. */
6119  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6120  @Pure
6121  public static boolean lexLT(float @Nullable [] seq1, float @Nullable [] seq2) {
6122    if (seq1 == null) {
6123      return false;
6124    }
6125    if (seq2 == null) {
6126      return false;
6127    }
6128    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6129    for (int i = 0 ; i < minlength ; i++) {
6130      if (gt(seq1[i], seq2[i])) {
6131        return false;
6132      } else if (lt(seq1[i], seq2[i])) {
6133        return true;
6134      }
6135    }
6136    if (seq1.length >= seq2.length) {
6137      return false;
6138    }
6139    return true;
6140  }
6141
6142  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6143  @Pure
6144  public static boolean lexLT(float @Nullable [] seq1, double @Nullable [] seq2) {
6145    if (seq1 == null) {
6146      return false;
6147    }
6148    if (seq2 == null) {
6149      return false;
6150    }
6151    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6152    for (int i = 0 ; i < minlength ; i++) {
6153      if (gt(seq1[i], seq2[i])) {
6154        return false;
6155        } else if (lt(seq1[i], seq2[i])) {
6156          return true;
6157        }
6158      }
6159      if (seq1.length >= seq2.length) {
6160        return false;
6161      }
6162      return true;
6163    }
6164
6165  /** Returns true iff seq1 is lexically &le; to seq2. */
6166  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6167  @Pure
6168  public static boolean lexLTE(float @Nullable [] seq1, float @Nullable [] seq2) {
6169    if (seq1 == null) {
6170      return false;
6171    }
6172    if (seq2 == null) {
6173      return false;
6174    }
6175    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6176    for (int i = 0 ; i < minlength ; i++) {
6177      if (gt(seq1[i], seq2[i])) {
6178        return false;
6179      } else if (lt(seq1[i], seq2[i])) {
6180        return true;
6181      }
6182    }
6183    if (seq1.length > seq2.length) {
6184      return false;
6185    }
6186    return true;
6187  }
6188
6189  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6190  @Pure
6191  public static boolean lexLTE(float @Nullable [] seq1, double @Nullable [] seq2) {
6192  if (seq1 == null) {
6193    return false;
6194  }
6195  if (seq2 == null) {
6196    return false;
6197  }
6198    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6199    for (int i = 0 ; i < minlength ; i++) {
6200      if (gt(seq1[i], seq2[i])) {
6201        return false;
6202      } else if (lt(seq1[i], seq2[i])) {
6203        return true;
6204      }
6205    }
6206    if (seq1.length > seq2.length) {
6207      return false;
6208    }
6209    return true;
6210  }
6211
6212  /** Returns true iff seq1 is lexically &gt; to seq2. */
6213  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6214  @Pure
6215  public static boolean lexGT(float @Nullable [] seq1, float @Nullable [] seq2) {
6216  if (seq1 == null) {
6217    return false;
6218  }
6219  if (seq2 == null) {
6220    return false;
6221  }
6222    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6223    for (int i = 0 ; i < minlength ; i++) {
6224      if (lt(seq1[i], seq2[i])) {
6225        return false;
6226      } else if (gt(seq1[i], seq2[i])) {
6227        return true;
6228      }
6229    }
6230    if (seq1.length <= seq2.length) {
6231      return false;
6232    }
6233    return true;
6234  }
6235
6236  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6237  @Pure
6238  public static boolean lexGT(float @Nullable [] seq1, double @Nullable [] seq2) {
6239  if (seq1 == null) {
6240    return false;
6241  }
6242  if (seq2 == null) {
6243    return false;
6244  }
6245    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6246    for (int i = 0 ; i < minlength ; i++) {
6247      if (lt(seq1[i], seq2[i])) {
6248        return false;
6249      } else if (gt(seq1[i], seq2[i])) {
6250        return true;
6251      }
6252    }
6253    if (seq1.length <= seq2.length) {
6254      return false;
6255    }
6256    return true;
6257  }
6258
6259  /** Returns true iff seq1 is lexically &ge; to seq2. */
6260  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6261  @Pure
6262  public static boolean lexGTE(float @Nullable [] seq1, float @Nullable [] seq2) {
6263  if (seq1 == null) {
6264    return false;
6265  }
6266  if (seq2 == null) {
6267    return false;
6268  }
6269    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6270    for (int i = 0 ; i < minlength ; i++) {
6271      if (lt(seq1[i], seq2[i])) {
6272        return false;
6273      } else if (gt(seq1[i], seq2[i])) {
6274        return true;
6275      }
6276    }
6277    if (seq1.length < seq2.length) {
6278      return false;
6279    }
6280    return true;
6281  }
6282
6283  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6284  @Pure
6285  public static boolean lexGTE(float @Nullable [] seq1, double @Nullable [] seq2) {
6286  if (seq1 == null) {
6287    return false;
6288  }
6289  if (seq2 == null) {
6290    return false;
6291  }
6292    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6293    for (int i = 0 ; i < minlength ; i++) {
6294      if (lt(seq1[i], seq2[i])) {
6295        return false;
6296      } else if (gt(seq1[i], seq2[i])) {
6297        return true;
6298      }
6299    }
6300    if (seq1.length < seq2.length) {
6301      return false;
6302    }
6303    return true;
6304  }
6305
6306  /** True iff for all applicable i, every seq[i] == seq[i+1].
6307   *
6308   * Meaning (in pseudo-FOL):
6309   *
6310   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
6311   *
6312   */
6313  @EnsuresNonNullIf(result=true, expression="#1")
6314  @Pure
6315  public static boolean eltwiseEqual(float @Nullable [] seq) {
6316  if (seq == null) {
6317    return false;
6318  }
6319    for (int i = 0 ; i < seq.length ; i++) {
6320      if (i < seq.length - 1) {
6321        if (ne(seq[i], seq[i + 1])) {
6322          return false;
6323        }
6324      }
6325    }
6326    return true;
6327  }
6328
6329  /** True iff for all applicable i, every seq[i] != seq[i+1].
6330   *
6331   * Meaning (in pseudo-FOL):
6332   *
6333   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
6334   *
6335   */
6336  @EnsuresNonNullIf(result=true, expression="#1")
6337  @Pure
6338  public static boolean eltwiseNotEqual(float @Nullable [] seq) {
6339  if (seq == null) {
6340    return false;
6341  }
6342    for (int i = 0 ; i < seq.length ; i++) {
6343      if (i < seq.length - 1) {
6344        if (eq(seq[i], seq[i + 1])) {
6345          return false;
6346        }
6347      }
6348    }
6349    return true;
6350  }
6351
6352  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
6353   *
6354   * Meaning (in pseudo-FOL):
6355   *
6356   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
6357   *
6358   */
6359  @EnsuresNonNullIf(result=true, expression="#1")
6360  @Pure
6361  public static boolean eltwiseLT(float @Nullable [] seq) {
6362  if (seq == null) {
6363    return false;
6364  }
6365    for (int i = 0 ; i < seq.length ; i++) {
6366      if (i < seq.length - 1) {
6367        if (gte(seq[i], seq[i + 1])) {
6368          return false;
6369        }
6370      }
6371    }
6372    return true;
6373  }
6374
6375  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
6376   *
6377   * Meaning (in pseudo-FOL):
6378   *
6379   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
6380   *
6381   */
6382  @EnsuresNonNullIf(result=true, expression="#1")
6383  @Pure
6384  public static boolean eltwiseLTE(float @Nullable [] seq) {
6385  if (seq == null) {
6386    return false;
6387  }
6388    for (int i = 0 ; i < seq.length ; i++) {
6389      if (i < seq.length - 1) {
6390        if (gt(seq[i], seq[i + 1])) {
6391          return false;
6392        }
6393      }
6394    }
6395    return true;
6396  }
6397
6398  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
6399   *
6400   * Meaning (in pseudo-FOL):
6401   *
6402   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
6403   *
6404   */
6405  @EnsuresNonNullIf(result=true, expression="#1")
6406  @Pure
6407  public static boolean eltwiseGT(float @Nullable [] seq) {
6408  if (seq == null) {
6409    return false;
6410  }
6411    for (int i = 0 ; i < seq.length ; i++) {
6412      if (i < seq.length - 1) {
6413        if (lte(seq[i], seq[i + 1])) {
6414          return false;
6415        }
6416      }
6417    }
6418    return true;
6419  }
6420
6421  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
6422   *
6423   * Meaning (in pseudo-FOL):
6424   *
6425   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
6426   *
6427   */
6428  @EnsuresNonNullIf(result=true, expression="#1")
6429  @Pure
6430  public static boolean eltwiseGTE(float @Nullable [] seq) {
6431  if (seq == null) {
6432    return false;
6433  }
6434    for (int i = 0 ; i < seq.length ; i++) {
6435      if (i < seq.length - 1) {
6436        if (lt(seq[i], seq[i + 1])) {
6437          return false;
6438        }
6439      }
6440    }
6441    return true;
6442  }
6443
6444  /** True iff for all applicable i, every seq[i] == i.
6445   *
6446   * Meaning (in pseudo-FOL):
6447   *
6448   * forall i in { 0..seq.length-1 } : seq[i] == i
6449   *
6450   */
6451  @EnsuresNonNullIf(result=true, expression="#1")
6452  @Pure
6453  public static boolean eltsEqualIndex(float @Nullable [] seq) {
6454  if (seq == null) {
6455    return false;
6456  }
6457    for (int i = 0 ; i < seq.length ; i++) {
6458      if (ne(seq[i], i)) {
6459        return false;
6460      }
6461    }
6462    return true;
6463  }
6464
6465  /** True iff for all applicable i, every seq[i] != i.
6466   *
6467   * Meaning (in pseudo-FOL):
6468   *
6469   * forall i in { 0..seq.length-1 } : seq[i] != i
6470   *
6471   */
6472  @EnsuresNonNullIf(result=true, expression="#1")
6473  @Pure
6474  public static boolean eltsNotEqualIndex(float @Nullable [] seq) {
6475  if (seq == null) {
6476    return false;
6477  }
6478    for (int i = 0 ; i < seq.length ; i++) {
6479      if (eq(seq[i], i)) {
6480        return false;
6481      }
6482    }
6483    return true;
6484  }
6485
6486  /** True iff for all applicable i, every seq[i] &lt; i.
6487   *
6488   * Meaning (in pseudo-FOL):
6489   *
6490   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
6491   *
6492   */
6493  @EnsuresNonNullIf(result=true, expression="#1")
6494  @Pure
6495  public static boolean eltsLtIndex(float @Nullable [] seq) {
6496  if (seq == null) {
6497    return false;
6498  }
6499    for (int i = 0 ; i < seq.length ; i++) {
6500      if (gte(seq[i], i)) {
6501        return false;
6502      }
6503    }
6504    return true;
6505  }
6506
6507  /** True iff for all applicable i, every seq[i] &le; i.
6508   *
6509   * Meaning (in pseudo-FOL):
6510   *
6511   * forall i in { 0..seq.length-1 } : seq[i] &le; i
6512   *
6513   */
6514  @EnsuresNonNullIf(result=true, expression="#1")
6515  @Pure
6516  public static boolean eltsLteIndex(float @Nullable [] seq) {
6517  if (seq == null) {
6518    return false;
6519  }
6520    for (int i = 0 ; i < seq.length ; i++) {
6521      if (gt(seq[i], i)) {
6522        return false;
6523      }
6524    }
6525    return true;
6526  }
6527
6528  /** True iff for all applicable i, every seq[i] &gt; i.
6529   *
6530   * Meaning (in pseudo-FOL):
6531   *
6532   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
6533   *
6534   */
6535  @EnsuresNonNullIf(result=true, expression="#1")
6536  @Pure
6537  public static boolean eltsGtIndex(float @Nullable [] seq) {
6538  if (seq == null) {
6539    return false;
6540  }
6541    for (int i = 0 ; i < seq.length ; i++) {
6542      if (lte(seq[i], i)) {
6543        return false;
6544      }
6545    }
6546    return true;
6547  }
6548
6549  /** True iff for all applicable i, every seq[i] &ge; i.
6550   *
6551   * Meaning (in pseudo-FOL):
6552   *
6553   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
6554   *
6555   */
6556  @EnsuresNonNullIf(result=true, expression="#1")
6557  @Pure
6558  public static boolean eltsGteIndex(float @Nullable [] seq) {
6559  if (seq == null) {
6560    return false;
6561  }
6562    for (int i = 0 ; i < seq.length ; i++) {
6563      if (lt(seq[i], i)) {
6564        return false;
6565      }
6566    }
6567    return true;
6568  }
6569
6570  /// Deferencing (accessing) fields
6571
6572  /**
6573   * collectfloat accepts an object and a list of fields (one of which is of array type, and the
6574   * rest of which are not), and produces an array in which the original object has had the given
6575   * fields accessed.
6576   *
6577   * <p>Daikon creates invariants over "variables" such as the following.
6578   *
6579   * <dl>
6580   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
6581   *              for all y's in array x.arr.</dd>
6582   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
6583   *              for all x's in array arr.</dd>
6584   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
6585   * </dl>
6586   *
6587   * <p>The collectfloat() method does this collecting work.
6588   *
6589   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
6590   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
6591   * elements that result from following the fields, one of which is assumed to be an array.
6592   *
6593   * <p>
6594   * requires: fieldStr.length() &gt; 0 and object != null
6595   * <p>
6596   * requires: fieldStr contains only field names, no "[]" strings.
6597   * <p>
6598   * requires: the method only works for field sequences with exactly one field representing an
6599   * array. For example, the collection a[].b[].c will fail.
6600   *
6601   * @return if the resulting collection is of non-primitive type, then returns an array of type
6602   * Object[]. Returns null if any array or field access causes an exception.
6603   */
6604
6605  @SideEffectFree
6606  public static float @Nullable [] collectfloat(@Nullable Object object, @Nullable String fieldStr) {
6607
6608    if (object == null) {
6609      return null;
6610    }
6611    if (fieldStr == null) {
6612      return null;
6613    }
6614
6615    // assert fieldStr != null && !"".equals(fieldStr);
6616    String[] fieldNames = fieldStr.split("\\.");
6617    float[] retval = collectfloat(object, fieldNames, 0);
6618    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
6619    return retval;
6620  }
6621
6622  /** Helper method for collectfloat(Object, String).
6623   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
6624   * @see collectfloat(Object, String)
6625   */
6626  // @PolyNull does not work for return type, because null is returned on error.
6627  @SideEffectFree
6628  private static float @Nullable [] collectfloat(@Nullable Object object,
6629                                                   String[] fields, int fieldsStartIdx) {
6630
6631    if (object == null) {
6632      return null;
6633    }
6634    assert (fields != null);
6635    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
6636
6637    Object fieldObj;
6638    try {
6639      Field field = (object instanceof java.lang.Class<?>)
6640        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
6641        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
6642      field.setAccessible(true);
6643      // Class cls = field.getType();
6644      fieldObj = field.get(object);
6645      // System.out.println("***fieldObj="+fieldObj);
6646
6647    } catch (Exception e) {
6648      return null;
6649
6650    }
6651
6652    if (fieldObj == null) {
6653      return null;
6654    }
6655
6656    // base case: just accessed the last field
6657    if (fields.length - 1 == fieldsStartIdx) {
6658
6659      if (fieldObj.getClass().isArray()) {
6660        // last field is an array
6661        return (float[])fieldObj;
6662      } else {
6663        // This hack should be removed in favor of, at "oneEltArray = ..."
6664        // below, calling a version of collectfloat_field that throws an
6665        // error.  Then, this case becomes a run-time error.  -MDE
6666
6667        // Just one element; return a one-element array.
6668        // assert cls.equals(Float.TYPE);
6669        return new float[] { ((Float)fieldObj).floatValue() };
6670      }
6671    } else {
6672      // recursive case: more fields to access after this one
6673
6674      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
6675
6676        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
6677        float[] intermediate = new float[collection.size()];
6678        int index = 0;
6679        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
6680          Object obj = i.next();
6681          float[] oneEltArray = collectfloat(obj, fields, fieldsStartIdx + 1);
6682          if (oneEltArray == null) {
6683            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
6684          }
6685          // assert oneEltArray.length == 1;
6686          intermediate[index++] = oneEltArray[0];
6687        }
6688        return intermediate;
6689      } else if (fieldObj.getClass().isArray()) {
6690
6691        // collect elements across array
6692        float[] intermediate = new float[Array.getLength(fieldObj)];
6693        for (int i = 0 ; i < intermediate.length ; i++) {
6694          Object obj = Array.get(fieldObj, i);
6695          float[] oneEltArray = collectfloat(obj, fields, fieldsStartIdx + 1);
6696          if (oneEltArray == null) {
6697            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
6698          }
6699          // assert oneEltArray.length == 1;
6700          intermediate[i] = oneEltArray[0];
6701        }
6702        return intermediate;
6703      } else {
6704
6705        return collectfloat(fieldObj, fields, fieldsStartIdx + 1);
6706      }
6707    }
6708  }
6709
6710  /**
6711   * Returns the results of dereferencing the fields for 'object'. For example, the call
6712   *
6713   * <pre>collectfloat_field(x, "f.g.h")</pre>
6714   *
6715   * has the same value as
6716   *
6717   * <pre>x.f.g.h</pre>.
6718   * Returns a default value if any field access causes an exception.
6719   */
6720  @SideEffectFree
6721  public static float collectfloat_field(Object object, String fieldStr) {
6722
6723    if (object == null) {
6724      return Float.NaN; // return default value
6725    }
6726    if (fieldStr == null) {
6727      return Float.NaN; // return default value
6728    }
6729
6730    String[] fieldNames = fieldStr.split("\\.");
6731
6732    // Holds the intermediate (and final) result
6733    Object fieldObj = object;
6734
6735    for (int i = 0 ; i < fieldNames.length ; i++) {
6736
6737      String fieldName = fieldNames[i];
6738
6739      try {
6740        Field field =
6741          (fieldObj instanceof java.lang.Class<?>)
6742          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
6743          : fieldObj.getClass().getDeclaredField(fieldName);
6744        field.setAccessible(true);
6745        fieldObj = field.get(fieldObj);
6746
6747        if (fieldObj == null) {
6748          return Float.NaN; // return default value
6749        }
6750
6751      } catch (Exception e) {
6752        return Float.NaN; // return default value
6753
6754      }
6755
6756    }
6757
6758    return ((Float)fieldObj).floatValue();
6759  }
6760
6761  ///////////////////////////////////////////////////////////////////////////
6762  /// Methods for "int" (from QuantBody.java.jpp)
6763  ///
6764
6765  /**
6766   * Returns the ith element of the array or collection argument. If the argument is null or not an
6767   * array or collection, returns a default value (Integer.MAX_VALUE).
6768   */
6769
6770  @Pure
6771  public static int getElement_int(Object o, long i) {
6772    if (o == null) {
6773      return Integer.MAX_VALUE; // return default value
6774    }
6775    java.lang.Class<?> c = o.getClass();
6776    if (c.isArray()) {
6777      return java.lang.reflect.Array.getInt(o, (int)i);
6778    } else if (o instanceof java.util.AbstractCollection<?>) {
6779      return java.lang.reflect.Array.getInt(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
6780    } else {
6781      return Integer.MAX_VALUE; // return default value
6782    }
6783  }
6784
6785  @Pure
6786  public static int getElement_int(int[] arr, long i) {
6787    if (arr == null) {
6788      return Integer.MAX_VALUE; // return default value
6789    }
6790    return arr[(int)i];
6791  }
6792
6793  private static boolean eq(int x, int y) {
6794    return x == y;
6795  }
6796
6797  private static boolean ne(int x, int y) {
6798    return x != y;
6799  }
6800
6801  private static boolean lt(int x, int y) {
6802    return x < y;
6803  }
6804
6805  private static boolean lte(int x, int y) {
6806    return x <= y;
6807  }
6808
6809  private static boolean gt(int x, int y) {
6810    return x > y;
6811  }
6812
6813  private static boolean gte(int x, int y) {
6814    return x >= y;
6815  }
6816
6817  /** True iff both sequences are non-null and have the same length. */
6818  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
6819  @Pure
6820  public static boolean sameLength(int @Nullable [] seq1, int @Nullable [] seq2) {
6821    return ((seq1 != null)
6822            && (seq2 != null)
6823            && seq1.length == seq2.length);
6824  }
6825
6826  /** True iff both sequences are non-null and have the same length. */
6827  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
6828  @Pure
6829  public static boolean sameLength(int @Nullable [] seq1, long @Nullable [] seq2) {
6830    return ((seq1 != null)
6831            && (seq2 != null)
6832            && seq1.length == seq2.length);
6833  }
6834
6835  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
6836   *
6837   * Meaning (in pseudo-FOL):
6838   *
6839   * <pre>
6840   * /\ seq1.length == seq2.length
6841   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
6842   * </pre>
6843   *
6844   */
6845  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6846  @Pure
6847  public static boolean pairwiseDivides(int[] seq1, int[] seq2) {
6848    if (!sameLength(seq1, seq2)) {
6849      return false;
6850    }
6851    assert seq1 != null && seq2 != null; // because sameLength() = true
6852    for (int i = 0 ; i < seq1.length ; i++) {
6853      if (ne(seq1[i] % seq2[i], 0)) {
6854        return false;
6855      }
6856    }
6857    return true;
6858  }
6859  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6860  @Pure
6861  public static boolean pairwiseDivides(int[] seq1, long[] seq2) {
6862    if (!sameLength(seq1, seq2)) {
6863      return false;
6864    }
6865    assert seq1 != null && seq2 != null; // because sameLength() = true
6866    for (int i = 0 ; i < seq1.length ; i++) {
6867      if (ne(seq1[i] % seq2[i], 0)) {
6868        return false;
6869      }
6870    }
6871    return true;
6872  }
6873
6874  /**
6875   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
6876   *
6877   * Meaning (in pseudo-FOL):
6878   *
6879   * <pre>
6880   * /\ seq1.length == seq2.length
6881   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
6882   * </pre>
6883   *
6884   */
6885  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6886  @Pure
6887  public static boolean pairwiseSquare(int[] seq1, int[] seq2) {
6888    if (!sameLength(seq1, seq2)) {
6889      return false;
6890    }
6891    assert seq1 != null && seq2 != null; // because sameLength() = true
6892    for (int i = 0 ; i < seq1.length ; i++) {
6893      if (ne(seq1[i], seq2[i] * seq2[i])) {
6894        return false;
6895      }
6896    }
6897    return true;
6898  }
6899  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6900  @Pure
6901  public static boolean pairwiseSquare(int[] seq1, long[] seq2) {
6902    if (!sameLength(seq1, seq2)) {
6903      return false;
6904    }
6905    assert seq1 != null && seq2 != null; // because sameLength() = true
6906    for (int i = 0 ; i < seq1.length ; i++) {
6907
6908      if (ne(seq1[i], seq2[i] * seq2[i])) {
6909
6910        return false;
6911      }
6912    }
6913    return true;
6914  }
6915
6916  /** True iff both sequences have the same length, and all seq1[i] == ~ seq2[i].
6917   *
6918   * Meaning (in pseudo-FOL):
6919   *
6920   * <pre>
6921   * /\ seq1.length == seq2.length
6922   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == ~ seq2[i]
6923   * </pre>
6924   *
6925   */
6926  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6927  @Pure
6928  public static boolean pairwiseBitwiseComplement(int[] seq1, int[] seq2) {
6929    if (!sameLength(seq1, seq2)) {
6930      return false;
6931    }
6932    assert seq1 != null && seq2 != null; // because sameLength() = true
6933    for (int i = 0 ; i < seq1.length ; i++) {
6934      if (seq1[i] != ~seq2[i]) {
6935        return false;
6936      }
6937    }
6938    return true;
6939  }
6940  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6941  @Pure
6942  public static boolean pairwiseBitwiseComplement(int[] seq1, long[] seq2) {
6943    if (!sameLength(seq1, seq2)) {
6944      return false;
6945    }
6946    assert seq1 != null && seq2 != null; // because sameLength() = true
6947    for (int i = 0 ; i < seq1.length ; i++) {
6948      if (seq1[i] != ~seq2[i]) {
6949        return false;
6950      }
6951    }
6952    return true;
6953  }
6954
6955  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6956  @Pure
6957  public static boolean pairwiseBitwiseComplement(Object[] seq1, Object[] seq2) {
6958    if (!sameLength(seq1, seq2)) {
6959      return false;
6960    }
6961    assert seq1 != null && seq2 != null; // because sameLength() = true
6962    if (!eltsNonNull(seq1)) {
6963      return false;
6964    }
6965    if (!eltsNonNull(seq2)) {
6966      return false;
6967    }
6968    int[] hashArr1 = new int[seq1.length];
6969    for (int i = 0 ; i < seq1.length ; i++) {
6970      hashArr1[i] = seq1[i].hashCode();
6971    }
6972    int[] hashArr2 = new int[seq2.length];
6973    for (int i = 0 ; i < seq2.length ; i++) {
6974      hashArr2[i] = seq2[i].hashCode();
6975    }
6976    return pairwiseBitwiseComplement(hashArr1, hashArr2);
6977  }
6978
6979  /** True iff both sequences have the same length, and all seq1[i] == (seq2[i] | seq1[i]).
6980   *
6981   * Meaning (in pseudo-FOL):
6982   *
6983   * <pre>
6984   * /\ seq1.length == seq2.length
6985   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == (seq2[i] | seq1[i])
6986   * </pre>
6987   *
6988   */
6989  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6990  @Pure
6991  public static boolean pairwiseBitwiseSubset(int[] seq1, int[] seq2) {
6992    if (seq1 == null) {
6993      return false;
6994    }
6995    if (seq2 == null) {
6996      return false;
6997    }
6998    if (seq1.length != seq2.length) {
6999      return false;
7000    }
7001    for (int i = 0 ; i < seq1.length ; i++) {
7002      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
7003        return false;
7004      }
7005    }
7006    return true;
7007  }
7008  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7009  @Pure
7010  public static boolean pairwiseBitwiseSubset(int[] seq1, long[] seq2) {
7011    if (!sameLength(seq1, seq2)) {
7012      return false;
7013    }
7014    assert seq1 != null && seq2 != null; // because sameLength() = true
7015    for (int i = 0 ; i < seq1.length ; i++) {
7016      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
7017        return false;
7018      }
7019    }
7020    return true;
7021  }
7022
7023  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7024  @Pure
7025  public static boolean pairwiseBitwiseSubset(Object[] seq1, Object[] seq2) {
7026    if (!sameLength(seq1, seq2)) {
7027      return false;
7028    }
7029    assert seq1 != null && seq2 != null; // because sameLength() = true
7030    if (!eltsNonNull(seq1)) {
7031      return false;
7032    }
7033    if (!eltsNonNull(seq2)) {
7034      return false;
7035    }
7036    int[] hashArr1 = new int[seq1.length];
7037    for (int i = 0 ; i < seq1.length ; i++) {
7038      hashArr1[i] = seq1[i].hashCode();
7039    }
7040    int[] hashArr2 = new int[seq2.length];
7041    for (int i = 0 ; i < seq2.length ; i++) {
7042      hashArr2[i] = seq2[i].hashCode();
7043    }
7044    return pairwiseBitwiseSubset(hashArr1, hashArr2);
7045  }
7046
7047  /**
7048   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
7049   *
7050   * <p>If either array is null, returns null. If either array is empty, returns only those
7051   * elements in the other array. If both arrays are empty, returns a new empty array.
7052   */
7053  @SideEffectFree
7054  public static int @PolyNull [] concat(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7055    if (seq1 == null) {
7056      return null;
7057    }
7058    if (seq2 == null) {
7059      return null;
7060    }
7061    return ArraysPlume.concat(seq1, seq2);
7062  }
7063
7064  @SideEffectFree
7065  public static long @PolyNull [] concat(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7066    if (seq1 == null) {
7067      return null;
7068    }
7069    if (seq2 == null) {
7070      return null;
7071    }
7072    // Cannot just use ArraysPlume.concat because the two arrays
7073    // have different types.  This essentially inlines that method.
7074    int newLength = seq1.length + seq2.length;
7075    long[] retval = new long[newLength];
7076
7077    for (int j = 0 ; j < seq1.length ; j++) {
7078      retval[j] = seq1[j];
7079    }
7080    System.arraycopy(seq2, 0, retval, seq1.length, seq2.length);
7081
7082    return retval;
7083  }
7084
7085  /**
7086   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
7087   * assurances about the order or repetition of elements: elements may be repeated, and their
7088   * order may be different from the order of elements in seq1 and seq2.
7089   */
7090  @SideEffectFree
7091  public static int @PolyNull [] union(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7092    if (seq1 == null) {
7093      return null;
7094    }
7095    if (seq2 == null) {
7096      return null;
7097    }
7098    return concat(seq1, seq2);
7099  }
7100
7101  @Pure
7102  public static long @PolyNull [] union(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7103    if (seq1 == null) {
7104      return null;
7105    }
7106    if (seq2 == null) {
7107      return null;
7108    }
7109    return concat(seq1, seq2);
7110  }
7111
7112  /**
7113   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
7114   * gives no assurances about the order or repetition of elements: elements may be repeated, and
7115   * their order may be different from the order of elements in seq1 and seq2.
7116   */
7117  @Pure
7118  public static int @PolyNull [] intersection(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7119    if (seq1 == null) {
7120      return null;
7121    }
7122    if (seq2 == null) {
7123      return null;
7124    }
7125    int[] intermediate = new int[Math.min(seq1.length, seq2.length)];
7126    int length = 0;
7127    for (int i = 0 ; i < seq1.length ; i++) {
7128      if (memberOf(seq1[i], seq2) ) {
7129        intermediate[length++] = seq1[i];
7130      }
7131    }
7132    return ArraysPlume.subarray(intermediate, 0, length);
7133  }
7134
7135  @Pure
7136  public static long @PolyNull [] intersection(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7137    if (seq1 == null) {
7138      return null;
7139    }
7140    if (seq2 == null) {
7141      return null;
7142    }
7143    long[] intermediate = new long[Math.min(seq1.length, seq2.length)];
7144    int length = 0;
7145    for (int i = 0 ; i < seq1.length ; i++) {
7146      if (memberOf(seq1[i], seq2) ) {
7147        intermediate[length++] = seq1[i];
7148      }
7149    }
7150    return ArraysPlume.subarray(intermediate, 0, length);
7151  }
7152
7153  /**
7154   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
7155   * no assurances about the order or repetition of elements: elements may be repeated, and their
7156   * order may be different from the order of elements in seq1 and seq2.
7157   */
7158  @Pure
7159  public static int @PolyNull [] setDiff(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7160    if (seq1 == null) {
7161      return null;
7162    }
7163    if (seq2 == null) {
7164      return null;
7165    }
7166    int[] intermediate = new int[seq1.length];
7167    int length = 0;
7168    for (int i = 0 ; i < seq1.length ; i++) {
7169      if (!memberOf(seq1[i], seq2)) {
7170        intermediate[length++] = seq1[i];
7171      }
7172    }
7173    return ArraysPlume.subarray(intermediate, 0, length);
7174  }
7175
7176  @Pure
7177  public static long @PolyNull [] setDiff(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7178    if (seq1 == null) {
7179      return null;
7180    }
7181    if (seq2 == null) {
7182      return null;
7183    }
7184    long[] intermediate = new long[seq1.length];
7185    int length = 0;
7186    for (int i = 0 ; i < seq1.length ; i++) {
7187      if (!memberOf(seq1[i], seq2)) {
7188        intermediate[length++] = seq1[i];
7189      }
7190    }
7191    return ArraysPlume.subarray(intermediate, 0, length);
7192  }
7193
7194  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
7195  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7196  @Pure
7197  public static boolean setEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7198    if (seq1 == null) {
7199      return false;
7200    }
7201    if (seq2 == null) {
7202      return false;
7203    }
7204    for (int i = 0; i < seq1.length ; i++) {
7205      if (!memberOf(seq1[i], seq2) ) {
7206        return false;
7207      }
7208    }
7209    for (int i = 0; i < seq2.length ; i++) {
7210      if (!memberOf(seq2[i], seq1) ) {
7211        return false;
7212      }
7213    }
7214    return true;
7215  }
7216
7217  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7218  @Pure
7219  public static boolean setEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7220    if (seq1 == null) {
7221      return false;
7222    }
7223    if (seq2 == null) {
7224      return false;
7225    }
7226    for (int i = 0; i < seq1.length ; i++) {
7227      if (!memberOf(seq1[i], seq2) ) {
7228        return false;
7229      }
7230    }
7231    for (int i = 0; i < seq2.length ; i++) {
7232      if (!memberOf(seq2[i], seq1) ) {
7233        return false;
7234      }
7235    }
7236    return true;
7237  }
7238
7239  /** True iff seq1 is the reverse of seq2.
7240   *
7241   * Meaning (in pseudo-FOL):
7242   *
7243   * <pre>
7244   * /\ seq1.length == seq2.length
7245   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
7246   * </pre>
7247   *
7248   */
7249  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7250  @Pure
7251  public static boolean isReverse(int[] seq1, int[] seq2) {
7252    if (!sameLength(seq1, seq2)) {
7253      return false;
7254    }
7255    assert seq1 != null && seq2 != null; // because sameLength() = true
7256    int length = seq1.length;
7257    for (int i = 0 ; i < length ; i++) {
7258      if (ne(seq1[i], seq2[length - i - 1])) {
7259        return false;
7260      }
7261    }
7262    return true;
7263  }
7264
7265  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7266  @Pure
7267  public static boolean isReverse(int @Nullable [] seq1, long @Nullable [] seq2) {
7268    if (!sameLength(seq1, seq2)) {
7269      return false;
7270    }
7271    assert seq1 != null && seq2 != null; // because sameLength() = true
7272    int length = seq1.length;
7273    for (int i = 0 ; i < length ; i++) {
7274      if (ne(seq1[i], seq2[length - i - 1])) {
7275        return false;
7276      }
7277    }
7278    return true;
7279  }
7280
7281  /** True iff all elements in elts occur once or more in arr;
7282   * that is, elts is a subset of arr.
7283   *
7284   * Meaning (in pseudo-FOL):
7285   *
7286   * forall i in { 0..elt.length-1 } : elt[i] element_of arr
7287   *
7288   */
7289  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7290  @Pure
7291  public static boolean subsetOf(@Nullable Object elts, @Nullable Object arr) {
7292    if (elts == null) {
7293      return false;
7294    }
7295    if (arr == null) {
7296      return false;
7297    }
7298    if (!(elts.getClass().isArray() && arr.getClass().isArray())) {
7299      // throw new IllegalArgumentException("both arguments must be arrays.");
7300      return false;
7301    }
7302    // We know that the two arguments are arrays of different types; if
7303    // they had been of the same type, then one of the more specific
7304    // overriding versions of this method would have been called.
7305
7306    // This implementation simply calls either subsetOf(long[], long[]) or
7307    // subsetOf(double[], double[]).
7308
7309    Class<?> eltsType = elts.getClass().getComponentType();
7310    Class<?> arrType = arr.getClass().getComponentType();
7311    if (isIntegralType(eltsType) && isIntegralType(arrType)) {
7312      // Both arrays are int/long.
7313      // Cast both arrays to long and call subsetOf(long[],long[]).
7314      long[] elts_long;
7315      if (eltsType == Long.class) {
7316        elts_long = (long[]) elts;
7317      } else {
7318        elts_long = new long[Array.getLength(elts)];
7319        for (int i = 0 ; i < elts_long.length ; i++) {
7320          elts_long[i] = Array.getLong(elts, i);
7321        }
7322      }
7323      long[] arr_long;
7324      if (arrType == Long.class) {
7325        arr_long = (long[]) arr;
7326      } else {
7327        arr_long = new long[Array.getLength(arr)];
7328        for (int i = 0 ; i < arr_long.length ; i++) {
7329          arr_long[i] = Array.getLong(arr, i);
7330        }
7331      }
7332      return subsetOf(elts_long, arr_long);
7333    } else if (isNumericType(eltsType) && isNumericType(arrType)) {
7334      // At least one array is float/double.
7335      // Cast both arrays to double and call subsetOf(double[],double[])
7336      double[] elts_double = new double[Array.getLength(elts)];
7337      for (int i = 0 ; i < elts_double.length ; i++) {
7338        elts_double[i] = Array.getDouble(elts, i);
7339      }
7340      double[] arr_double = new double[Array.getLength(arr)];
7341      for (int i = 0 ; i < arr_double.length ; i++) {
7342        arr_double[i] = Array.getDouble(arr, i);
7343      }
7344      return subsetOf(elts_double, arr_double);
7345    } else {
7346      // throw new IllegalArgumentException("both arguments must be arrays of numeric types.");
7347      return false;
7348    }
7349
7350  }
7351
7352  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
7353  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7354  @Pure
7355  public static boolean subsetOf(int @Nullable [] seq1, int @Nullable [] seq2) {
7356    if (seq1 == null) {
7357      return false;
7358    }
7359    if (seq2 == null) {
7360      return false;
7361    }
7362    for (int i = 0 ; i < seq1.length ; i++) {
7363      if (!memberOf(seq1[i], seq2)) {
7364        return false;
7365      }
7366    }
7367    return true;
7368  }
7369
7370  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7371  @Pure
7372  public static boolean subsetOf(int @Nullable [] seq1, long @Nullable [] seq2) {
7373    if (seq1 == null) {
7374      return false;
7375    }
7376    if (seq2 == null) {
7377      return false;
7378    }
7379    for (int i = 0 ; i < seq1.length ; i++) {
7380      if (!memberOf(seq1[i], seq2)) {
7381        return false;
7382      }
7383    }
7384    return true;
7385  }
7386
7387  /** Returns true iff seq contains no duplicate elements. */
7388  @EnsuresNonNullIf(result=true, expression="#1")
7389  @Pure
7390  public static boolean noDups(int @Nullable [] seq) {
7391    if (seq == null) {
7392      return false;
7393    }
7394    return ArraysPlume.noDuplicates(seq);
7395  }
7396
7397 /** Returns true iff elt is in array arr. */
7398  @EnsuresNonNullIf(result=true, expression="#2")
7399  @Pure
7400  public static boolean memberOf(int elt, int @Nullable [] arr) {
7401    if (arr == null) {
7402      return false;
7403    }
7404    for (int i = 0 ; i < arr.length ; i++) {
7405      if (eq(arr[i], elt)) {
7406        return true;
7407      }
7408    }
7409    return false;
7410  }
7411
7412  @EnsuresNonNullIf(result=true, expression="#2")
7413  @Pure
7414  public static boolean memberOf(int elt, long @Nullable [] arr) {
7415    if (arr == null) {
7416      return false;
7417    }
7418    for (int i = 0 ; i < arr.length ; i++) {
7419      if (eq(arr[i], elt)) {
7420        return true;
7421      }
7422    }
7423    return false;
7424  }
7425
7426  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
7427  @Pure
7428  public static int @PolyNull [] slice(int @PolyNull [] seq, int start, int end) {
7429    if (seq == null) {
7430      return null;
7431    }
7432    int sliceStart = start;
7433    int sliceEnd = end;
7434    if (start < 0) {
7435      return new int[] { };
7436    }
7437    if (end > seq.length - 1) {
7438      return new int[] { };
7439    }
7440    if (sliceStart > sliceEnd) {
7441      return new int[] { };
7442    }
7443    int length = sliceEnd - sliceStart + 1;
7444    return ArraysPlume.subarray(seq, sliceStart, length);
7445  }
7446
7447  @Pure
7448  public static int @PolyNull [] slice(int @PolyNull [] seq, long start, int end) {
7449    return slice(seq, (int)start, end);
7450  }
7451  @Pure
7452  public static int @PolyNull [] slice(int @PolyNull [] seq, int start, long end) {
7453    return slice(seq, start, (int)end);
7454  }
7455  @Pure
7456  public static int @PolyNull [] slice(int @PolyNull [] seq, long start, long end) {
7457    return slice(seq, (int)start, (int)end);
7458  }
7459
7460  /** True iff all elements in arr equal elt.
7461   *
7462   * Meaning (in pseudo-FOL):
7463   *
7464   * forall i in { 0..arr.length-1 } : arr[i] == elt
7465   *
7466   */
7467  @EnsuresNonNullIf(result=true, expression="#1")
7468  @Pure
7469  public static boolean eltsEqual(int @Nullable [] arr, int elt) {
7470    if (arr == null) {
7471      return false;
7472    }
7473    for (int i = 0 ; i < arr.length ; i++) {
7474      if (ne(arr[i], elt)) {
7475        return false;
7476      }
7477    }
7478    return true;
7479  }
7480
7481  @EnsuresNonNullIf(result=true, expression="#1")
7482  @Pure
7483  public static boolean eltsEqual(int @Nullable [] arr, long elt) {
7484    if (arr == null) {
7485      return false;
7486    }
7487    for (int i = 0 ; i < arr.length ; i++) {
7488      if (ne(arr[i], elt)) {
7489        return false;
7490      }
7491    }
7492    return true;
7493  }
7494
7495  /** True iff every element in arr does not equal elt.
7496   *
7497   * Meaning (in pseudo-FOL):
7498   *
7499   * forall i in { 0..arr.length-1 } : arr[i] != elt
7500   *
7501   */
7502  @EnsuresNonNullIf(result=true, expression="#1")
7503  @Pure
7504  public static boolean eltsNotEqual(int @Nullable [] arr, int elt) {
7505    if (arr == null) {
7506      return false;
7507    }
7508    for (int i = 0 ; i < arr.length ; i++) {
7509      if (eq(arr[i], elt)) {
7510        return false;
7511      }
7512    }
7513    return true;
7514  }
7515
7516  @EnsuresNonNullIf(result=true, expression="#1")
7517  @Pure
7518  public static boolean eltsNotEqual(int @Nullable [] arr, long elt) {
7519    if (arr == null) {
7520      return false;
7521    }
7522    for (int i = 0 ; i < arr.length ; i++) {
7523      if (eq(arr[i], elt)) {
7524        return false;
7525      }
7526    }
7527    return true;
7528  }
7529
7530  /** True iff every element in arr is greater than elt.
7531   *
7532   * Meaning (in pseudo-FOL):
7533   *
7534   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
7535   *
7536   */
7537  @EnsuresNonNullIf(result=true, expression="#1")
7538  @Pure
7539  public static boolean eltsGT(int @Nullable [] arr, int elt) {
7540    if (arr == null) {
7541      return false;
7542    }
7543    for (int i = 0 ; i < arr.length ; i++) {
7544      if (lte(arr[i], elt)) {
7545        return false;
7546      }
7547    }
7548    return true;
7549  }
7550
7551  @EnsuresNonNullIf(result=true, expression="#1")
7552  @Pure
7553  public static boolean eltsGT(int @Nullable [] arr, long elt) {
7554    if (arr == null) {
7555      return false;
7556    }
7557    for (int i = 0 ; i < arr.length ; i++) {
7558      if (lte(arr[i], elt)) {
7559        return false;
7560      }
7561    }
7562    return true;
7563  }
7564
7565  /** True iff every element in arr is greater than or equal to elt.
7566   *
7567   * Meaning (in pseudo-FOL):
7568   *
7569   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
7570   *
7571   */
7572  @EnsuresNonNullIf(result=true, expression="#1")
7573  @Pure
7574  public static boolean eltsGTE(int @Nullable [] arr, int elt) {
7575    if (arr == null) {
7576      return false;
7577    }
7578    for (int i = 0 ; i < arr.length ; i++) {
7579      if (lt(arr[i], elt)) {
7580        return false;
7581      }
7582    }
7583    return true;
7584  }
7585
7586  @EnsuresNonNullIf(result=true, expression="#1")
7587  @Pure
7588  public static boolean eltsGTE(int @Nullable [] arr, long elt) {
7589    if (arr == null) {
7590      return false;
7591    }
7592    for (int i = 0 ; i < arr.length ; i++) {
7593      if (lt(arr[i], elt)) {
7594        return false;
7595      }
7596    }
7597    return true;
7598  }
7599
7600  /** True iff every element in arr is less than elt.
7601   *
7602   * Meaning (in pseudo-FOL):
7603   *
7604   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
7605   *
7606   */
7607  @EnsuresNonNullIf(result=true, expression="#1")
7608  @Pure
7609  public static boolean eltsLT(int @Nullable [] arr, int elt) {
7610    if (arr == null) {
7611      return false;
7612    }
7613    for (int i = 0 ; i < arr.length ; i++) {
7614      if (gte(arr[i], elt)) {
7615        return false;
7616      }
7617    }
7618    return true;
7619  }
7620
7621  @EnsuresNonNullIf(result=true, expression="#1")
7622  @Pure
7623  public static boolean eltsLT(int @Nullable [] arr, long elt) {
7624    if (arr == null) {
7625      return false;
7626    }
7627    for (int i = 0 ; i < arr.length ; i++) {
7628      if (gte(arr[i], elt)) {
7629        return false;
7630      }
7631    }
7632    return true;
7633  }
7634
7635  /** True iff every element in arr is less than or equal to elt.
7636   *
7637   * Meaning (in pseudo-FOL):
7638   *
7639   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
7640   *
7641   */
7642  @EnsuresNonNullIf(result=true, expression="#1")
7643  @Pure
7644  public static boolean eltsLTE(int @Nullable [] arr, int elt) {
7645    if (arr == null) {
7646      return false;
7647    }
7648    for (int i = 0 ; i < arr.length ; i++) {
7649      if (gt(arr[i], elt)) {
7650        return false;
7651      }
7652    }
7653    return true;
7654  }
7655
7656  @EnsuresNonNullIf(result=true, expression="#1")
7657  @Pure
7658  public static boolean eltsLTE(int @Nullable [] arr, long elt) {
7659    if (arr == null) {
7660      return false;
7661    }
7662    for (int i = 0 ; i < arr.length ; i++) {
7663      if (gt(arr[i], elt)) {
7664        return false;
7665      }
7666    }
7667    return true;
7668  }
7669
7670  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
7671   *
7672   * Meaning (in pseudo-FOL):
7673   *
7674   * /\ seq1.length == se2.length
7675   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
7676   *
7677   */
7678
7679  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7680  @Pure
7681  public static boolean pairwiseEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7682    if (!sameLength(seq1, seq2)) {
7683      return false;
7684    }
7685    assert seq1 != null && seq2 != null; // because sameLength() = true
7686    for (int i = 0 ; i < seq1.length ; i++) {
7687      if (ne(seq1[i], seq2[i])) {
7688        return false;
7689      }
7690    }
7691    return true;
7692  }
7693
7694  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7695  @Pure
7696  public static boolean pairwiseEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7697    if (!sameLength(seq1, seq2)) {
7698      return false;
7699    }
7700    assert seq1 != null && seq2 != null; // because sameLength() = true
7701    for (int i = 0 ; i < seq1.length ; i++) {
7702      if (ne(seq1[i], seq2[i])) {
7703        return false;
7704      }
7705    }
7706    return true;
7707  }
7708
7709  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
7710   *
7711   * Meaning (in pseudo-FOL):
7712   *
7713   * /\ seq1.length == se2.length
7714   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
7715   *
7716   */
7717  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7718  @Pure
7719  public static boolean pairwiseNotEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7720    if (!sameLength(seq1, seq2)) {
7721      return false;
7722    }
7723    assert seq1 != null && seq2 != null; // because sameLength() = true
7724    for (int i = 0 ; i < seq1.length ; i++) {
7725      if (eq(seq1[i], seq2[i])) {
7726        return false;
7727      }
7728    }
7729    return true;
7730  }
7731
7732  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7733  @Pure
7734  public static boolean pairwiseNotEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7735    if (!sameLength(seq1, seq2)) {
7736      return false;
7737    }
7738    assert seq1 != null && seq2 != null; // because sameLength() = true
7739    for (int i = 0 ; i < seq1.length ; i++) {
7740      if (eq(seq1[i], seq2[i])) {
7741        return false;
7742      }
7743    }
7744    return true;
7745  }
7746
7747  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
7748   *
7749   * Meaning (in pseudo-FOL):
7750   *
7751   * /\ seq1.length == se2.length
7752   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
7753   *
7754   */
7755  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7756  @Pure
7757  public static boolean pairwiseLT(int @Nullable [] seq1, int @Nullable [] seq2) {
7758    if (!sameLength(seq1, seq2)) {
7759      return false;
7760    }
7761    assert seq1 != null && seq2 != null; // because sameLength() = true
7762    for (int i = 0 ; i < seq1.length ; i++) {
7763      if (gte(seq1[i], seq2[i])) {
7764        return false;
7765      }
7766    }
7767    return true;
7768  }
7769
7770  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7771  @Pure
7772  public static boolean pairwiseLT(int @Nullable [] seq1, long @Nullable [] seq2) {
7773    if (!sameLength(seq1, seq2)) {
7774      return false;
7775    }
7776    assert seq1 != null && seq2 != null; // because sameLength() = true
7777    for (int i = 0 ; i < seq1.length ; i++) {
7778      if (gte(seq1[i], seq2[i])) {
7779        return false;
7780      }
7781    }
7782    return true;
7783  }
7784
7785  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
7786   * Meaning (in pseudo-FOL):
7787   *
7788   * /\ seq1.length == se2.length
7789   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
7790   *
7791   */
7792  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7793  @Pure
7794  public static boolean pairwiseLTE(int @Nullable [] seq1, int @Nullable [] seq2) {
7795    if (!sameLength(seq1, seq2)) {
7796      return false;
7797    }
7798    assert seq1 != null && seq2 != null; // because sameLength() = true
7799    for (int i = 0 ; i < seq1.length ; i++) {
7800      if (gt(seq1[i], seq2[i])) {
7801        return false;
7802      }
7803    }
7804    return true;
7805  }
7806
7807  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7808  @Pure
7809  public static boolean pairwiseLTE(int @Nullable [] seq1, long @Nullable [] seq2) {
7810    if (!sameLength(seq1, seq2)) {
7811      return false;
7812    }
7813    assert seq1 != null && seq2 != null; // because sameLength() = true
7814    for (int i = 0 ; i < seq1.length ; i++) {
7815      if (gt(seq1[i], seq2[i])) {
7816        return false;
7817      }
7818    }
7819    return true;
7820  }
7821
7822  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
7823   * Meaning (in pseudo-FOL):
7824   *
7825   * /\ seq1.length == se2.length
7826   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
7827   *
7828   */
7829  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7830  @Pure
7831  public static boolean pairwiseGT(int @Nullable [] seq1, int @Nullable [] seq2) {
7832    if (!sameLength(seq1, seq2)) {
7833      return false;
7834    }
7835    assert seq1 != null && seq2 != null; // because sameLength() = true
7836    for (int i = 0 ; i < seq1.length ; i++) {
7837      if (lte(seq1[i], seq2[i])) {
7838        return false;
7839      }
7840    }
7841    return true;
7842  }
7843
7844  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7845  @Pure
7846  public static boolean pairwiseGT(int @Nullable [] seq1, long @Nullable [] seq2) {
7847    if (!sameLength(seq1, seq2)) {
7848      return false;
7849    }
7850    assert seq1 != null && seq2 != null; // because sameLength() = true
7851    for (int i = 0 ; i < seq1.length ; i++) {
7852      if (lte(seq1[i], seq2[i])) {
7853        return false;
7854      }
7855    }
7856    return true;
7857  }
7858
7859  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
7860   * Meaning (in pseudo-FOL):
7861   *
7862   * /\ seq1.length == se2.length
7863   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
7864   *
7865   */
7866  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7867  @Pure
7868  public static boolean pairwiseGTE(int @Nullable [] seq1, int @Nullable [] seq2) {
7869    if (!sameLength(seq1, seq2)) {
7870      return false;
7871    }
7872    assert seq1 != null && seq2 != null; // because sameLength() = true
7873    for (int i = 0 ; i < seq1.length ; i++) {
7874      if (lt(seq1[i], seq2[i])) {
7875        return false;
7876      }
7877    }
7878    return true;
7879  }
7880
7881  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7882  @Pure
7883  public static boolean pairwiseGTE(int @Nullable [] seq1, long @Nullable [] seq2) {
7884    if (!sameLength(seq1, seq2)) {
7885      return false;
7886    }
7887    assert seq1 != null && seq2 != null; // because sameLength() = true
7888    for (int i = 0 ; i < seq1.length ; i++) {
7889      if (lt(seq1[i], seq2[i])) {
7890        return false;
7891      }
7892    }
7893    return true;
7894  }
7895
7896  /**
7897   * Returns true iff seq1 is lexically equal to seq2.
7898   * For equality, "lexically" and "pairwise" are the same.
7899   */
7900  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7901  @Pure
7902  public static boolean lexEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7903    if (seq1 == null) {
7904      return false;
7905    }
7906    if (seq2 == null) {
7907      return false;
7908    }
7909    return pairwiseEqual(seq1, seq2);
7910  }
7911
7912  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7913  @Pure
7914  public static boolean lexEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7915    if (seq1 == null) {
7916      return false;
7917    }
7918    if (seq2 == null) {
7919      return false;
7920    }
7921    return pairwiseEqual(seq1, seq2);
7922  }
7923
7924  /** Returns true iff seq1 is lexically not equal to seq2. */
7925  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7926  @Pure
7927  public static boolean lexNotEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7928    if (seq1 == null) {
7929      return false;
7930    }
7931    if (seq2 == null) {
7932      return false;
7933    }
7934    return !lexEqual(seq1, seq2);
7935  }
7936
7937  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7938  @Pure
7939  public static boolean lexNotEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7940    if (seq1 == null) {
7941      return false;
7942    }
7943    if (seq2 == null) {
7944      return false;
7945    }
7946    return !lexEqual(seq1, seq2);
7947  }
7948
7949  /** Returns true iff seq1 is lexically &lt;  seq2. */
7950  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7951  @Pure
7952  public static boolean lexLT(int @Nullable [] seq1, int @Nullable [] seq2) {
7953    if (seq1 == null) {
7954      return false;
7955    }
7956    if (seq2 == null) {
7957      return false;
7958    }
7959    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
7960    for (int i = 0 ; i < minlength ; i++) {
7961      if (gt(seq1[i], seq2[i])) {
7962        return false;
7963      } else if (lt(seq1[i], seq2[i])) {
7964        return true;
7965      }
7966    }
7967    if (seq1.length >= seq2.length) {
7968      return false;
7969    }
7970    return true;
7971  }
7972
7973  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7974  @Pure
7975  public static boolean lexLT(int @Nullable [] seq1, long @Nullable [] seq2) {
7976    if (seq1 == null) {
7977      return false;
7978    }
7979    if (seq2 == null) {
7980      return false;
7981    }
7982    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
7983    for (int i = 0 ; i < minlength ; i++) {
7984      if (gt(seq1[i], seq2[i])) {
7985        return false;
7986        } else if (lt(seq1[i], seq2[i])) {
7987          return true;
7988        }
7989      }
7990      if (seq1.length >= seq2.length) {
7991        return false;
7992      }
7993      return true;
7994    }
7995
7996  /** Returns true iff seq1 is lexically &le; to seq2. */
7997  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7998  @Pure
7999  public static boolean lexLTE(int @Nullable [] seq1, int @Nullable [] seq2) {
8000    if (seq1 == null) {
8001      return false;
8002    }
8003    if (seq2 == null) {
8004      return false;
8005    }
8006    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8007    for (int i = 0 ; i < minlength ; i++) {
8008      if (gt(seq1[i], seq2[i])) {
8009        return false;
8010      } else if (lt(seq1[i], seq2[i])) {
8011        return true;
8012      }
8013    }
8014    if (seq1.length > seq2.length) {
8015      return false;
8016    }
8017    return true;
8018  }
8019
8020  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8021  @Pure
8022  public static boolean lexLTE(int @Nullable [] seq1, long @Nullable [] seq2) {
8023  if (seq1 == null) {
8024    return false;
8025  }
8026  if (seq2 == null) {
8027    return false;
8028  }
8029    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8030    for (int i = 0 ; i < minlength ; i++) {
8031      if (gt(seq1[i], seq2[i])) {
8032        return false;
8033      } else if (lt(seq1[i], seq2[i])) {
8034        return true;
8035      }
8036    }
8037    if (seq1.length > seq2.length) {
8038      return false;
8039    }
8040    return true;
8041  }
8042
8043  /** Returns true iff seq1 is lexically &gt; to seq2. */
8044  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8045  @Pure
8046  public static boolean lexGT(int @Nullable [] seq1, int @Nullable [] seq2) {
8047  if (seq1 == null) {
8048    return false;
8049  }
8050  if (seq2 == null) {
8051    return false;
8052  }
8053    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8054    for (int i = 0 ; i < minlength ; i++) {
8055      if (lt(seq1[i], seq2[i])) {
8056        return false;
8057      } else if (gt(seq1[i], seq2[i])) {
8058        return true;
8059      }
8060    }
8061    if (seq1.length <= seq2.length) {
8062      return false;
8063    }
8064    return true;
8065  }
8066
8067  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8068  @Pure
8069  public static boolean lexGT(int @Nullable [] seq1, long @Nullable [] seq2) {
8070  if (seq1 == null) {
8071    return false;
8072  }
8073  if (seq2 == null) {
8074    return false;
8075  }
8076    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8077    for (int i = 0 ; i < minlength ; i++) {
8078      if (lt(seq1[i], seq2[i])) {
8079        return false;
8080      } else if (gt(seq1[i], seq2[i])) {
8081        return true;
8082      }
8083    }
8084    if (seq1.length <= seq2.length) {
8085      return false;
8086    }
8087    return true;
8088  }
8089
8090  /** Returns true iff seq1 is lexically &ge; to seq2. */
8091  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8092  @Pure
8093  public static boolean lexGTE(int @Nullable [] seq1, int @Nullable [] seq2) {
8094  if (seq1 == null) {
8095    return false;
8096  }
8097  if (seq2 == null) {
8098    return false;
8099  }
8100    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8101    for (int i = 0 ; i < minlength ; i++) {
8102      if (lt(seq1[i], seq2[i])) {
8103        return false;
8104      } else if (gt(seq1[i], seq2[i])) {
8105        return true;
8106      }
8107    }
8108    if (seq1.length < seq2.length) {
8109      return false;
8110    }
8111    return true;
8112  }
8113
8114  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8115  @Pure
8116  public static boolean lexGTE(int @Nullable [] seq1, long @Nullable [] seq2) {
8117  if (seq1 == null) {
8118    return false;
8119  }
8120  if (seq2 == null) {
8121    return false;
8122  }
8123    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8124    for (int i = 0 ; i < minlength ; i++) {
8125      if (lt(seq1[i], seq2[i])) {
8126        return false;
8127      } else if (gt(seq1[i], seq2[i])) {
8128        return true;
8129      }
8130    }
8131    if (seq1.length < seq2.length) {
8132      return false;
8133    }
8134    return true;
8135  }
8136
8137  /** True iff for all applicable i, every seq[i] == seq[i+1].
8138   *
8139   * Meaning (in pseudo-FOL):
8140   *
8141   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
8142   *
8143   */
8144  @EnsuresNonNullIf(result=true, expression="#1")
8145  @Pure
8146  public static boolean eltwiseEqual(int @Nullable [] seq) {
8147  if (seq == null) {
8148    return false;
8149  }
8150    for (int i = 0 ; i < seq.length ; i++) {
8151      if (i < seq.length - 1) {
8152        if (ne(seq[i], seq[i + 1])) {
8153          return false;
8154        }
8155      }
8156    }
8157    return true;
8158  }
8159
8160  /** True iff for all applicable i, every seq[i] != seq[i+1].
8161   *
8162   * Meaning (in pseudo-FOL):
8163   *
8164   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
8165   *
8166   */
8167  @EnsuresNonNullIf(result=true, expression="#1")
8168  @Pure
8169  public static boolean eltwiseNotEqual(int @Nullable [] seq) {
8170  if (seq == null) {
8171    return false;
8172  }
8173    for (int i = 0 ; i < seq.length ; i++) {
8174      if (i < seq.length - 1) {
8175        if (eq(seq[i], seq[i + 1])) {
8176          return false;
8177        }
8178      }
8179    }
8180    return true;
8181  }
8182
8183  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
8184   *
8185   * Meaning (in pseudo-FOL):
8186   *
8187   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
8188   *
8189   */
8190  @EnsuresNonNullIf(result=true, expression="#1")
8191  @Pure
8192  public static boolean eltwiseLT(int @Nullable [] seq) {
8193  if (seq == null) {
8194    return false;
8195  }
8196    for (int i = 0 ; i < seq.length ; i++) {
8197      if (i < seq.length - 1) {
8198        if (gte(seq[i], seq[i + 1])) {
8199          return false;
8200        }
8201      }
8202    }
8203    return true;
8204  }
8205
8206  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
8207   *
8208   * Meaning (in pseudo-FOL):
8209   *
8210   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
8211   *
8212   */
8213  @EnsuresNonNullIf(result=true, expression="#1")
8214  @Pure
8215  public static boolean eltwiseLTE(int @Nullable [] seq) {
8216  if (seq == null) {
8217    return false;
8218  }
8219    for (int i = 0 ; i < seq.length ; i++) {
8220      if (i < seq.length - 1) {
8221        if (gt(seq[i], seq[i + 1])) {
8222          return false;
8223        }
8224      }
8225    }
8226    return true;
8227  }
8228
8229  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
8230   *
8231   * Meaning (in pseudo-FOL):
8232   *
8233   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
8234   *
8235   */
8236  @EnsuresNonNullIf(result=true, expression="#1")
8237  @Pure
8238  public static boolean eltwiseGT(int @Nullable [] seq) {
8239  if (seq == null) {
8240    return false;
8241  }
8242    for (int i = 0 ; i < seq.length ; i++) {
8243      if (i < seq.length - 1) {
8244        if (lte(seq[i], seq[i + 1])) {
8245          return false;
8246        }
8247      }
8248    }
8249    return true;
8250  }
8251
8252  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
8253   *
8254   * Meaning (in pseudo-FOL):
8255   *
8256   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
8257   *
8258   */
8259  @EnsuresNonNullIf(result=true, expression="#1")
8260  @Pure
8261  public static boolean eltwiseGTE(int @Nullable [] seq) {
8262  if (seq == null) {
8263    return false;
8264  }
8265    for (int i = 0 ; i < seq.length ; i++) {
8266      if (i < seq.length - 1) {
8267        if (lt(seq[i], seq[i + 1])) {
8268          return false;
8269        }
8270      }
8271    }
8272    return true;
8273  }
8274
8275  /** True iff for all applicable i, every seq[i] == i.
8276   *
8277   * Meaning (in pseudo-FOL):
8278   *
8279   * forall i in { 0..seq.length-1 } : seq[i] == i
8280   *
8281   */
8282  @EnsuresNonNullIf(result=true, expression="#1")
8283  @Pure
8284  public static boolean eltsEqualIndex(int @Nullable [] seq) {
8285  if (seq == null) {
8286    return false;
8287  }
8288    for (int i = 0 ; i < seq.length ; i++) {
8289      if (ne(seq[i], i)) {
8290        return false;
8291      }
8292    }
8293    return true;
8294  }
8295
8296  /** True iff for all applicable i, every seq[i] != i.
8297   *
8298   * Meaning (in pseudo-FOL):
8299   *
8300   * forall i in { 0..seq.length-1 } : seq[i] != i
8301   *
8302   */
8303  @EnsuresNonNullIf(result=true, expression="#1")
8304  @Pure
8305  public static boolean eltsNotEqualIndex(int @Nullable [] seq) {
8306  if (seq == null) {
8307    return false;
8308  }
8309    for (int i = 0 ; i < seq.length ; i++) {
8310      if (eq(seq[i], i)) {
8311        return false;
8312      }
8313    }
8314    return true;
8315  }
8316
8317  /** True iff for all applicable i, every seq[i] &lt; i.
8318   *
8319   * Meaning (in pseudo-FOL):
8320   *
8321   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
8322   *
8323   */
8324  @EnsuresNonNullIf(result=true, expression="#1")
8325  @Pure
8326  public static boolean eltsLtIndex(int @Nullable [] seq) {
8327  if (seq == null) {
8328    return false;
8329  }
8330    for (int i = 0 ; i < seq.length ; i++) {
8331      if (gte(seq[i], i)) {
8332        return false;
8333      }
8334    }
8335    return true;
8336  }
8337
8338  /** True iff for all applicable i, every seq[i] &le; i.
8339   *
8340   * Meaning (in pseudo-FOL):
8341   *
8342   * forall i in { 0..seq.length-1 } : seq[i] &le; i
8343   *
8344   */
8345  @EnsuresNonNullIf(result=true, expression="#1")
8346  @Pure
8347  public static boolean eltsLteIndex(int @Nullable [] seq) {
8348  if (seq == null) {
8349    return false;
8350  }
8351    for (int i = 0 ; i < seq.length ; i++) {
8352      if (gt(seq[i], i)) {
8353        return false;
8354      }
8355    }
8356    return true;
8357  }
8358
8359  /** True iff for all applicable i, every seq[i] &gt; i.
8360   *
8361   * Meaning (in pseudo-FOL):
8362   *
8363   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
8364   *
8365   */
8366  @EnsuresNonNullIf(result=true, expression="#1")
8367  @Pure
8368  public static boolean eltsGtIndex(int @Nullable [] seq) {
8369  if (seq == null) {
8370    return false;
8371  }
8372    for (int i = 0 ; i < seq.length ; i++) {
8373      if (lte(seq[i], i)) {
8374        return false;
8375      }
8376    }
8377    return true;
8378  }
8379
8380  /** True iff for all applicable i, every seq[i] &ge; i.
8381   *
8382   * Meaning (in pseudo-FOL):
8383   *
8384   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
8385   *
8386   */
8387  @EnsuresNonNullIf(result=true, expression="#1")
8388  @Pure
8389  public static boolean eltsGteIndex(int @Nullable [] seq) {
8390  if (seq == null) {
8391    return false;
8392  }
8393    for (int i = 0 ; i < seq.length ; i++) {
8394      if (lt(seq[i], i)) {
8395        return false;
8396      }
8397    }
8398    return true;
8399  }
8400
8401  /// Deferencing (accessing) fields
8402
8403  /**
8404   * collectint accepts an object and a list of fields (one of which is of array type, and the
8405   * rest of which are not), and produces an array in which the original object has had the given
8406   * fields accessed.
8407   *
8408   * <p>Daikon creates invariants over "variables" such as the following.
8409   *
8410   * <dl>
8411   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
8412   *              for all y's in array x.arr.</dd>
8413   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
8414   *              for all x's in array arr.</dd>
8415   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
8416   * </dl>
8417   *
8418   * <p>The collectint() method does this collecting work.
8419   *
8420   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
8421   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
8422   * elements that result from following the fields, one of which is assumed to be an array.
8423   *
8424   * <p>
8425   * requires: fieldStr.length() &gt; 0 and object != null
8426   * <p>
8427   * requires: fieldStr contains only field names, no "[]" strings.
8428   * <p>
8429   * requires: the method only works for field sequences with exactly one field representing an
8430   * array. For example, the collection a[].b[].c will fail.
8431   *
8432   * @return if the resulting collection is of non-primitive type, then returns an array of type
8433   * Object[]. Returns null if any array or field access causes an exception.
8434   */
8435
8436  @SideEffectFree
8437  public static int @Nullable [] collectint(@Nullable Object object, @Nullable String fieldStr) {
8438
8439    if (object == null) {
8440      return null;
8441    }
8442    if (fieldStr == null) {
8443      return null;
8444    }
8445
8446    // assert fieldStr != null && !"".equals(fieldStr);
8447    String[] fieldNames = fieldStr.split("\\.");
8448    int[] retval = collectint(object, fieldNames, 0);
8449    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
8450    return retval;
8451  }
8452
8453  /** Helper method for collectint(Object, String).
8454   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
8455   * @see collectint(Object, String)
8456   */
8457  // @PolyNull does not work for return type, because null is returned on error.
8458  @SideEffectFree
8459  private static int @Nullable [] collectint(@Nullable Object object,
8460                                                   String[] fields, int fieldsStartIdx) {
8461
8462    if (object == null) {
8463      return null;
8464    }
8465    assert (fields != null);
8466    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
8467
8468    Object fieldObj;
8469    try {
8470      Field field = (object instanceof java.lang.Class<?>)
8471        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
8472        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
8473      field.setAccessible(true);
8474      // Class cls = field.getType();
8475      fieldObj = field.get(object);
8476      // System.out.println("***fieldObj="+fieldObj);
8477
8478    } catch (Exception e) {
8479      return null;
8480
8481    }
8482
8483    if (fieldObj == null) {
8484      return null;
8485    }
8486
8487    // base case: just accessed the last field
8488    if (fields.length - 1 == fieldsStartIdx) {
8489
8490      if (fieldObj.getClass().isArray()) {
8491        // last field is an array
8492        return (int[])fieldObj;
8493      } else {
8494        // This hack should be removed in favor of, at "oneEltArray = ..."
8495        // below, calling a version of collectint_field that throws an
8496        // error.  Then, this case becomes a run-time error.  -MDE
8497
8498        // Just one element; return a one-element array.
8499        // assert cls.equals(Integer.TYPE);
8500        return new int[] { ((Integer)fieldObj).intValue() };
8501      }
8502    } else {
8503      // recursive case: more fields to access after this one
8504
8505      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
8506
8507        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
8508        int[] intermediate = new int[collection.size()];
8509        int index = 0;
8510        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
8511          Object obj = i.next();
8512          int[] oneEltArray = collectint(obj, fields, fieldsStartIdx + 1);
8513          if (oneEltArray == null) {
8514            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
8515          }
8516          // assert oneEltArray.length == 1;
8517          intermediate[index++] = oneEltArray[0];
8518        }
8519        return intermediate;
8520      } else if (fieldObj.getClass().isArray()) {
8521
8522        // collect elements across array
8523        int[] intermediate = new int[Array.getLength(fieldObj)];
8524        for (int i = 0 ; i < intermediate.length ; i++) {
8525          Object obj = Array.get(fieldObj, i);
8526          int[] oneEltArray = collectint(obj, fields, fieldsStartIdx + 1);
8527          if (oneEltArray == null) {
8528            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
8529          }
8530          // assert oneEltArray.length == 1;
8531          intermediate[i] = oneEltArray[0];
8532        }
8533        return intermediate;
8534      } else {
8535
8536        return collectint(fieldObj, fields, fieldsStartIdx + 1);
8537      }
8538    }
8539  }
8540
8541  /**
8542   * Returns the results of dereferencing the fields for 'object'. For example, the call
8543   *
8544   * <pre>collectint_field(x, "f.g.h")</pre>
8545   *
8546   * has the same value as
8547   *
8548   * <pre>x.f.g.h</pre>.
8549   * Returns a default value if any field access causes an exception.
8550   */
8551  @SideEffectFree
8552  public static int collectint_field(Object object, String fieldStr) {
8553
8554    if (object == null) {
8555      return Integer.MAX_VALUE; // return default value
8556    }
8557    if (fieldStr == null) {
8558      return Integer.MAX_VALUE; // return default value
8559    }
8560
8561    String[] fieldNames = fieldStr.split("\\.");
8562
8563    // Holds the intermediate (and final) result
8564    Object fieldObj = object;
8565
8566    for (int i = 0 ; i < fieldNames.length ; i++) {
8567
8568      String fieldName = fieldNames[i];
8569
8570      try {
8571        Field field =
8572          (fieldObj instanceof java.lang.Class<?>)
8573          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
8574          : fieldObj.getClass().getDeclaredField(fieldName);
8575        field.setAccessible(true);
8576        fieldObj = field.get(fieldObj);
8577
8578        if (fieldObj == null) {
8579          return Integer.MAX_VALUE; // return default value
8580        }
8581
8582      } catch (Exception e) {
8583        return Integer.MAX_VALUE; // return default value
8584
8585      }
8586
8587    }
8588
8589    return ((Integer)fieldObj).intValue();
8590  }
8591
8592  ///////////////////////////////////////////////////////////////////////////
8593  /// Methods for "long" (from QuantBody.java.jpp)
8594  ///
8595
8596  /**
8597   * Returns the ith element of the array or collection argument. If the argument is null or not an
8598   * array or collection, returns a default value (Long.MAX_VALUE).
8599   */
8600
8601  @Pure
8602  public static long getElement_long(Object o, long i) {
8603    if (o == null) {
8604      return Long.MAX_VALUE; // return default value
8605    }
8606    java.lang.Class<?> c = o.getClass();
8607    if (c.isArray()) {
8608      return java.lang.reflect.Array.getLong(o, (int)i);
8609    } else if (o instanceof java.util.AbstractCollection<?>) {
8610      return java.lang.reflect.Array.getLong(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
8611    } else {
8612      return Long.MAX_VALUE; // return default value
8613    }
8614  }
8615
8616  @Pure
8617  public static long getElement_long(long[] arr, long i) {
8618    if (arr == null) {
8619      return Long.MAX_VALUE; // return default value
8620    }
8621    return arr[(int)i];
8622  }
8623
8624  private static boolean eq(long x, long y) {
8625    return x == y;
8626  }
8627
8628  private static boolean ne(long x, long y) {
8629    return x != y;
8630  }
8631
8632  private static boolean lt(long x, long y) {
8633    return x < y;
8634  }
8635
8636  private static boolean lte(long x, long y) {
8637    return x <= y;
8638  }
8639
8640  private static boolean gt(long x, long y) {
8641    return x > y;
8642  }
8643
8644  private static boolean gte(long x, long y) {
8645    return x >= y;
8646  }
8647
8648  /** True iff both sequences are non-null and have the same length. */
8649  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
8650  @Pure
8651  public static boolean sameLength(long @Nullable [] seq1, long @Nullable [] seq2) {
8652    return ((seq1 != null)
8653            && (seq2 != null)
8654            && seq1.length == seq2.length);
8655  }
8656
8657  /** True iff both sequences are non-null and have the same length. */
8658  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
8659  @Pure
8660  public static boolean sameLength(long @Nullable [] seq1, int @Nullable [] seq2) {
8661    return ((seq1 != null)
8662            && (seq2 != null)
8663            && seq1.length == seq2.length);
8664  }
8665
8666  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
8667   *
8668   * Meaning (in pseudo-FOL):
8669   *
8670   * <pre>
8671   * /\ seq1.length == seq2.length
8672   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
8673   * </pre>
8674   *
8675   */
8676  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8677  @Pure
8678  public static boolean pairwiseDivides(long[] seq1, long[] seq2) {
8679    if (!sameLength(seq1, seq2)) {
8680      return false;
8681    }
8682    assert seq1 != null && seq2 != null; // because sameLength() = true
8683    for (int i = 0 ; i < seq1.length ; i++) {
8684      if (ne(seq1[i] % seq2[i], 0)) {
8685        return false;
8686      }
8687    }
8688    return true;
8689  }
8690  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8691  @Pure
8692  public static boolean pairwiseDivides(long[] seq1, int[] seq2) {
8693    if (!sameLength(seq1, seq2)) {
8694      return false;
8695    }
8696    assert seq1 != null && seq2 != null; // because sameLength() = true
8697    for (int i = 0 ; i < seq1.length ; i++) {
8698      if (ne(seq1[i] % seq2[i], 0)) {
8699        return false;
8700      }
8701    }
8702    return true;
8703  }
8704
8705  /**
8706   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
8707   *
8708   * Meaning (in pseudo-FOL):
8709   *
8710   * <pre>
8711   * /\ seq1.length == seq2.length
8712   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
8713   * </pre>
8714   *
8715   */
8716  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8717  @Pure
8718  public static boolean pairwiseSquare(long[] seq1, long[] seq2) {
8719    if (!sameLength(seq1, seq2)) {
8720      return false;
8721    }
8722    assert seq1 != null && seq2 != null; // because sameLength() = true
8723    for (int i = 0 ; i < seq1.length ; i++) {
8724      if (ne(seq1[i], seq2[i] * seq2[i])) {
8725        return false;
8726      }
8727    }
8728    return true;
8729  }
8730  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8731  @Pure
8732  public static boolean pairwiseSquare(long[] seq1, int[] seq2) {
8733    if (!sameLength(seq1, seq2)) {
8734      return false;
8735    }
8736    assert seq1 != null && seq2 != null; // because sameLength() = true
8737    for (int i = 0 ; i < seq1.length ; i++) {
8738
8739      if (ne(seq1[i], ((long) seq2[i]) * ((long) seq2[i]))) {
8740
8741        return false;
8742      }
8743    }
8744    return true;
8745  }
8746
8747  /** True iff both sequences have the same length, and all seq1[i] == ~ seq2[i].
8748   *
8749   * Meaning (in pseudo-FOL):
8750   *
8751   * <pre>
8752   * /\ seq1.length == seq2.length
8753   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == ~ seq2[i]
8754   * </pre>
8755   *
8756   */
8757  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8758  @Pure
8759  public static boolean pairwiseBitwiseComplement(long[] seq1, long[] seq2) {
8760    if (!sameLength(seq1, seq2)) {
8761      return false;
8762    }
8763    assert seq1 != null && seq2 != null; // because sameLength() = true
8764    for (int i = 0 ; i < seq1.length ; i++) {
8765      if (seq1[i] != ~seq2[i]) {
8766        return false;
8767      }
8768    }
8769    return true;
8770  }
8771  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8772  @Pure
8773  public static boolean pairwiseBitwiseComplement(long[] seq1, int[] seq2) {
8774    if (!sameLength(seq1, seq2)) {
8775      return false;
8776    }
8777    assert seq1 != null && seq2 != null; // because sameLength() = true
8778    for (int i = 0 ; i < seq1.length ; i++) {
8779      if (seq1[i] != ~seq2[i]) {
8780        return false;
8781      }
8782    }
8783    return true;
8784  }
8785
8786  /** True iff both sequences have the same length, and all seq1[i] == (seq2[i] | seq1[i]).
8787   *
8788   * Meaning (in pseudo-FOL):
8789   *
8790   * <pre>
8791   * /\ seq1.length == seq2.length
8792   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == (seq2[i] | seq1[i])
8793   * </pre>
8794   *
8795   */
8796  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8797  @Pure
8798  public static boolean pairwiseBitwiseSubset(long[] seq1, long[] seq2) {
8799    if (seq1 == null) {
8800      return false;
8801    }
8802    if (seq2 == null) {
8803      return false;
8804    }
8805    if (seq1.length != seq2.length) {
8806      return false;
8807    }
8808    for (int i = 0 ; i < seq1.length ; i++) {
8809      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
8810        return false;
8811      }
8812    }
8813    return true;
8814  }
8815  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8816  @Pure
8817  public static boolean pairwiseBitwiseSubset(long[] seq1, int[] seq2) {
8818    if (!sameLength(seq1, seq2)) {
8819      return false;
8820    }
8821    assert seq1 != null && seq2 != null; // because sameLength() = true
8822    for (int i = 0 ; i < seq1.length ; i++) {
8823      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
8824        return false;
8825      }
8826    }
8827    return true;
8828  }
8829
8830  /**
8831   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
8832   *
8833   * <p>If either array is null, returns null. If either array is empty, returns only those
8834   * elements in the other array. If both arrays are empty, returns a new empty array.
8835   */
8836  @SideEffectFree
8837  public static long @PolyNull [] concat(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8838    if (seq1 == null) {
8839      return null;
8840    }
8841    if (seq2 == null) {
8842      return null;
8843    }
8844    return ArraysPlume.concat(seq1, seq2);
8845  }
8846
8847  @SideEffectFree
8848  public static long @PolyNull [] concat(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8849    if (seq1 == null) {
8850      return null;
8851    }
8852    if (seq2 == null) {
8853      return null;
8854    }
8855    // Cannot just use ArraysPlume.concat because the two arrays
8856    // have different types.  This essentially inlines that method.
8857    int newLength = seq1.length + seq2.length;
8858    long[] retval = new long[newLength];
8859
8860    System.arraycopy(seq1, 0, retval, 0, seq1.length);
8861    for (int j = 0 ; j < seq2.length ; j++) {
8862      retval[seq1.length + j] = seq2[j];
8863    }
8864
8865    return retval;
8866  }
8867
8868  /**
8869   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
8870   * assurances about the order or repetition of elements: elements may be repeated, and their
8871   * order may be different from the order of elements in seq1 and seq2.
8872   */
8873  @SideEffectFree
8874  public static long @PolyNull [] union(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8875    if (seq1 == null) {
8876      return null;
8877    }
8878    if (seq2 == null) {
8879      return null;
8880    }
8881    return concat(seq1, seq2);
8882  }
8883
8884  @Pure
8885  public static long @PolyNull [] union(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8886    if (seq1 == null) {
8887      return null;
8888    }
8889    if (seq2 == null) {
8890      return null;
8891    }
8892    return concat(seq1, seq2);
8893  }
8894
8895  /**
8896   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
8897   * gives no assurances about the order or repetition of elements: elements may be repeated, and
8898   * their order may be different from the order of elements in seq1 and seq2.
8899   */
8900  @Pure
8901  public static long @PolyNull [] intersection(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8902    if (seq1 == null) {
8903      return null;
8904    }
8905    if (seq2 == null) {
8906      return null;
8907    }
8908    long[] intermediate = new long[Math.min(seq1.length, seq2.length)];
8909    int length = 0;
8910    for (int i = 0 ; i < seq1.length ; i++) {
8911      if (memberOf(seq1[i], seq2) ) {
8912        intermediate[length++] = seq1[i];
8913      }
8914    }
8915    return ArraysPlume.subarray(intermediate, 0, length);
8916  }
8917
8918  @Pure
8919  public static long @PolyNull [] intersection(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8920    if (seq1 == null) {
8921      return null;
8922    }
8923    if (seq2 == null) {
8924      return null;
8925    }
8926    long[] intermediate = new long[Math.min(seq1.length, seq2.length)];
8927    int length = 0;
8928    for (int i = 0 ; i < seq1.length ; i++) {
8929      if (memberOf(seq1[i], seq2) ) {
8930        intermediate[length++] = seq1[i];
8931      }
8932    }
8933    return ArraysPlume.subarray(intermediate, 0, length);
8934  }
8935
8936  /**
8937   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
8938   * no assurances about the order or repetition of elements: elements may be repeated, and their
8939   * order may be different from the order of elements in seq1 and seq2.
8940   */
8941  @Pure
8942  public static long @PolyNull [] setDiff(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8943    if (seq1 == null) {
8944      return null;
8945    }
8946    if (seq2 == null) {
8947      return null;
8948    }
8949    long[] intermediate = new long[seq1.length];
8950    int length = 0;
8951    for (int i = 0 ; i < seq1.length ; i++) {
8952      if (!memberOf(seq1[i], seq2)) {
8953        intermediate[length++] = seq1[i];
8954      }
8955    }
8956    return ArraysPlume.subarray(intermediate, 0, length);
8957  }
8958
8959  @Pure
8960  public static long @PolyNull [] setDiff(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8961    if (seq1 == null) {
8962      return null;
8963    }
8964    if (seq2 == null) {
8965      return null;
8966    }
8967    long[] intermediate = new long[seq1.length];
8968    int length = 0;
8969    for (int i = 0 ; i < seq1.length ; i++) {
8970      if (!memberOf(seq1[i], seq2)) {
8971        intermediate[length++] = seq1[i];
8972      }
8973    }
8974    return ArraysPlume.subarray(intermediate, 0, length);
8975  }
8976
8977  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
8978  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8979  @Pure
8980  public static boolean setEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
8981    if (seq1 == null) {
8982      return false;
8983    }
8984    if (seq2 == null) {
8985      return false;
8986    }
8987    for (int i = 0; i < seq1.length ; i++) {
8988      if (!memberOf(seq1[i], seq2) ) {
8989        return false;
8990      }
8991    }
8992    for (int i = 0; i < seq2.length ; i++) {
8993      if (!memberOf(seq2[i], seq1) ) {
8994        return false;
8995      }
8996    }
8997    return true;
8998  }
8999
9000  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9001  @Pure
9002  public static boolean setEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9003    if (seq1 == null) {
9004      return false;
9005    }
9006    if (seq2 == null) {
9007      return false;
9008    }
9009    for (int i = 0; i < seq1.length ; i++) {
9010      if (!memberOf(seq1[i], seq2) ) {
9011        return false;
9012      }
9013    }
9014    for (int i = 0; i < seq2.length ; i++) {
9015      if (!memberOf(seq2[i], seq1) ) {
9016        return false;
9017      }
9018    }
9019    return true;
9020  }
9021
9022  /** True iff seq1 is the reverse of seq2.
9023   *
9024   * Meaning (in pseudo-FOL):
9025   *
9026   * <pre>
9027   * /\ seq1.length == seq2.length
9028   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
9029   * </pre>
9030   *
9031   */
9032  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9033  @Pure
9034  public static boolean isReverse(long[] seq1, long[] seq2) {
9035    if (!sameLength(seq1, seq2)) {
9036      return false;
9037    }
9038    assert seq1 != null && seq2 != null; // because sameLength() = true
9039    int length = seq1.length;
9040    for (int i = 0 ; i < length ; i++) {
9041      if (ne(seq1[i], seq2[length - i - 1])) {
9042        return false;
9043      }
9044    }
9045    return true;
9046  }
9047
9048  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9049  @Pure
9050  public static boolean isReverse(long @Nullable [] seq1, int @Nullable [] seq2) {
9051    if (!sameLength(seq1, seq2)) {
9052      return false;
9053    }
9054    assert seq1 != null && seq2 != null; // because sameLength() = true
9055    int length = seq1.length;
9056    for (int i = 0 ; i < length ; i++) {
9057      if (ne(seq1[i], seq2[length - i - 1])) {
9058        return false;
9059      }
9060    }
9061    return true;
9062  }
9063
9064  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
9065  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9066  @Pure
9067  public static boolean subsetOf(long @Nullable [] seq1, long @Nullable [] seq2) {
9068    if (seq1 == null) {
9069      return false;
9070    }
9071    if (seq2 == null) {
9072      return false;
9073    }
9074    for (int i = 0 ; i < seq1.length ; i++) {
9075      if (!memberOf(seq1[i], seq2)) {
9076        return false;
9077      }
9078    }
9079    return true;
9080  }
9081
9082  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9083  @Pure
9084  public static boolean subsetOf(long @Nullable [] seq1, int @Nullable [] seq2) {
9085    if (seq1 == null) {
9086      return false;
9087    }
9088    if (seq2 == null) {
9089      return false;
9090    }
9091    for (int i = 0 ; i < seq1.length ; i++) {
9092      if (!memberOf(seq1[i], seq2)) {
9093        return false;
9094      }
9095    }
9096    return true;
9097  }
9098
9099  /** Returns true iff seq contains no duplicate elements. */
9100  @EnsuresNonNullIf(result=true, expression="#1")
9101  @Pure
9102  public static boolean noDups(long @Nullable [] seq) {
9103    if (seq == null) {
9104      return false;
9105    }
9106    return ArraysPlume.noDuplicates(seq);
9107  }
9108
9109 /** Returns true iff elt is in array arr. */
9110  @EnsuresNonNullIf(result=true, expression="#2")
9111  @Pure
9112  public static boolean memberOf(long elt, long @Nullable [] arr) {
9113    if (arr == null) {
9114      return false;
9115    }
9116    for (int i = 0 ; i < arr.length ; i++) {
9117      if (eq(arr[i], elt)) {
9118        return true;
9119      }
9120    }
9121    return false;
9122  }
9123
9124  @EnsuresNonNullIf(result=true, expression="#2")
9125  @Pure
9126  public static boolean memberOf(long elt, int @Nullable [] arr) {
9127    if (arr == null) {
9128      return false;
9129    }
9130    for (int i = 0 ; i < arr.length ; i++) {
9131      if (eq(arr[i], elt)) {
9132        return true;
9133      }
9134    }
9135    return false;
9136  }
9137
9138  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
9139  @Pure
9140  public static long @PolyNull [] slice(long @PolyNull [] seq, int start, int end) {
9141    if (seq == null) {
9142      return null;
9143    }
9144    int sliceStart = start;
9145    int sliceEnd = end;
9146    if (start < 0) {
9147      return new long[] { };
9148    }
9149    if (end > seq.length - 1) {
9150      return new long[] { };
9151    }
9152    if (sliceStart > sliceEnd) {
9153      return new long[] { };
9154    }
9155    int length = sliceEnd - sliceStart + 1;
9156    return ArraysPlume.subarray(seq, sliceStart, length);
9157  }
9158
9159  @Pure
9160  public static long @PolyNull [] slice(long @PolyNull [] seq, long start, int end) {
9161    return slice(seq, (int)start, end);
9162  }
9163  @Pure
9164  public static long @PolyNull [] slice(long @PolyNull [] seq, int start, long end) {
9165    return slice(seq, start, (int)end);
9166  }
9167  @Pure
9168  public static long @PolyNull [] slice(long @PolyNull [] seq, long start, long end) {
9169    return slice(seq, (int)start, (int)end);
9170  }
9171
9172  /** True iff all elements in arr equal elt.
9173   *
9174   * Meaning (in pseudo-FOL):
9175   *
9176   * forall i in { 0..arr.length-1 } : arr[i] == elt
9177   *
9178   */
9179  @EnsuresNonNullIf(result=true, expression="#1")
9180  @Pure
9181  public static boolean eltsEqual(long @Nullable [] arr, long elt) {
9182    if (arr == null) {
9183      return false;
9184    }
9185    for (int i = 0 ; i < arr.length ; i++) {
9186      if (ne(arr[i], elt)) {
9187        return false;
9188      }
9189    }
9190    return true;
9191  }
9192
9193  @EnsuresNonNullIf(result=true, expression="#1")
9194  @Pure
9195  public static boolean eltsEqual(long @Nullable [] arr, int elt) {
9196    if (arr == null) {
9197      return false;
9198    }
9199    for (int i = 0 ; i < arr.length ; i++) {
9200      if (ne(arr[i], elt)) {
9201        return false;
9202      }
9203    }
9204    return true;
9205  }
9206
9207  /** True iff every element in arr does not equal elt.
9208   *
9209   * Meaning (in pseudo-FOL):
9210   *
9211   * forall i in { 0..arr.length-1 } : arr[i] != elt
9212   *
9213   */
9214  @EnsuresNonNullIf(result=true, expression="#1")
9215  @Pure
9216  public static boolean eltsNotEqual(long @Nullable [] arr, long elt) {
9217    if (arr == null) {
9218      return false;
9219    }
9220    for (int i = 0 ; i < arr.length ; i++) {
9221      if (eq(arr[i], elt)) {
9222        return false;
9223      }
9224    }
9225    return true;
9226  }
9227
9228  @EnsuresNonNullIf(result=true, expression="#1")
9229  @Pure
9230  public static boolean eltsNotEqual(long @Nullable [] arr, int elt) {
9231    if (arr == null) {
9232      return false;
9233    }
9234    for (int i = 0 ; i < arr.length ; i++) {
9235      if (eq(arr[i], elt)) {
9236        return false;
9237      }
9238    }
9239    return true;
9240  }
9241
9242  /** True iff every element in arr is greater than elt.
9243   *
9244   * Meaning (in pseudo-FOL):
9245   *
9246   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
9247   *
9248   */
9249  @EnsuresNonNullIf(result=true, expression="#1")
9250  @Pure
9251  public static boolean eltsGT(long @Nullable [] arr, long elt) {
9252    if (arr == null) {
9253      return false;
9254    }
9255    for (int i = 0 ; i < arr.length ; i++) {
9256      if (lte(arr[i], elt)) {
9257        return false;
9258      }
9259    }
9260    return true;
9261  }
9262
9263  @EnsuresNonNullIf(result=true, expression="#1")
9264  @Pure
9265  public static boolean eltsGT(long @Nullable [] arr, int elt) {
9266    if (arr == null) {
9267      return false;
9268    }
9269    for (int i = 0 ; i < arr.length ; i++) {
9270      if (lte(arr[i], elt)) {
9271        return false;
9272      }
9273    }
9274    return true;
9275  }
9276
9277  /** True iff every element in arr is greater than or equal to elt.
9278   *
9279   * Meaning (in pseudo-FOL):
9280   *
9281   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
9282   *
9283   */
9284  @EnsuresNonNullIf(result=true, expression="#1")
9285  @Pure
9286  public static boolean eltsGTE(long @Nullable [] arr, long elt) {
9287    if (arr == null) {
9288      return false;
9289    }
9290    for (int i = 0 ; i < arr.length ; i++) {
9291      if (lt(arr[i], elt)) {
9292        return false;
9293      }
9294    }
9295    return true;
9296  }
9297
9298  @EnsuresNonNullIf(result=true, expression="#1")
9299  @Pure
9300  public static boolean eltsGTE(long @Nullable [] arr, int elt) {
9301    if (arr == null) {
9302      return false;
9303    }
9304    for (int i = 0 ; i < arr.length ; i++) {
9305      if (lt(arr[i], elt)) {
9306        return false;
9307      }
9308    }
9309    return true;
9310  }
9311
9312  /** True iff every element in arr is less than elt.
9313   *
9314   * Meaning (in pseudo-FOL):
9315   *
9316   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
9317   *
9318   */
9319  @EnsuresNonNullIf(result=true, expression="#1")
9320  @Pure
9321  public static boolean eltsLT(long @Nullable [] arr, long elt) {
9322    if (arr == null) {
9323      return false;
9324    }
9325    for (int i = 0 ; i < arr.length ; i++) {
9326      if (gte(arr[i], elt)) {
9327        return false;
9328      }
9329    }
9330    return true;
9331  }
9332
9333  @EnsuresNonNullIf(result=true, expression="#1")
9334  @Pure
9335  public static boolean eltsLT(long @Nullable [] arr, int elt) {
9336    if (arr == null) {
9337      return false;
9338    }
9339    for (int i = 0 ; i < arr.length ; i++) {
9340      if (gte(arr[i], elt)) {
9341        return false;
9342      }
9343    }
9344    return true;
9345  }
9346
9347  /** True iff every element in arr is less than or equal to elt.
9348   *
9349   * Meaning (in pseudo-FOL):
9350   *
9351   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
9352   *
9353   */
9354  @EnsuresNonNullIf(result=true, expression="#1")
9355  @Pure
9356  public static boolean eltsLTE(long @Nullable [] arr, long elt) {
9357    if (arr == null) {
9358      return false;
9359    }
9360    for (int i = 0 ; i < arr.length ; i++) {
9361      if (gt(arr[i], elt)) {
9362        return false;
9363      }
9364    }
9365    return true;
9366  }
9367
9368  @EnsuresNonNullIf(result=true, expression="#1")
9369  @Pure
9370  public static boolean eltsLTE(long @Nullable [] arr, int elt) {
9371    if (arr == null) {
9372      return false;
9373    }
9374    for (int i = 0 ; i < arr.length ; i++) {
9375      if (gt(arr[i], elt)) {
9376        return false;
9377      }
9378    }
9379    return true;
9380  }
9381
9382  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
9383   *
9384   * Meaning (in pseudo-FOL):
9385   *
9386   * /\ seq1.length == se2.length
9387   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
9388   *
9389   */
9390
9391  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9392  @Pure
9393  public static boolean pairwiseEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9394    if (!sameLength(seq1, seq2)) {
9395      return false;
9396    }
9397    assert seq1 != null && seq2 != null; // because sameLength() = true
9398    for (int i = 0 ; i < seq1.length ; i++) {
9399      if (ne(seq1[i], seq2[i])) {
9400        return false;
9401      }
9402    }
9403    return true;
9404  }
9405
9406  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9407  @Pure
9408  public static boolean pairwiseEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9409    if (!sameLength(seq1, seq2)) {
9410      return false;
9411    }
9412    assert seq1 != null && seq2 != null; // because sameLength() = true
9413    for (int i = 0 ; i < seq1.length ; i++) {
9414      if (ne(seq1[i], seq2[i])) {
9415        return false;
9416      }
9417    }
9418    return true;
9419  }
9420
9421  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
9422   *
9423   * Meaning (in pseudo-FOL):
9424   *
9425   * /\ seq1.length == se2.length
9426   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
9427   *
9428   */
9429  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9430  @Pure
9431  public static boolean pairwiseNotEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9432    if (!sameLength(seq1, seq2)) {
9433      return false;
9434    }
9435    assert seq1 != null && seq2 != null; // because sameLength() = true
9436    for (int i = 0 ; i < seq1.length ; i++) {
9437      if (eq(seq1[i], seq2[i])) {
9438        return false;
9439      }
9440    }
9441    return true;
9442  }
9443
9444  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9445  @Pure
9446  public static boolean pairwiseNotEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9447    if (!sameLength(seq1, seq2)) {
9448      return false;
9449    }
9450    assert seq1 != null && seq2 != null; // because sameLength() = true
9451    for (int i = 0 ; i < seq1.length ; i++) {
9452      if (eq(seq1[i], seq2[i])) {
9453        return false;
9454      }
9455    }
9456    return true;
9457  }
9458
9459  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
9460   *
9461   * Meaning (in pseudo-FOL):
9462   *
9463   * /\ seq1.length == se2.length
9464   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
9465   *
9466   */
9467  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9468  @Pure
9469  public static boolean pairwiseLT(long @Nullable [] seq1, long @Nullable [] seq2) {
9470    if (!sameLength(seq1, seq2)) {
9471      return false;
9472    }
9473    assert seq1 != null && seq2 != null; // because sameLength() = true
9474    for (int i = 0 ; i < seq1.length ; i++) {
9475      if (gte(seq1[i], seq2[i])) {
9476        return false;
9477      }
9478    }
9479    return true;
9480  }
9481
9482  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9483  @Pure
9484  public static boolean pairwiseLT(long @Nullable [] seq1, int @Nullable [] seq2) {
9485    if (!sameLength(seq1, seq2)) {
9486      return false;
9487    }
9488    assert seq1 != null && seq2 != null; // because sameLength() = true
9489    for (int i = 0 ; i < seq1.length ; i++) {
9490      if (gte(seq1[i], seq2[i])) {
9491        return false;
9492      }
9493    }
9494    return true;
9495  }
9496
9497  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
9498   * Meaning (in pseudo-FOL):
9499   *
9500   * /\ seq1.length == se2.length
9501   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
9502   *
9503   */
9504  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9505  @Pure
9506  public static boolean pairwiseLTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9507    if (!sameLength(seq1, seq2)) {
9508      return false;
9509    }
9510    assert seq1 != null && seq2 != null; // because sameLength() = true
9511    for (int i = 0 ; i < seq1.length ; i++) {
9512      if (gt(seq1[i], seq2[i])) {
9513        return false;
9514      }
9515    }
9516    return true;
9517  }
9518
9519  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9520  @Pure
9521  public static boolean pairwiseLTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9522    if (!sameLength(seq1, seq2)) {
9523      return false;
9524    }
9525    assert seq1 != null && seq2 != null; // because sameLength() = true
9526    for (int i = 0 ; i < seq1.length ; i++) {
9527      if (gt(seq1[i], seq2[i])) {
9528        return false;
9529      }
9530    }
9531    return true;
9532  }
9533
9534  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
9535   * Meaning (in pseudo-FOL):
9536   *
9537   * /\ seq1.length == se2.length
9538   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
9539   *
9540   */
9541  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9542  @Pure
9543  public static boolean pairwiseGT(long @Nullable [] seq1, long @Nullable [] seq2) {
9544    if (!sameLength(seq1, seq2)) {
9545      return false;
9546    }
9547    assert seq1 != null && seq2 != null; // because sameLength() = true
9548    for (int i = 0 ; i < seq1.length ; i++) {
9549      if (lte(seq1[i], seq2[i])) {
9550        return false;
9551      }
9552    }
9553    return true;
9554  }
9555
9556  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9557  @Pure
9558  public static boolean pairwiseGT(long @Nullable [] seq1, int @Nullable [] seq2) {
9559    if (!sameLength(seq1, seq2)) {
9560      return false;
9561    }
9562    assert seq1 != null && seq2 != null; // because sameLength() = true
9563    for (int i = 0 ; i < seq1.length ; i++) {
9564      if (lte(seq1[i], seq2[i])) {
9565        return false;
9566      }
9567    }
9568    return true;
9569  }
9570
9571  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
9572   * Meaning (in pseudo-FOL):
9573   *
9574   * /\ seq1.length == se2.length
9575   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
9576   *
9577   */
9578  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9579  @Pure
9580  public static boolean pairwiseGTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9581    if (!sameLength(seq1, seq2)) {
9582      return false;
9583    }
9584    assert seq1 != null && seq2 != null; // because sameLength() = true
9585    for (int i = 0 ; i < seq1.length ; i++) {
9586      if (lt(seq1[i], seq2[i])) {
9587        return false;
9588      }
9589    }
9590    return true;
9591  }
9592
9593  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9594  @Pure
9595  public static boolean pairwiseGTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9596    if (!sameLength(seq1, seq2)) {
9597      return false;
9598    }
9599    assert seq1 != null && seq2 != null; // because sameLength() = true
9600    for (int i = 0 ; i < seq1.length ; i++) {
9601      if (lt(seq1[i], seq2[i])) {
9602        return false;
9603      }
9604    }
9605    return true;
9606  }
9607
9608  /**
9609   * Returns true iff seq1 is lexically equal to seq2.
9610   * For equality, "lexically" and "pairwise" are the same.
9611   */
9612  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9613  @Pure
9614  public static boolean lexEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9615    if (seq1 == null) {
9616      return false;
9617    }
9618    if (seq2 == null) {
9619      return false;
9620    }
9621    return pairwiseEqual(seq1, seq2);
9622  }
9623
9624  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9625  @Pure
9626  public static boolean lexEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9627    if (seq1 == null) {
9628      return false;
9629    }
9630    if (seq2 == null) {
9631      return false;
9632    }
9633    return pairwiseEqual(seq1, seq2);
9634  }
9635
9636  /** Returns true iff seq1 is lexically not equal to seq2. */
9637  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9638  @Pure
9639  public static boolean lexNotEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9640    if (seq1 == null) {
9641      return false;
9642    }
9643    if (seq2 == null) {
9644      return false;
9645    }
9646    return !lexEqual(seq1, seq2);
9647  }
9648
9649  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9650  @Pure
9651  public static boolean lexNotEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9652    if (seq1 == null) {
9653      return false;
9654    }
9655    if (seq2 == null) {
9656      return false;
9657    }
9658    return !lexEqual(seq1, seq2);
9659  }
9660
9661  /** Returns true iff seq1 is lexically &lt;  seq2. */
9662  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9663  @Pure
9664  public static boolean lexLT(long @Nullable [] seq1, long @Nullable [] seq2) {
9665    if (seq1 == null) {
9666      return false;
9667    }
9668    if (seq2 == null) {
9669      return false;
9670    }
9671    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9672    for (int i = 0 ; i < minlength ; i++) {
9673      if (gt(seq1[i], seq2[i])) {
9674        return false;
9675      } else if (lt(seq1[i], seq2[i])) {
9676        return true;
9677      }
9678    }
9679    if (seq1.length >= seq2.length) {
9680      return false;
9681    }
9682    return true;
9683  }
9684
9685  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9686  @Pure
9687  public static boolean lexLT(long @Nullable [] seq1, int @Nullable [] seq2) {
9688    if (seq1 == null) {
9689      return false;
9690    }
9691    if (seq2 == null) {
9692      return false;
9693    }
9694    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9695    for (int i = 0 ; i < minlength ; i++) {
9696      if (gt(seq1[i], seq2[i])) {
9697        return false;
9698        } else if (lt(seq1[i], seq2[i])) {
9699          return true;
9700        }
9701      }
9702      if (seq1.length >= seq2.length) {
9703        return false;
9704      }
9705      return true;
9706    }
9707
9708  /** Returns true iff seq1 is lexically &le; to seq2. */
9709  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9710  @Pure
9711  public static boolean lexLTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9712    if (seq1 == null) {
9713      return false;
9714    }
9715    if (seq2 == null) {
9716      return false;
9717    }
9718    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9719    for (int i = 0 ; i < minlength ; i++) {
9720      if (gt(seq1[i], seq2[i])) {
9721        return false;
9722      } else if (lt(seq1[i], seq2[i])) {
9723        return true;
9724      }
9725    }
9726    if (seq1.length > seq2.length) {
9727      return false;
9728    }
9729    return true;
9730  }
9731
9732  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9733  @Pure
9734  public static boolean lexLTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9735  if (seq1 == null) {
9736    return false;
9737  }
9738  if (seq2 == null) {
9739    return false;
9740  }
9741    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9742    for (int i = 0 ; i < minlength ; i++) {
9743      if (gt(seq1[i], seq2[i])) {
9744        return false;
9745      } else if (lt(seq1[i], seq2[i])) {
9746        return true;
9747      }
9748    }
9749    if (seq1.length > seq2.length) {
9750      return false;
9751    }
9752    return true;
9753  }
9754
9755  /** Returns true iff seq1 is lexically &gt; to seq2. */
9756  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9757  @Pure
9758  public static boolean lexGT(long @Nullable [] seq1, long @Nullable [] seq2) {
9759  if (seq1 == null) {
9760    return false;
9761  }
9762  if (seq2 == null) {
9763    return false;
9764  }
9765    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9766    for (int i = 0 ; i < minlength ; i++) {
9767      if (lt(seq1[i], seq2[i])) {
9768        return false;
9769      } else if (gt(seq1[i], seq2[i])) {
9770        return true;
9771      }
9772    }
9773    if (seq1.length <= seq2.length) {
9774      return false;
9775    }
9776    return true;
9777  }
9778
9779  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9780  @Pure
9781  public static boolean lexGT(long @Nullable [] seq1, int @Nullable [] seq2) {
9782  if (seq1 == null) {
9783    return false;
9784  }
9785  if (seq2 == null) {
9786    return false;
9787  }
9788    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9789    for (int i = 0 ; i < minlength ; i++) {
9790      if (lt(seq1[i], seq2[i])) {
9791        return false;
9792      } else if (gt(seq1[i], seq2[i])) {
9793        return true;
9794      }
9795    }
9796    if (seq1.length <= seq2.length) {
9797      return false;
9798    }
9799    return true;
9800  }
9801
9802  /** Returns true iff seq1 is lexically &ge; to seq2. */
9803  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9804  @Pure
9805  public static boolean lexGTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9806  if (seq1 == null) {
9807    return false;
9808  }
9809  if (seq2 == null) {
9810    return false;
9811  }
9812    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9813    for (int i = 0 ; i < minlength ; i++) {
9814      if (lt(seq1[i], seq2[i])) {
9815        return false;
9816      } else if (gt(seq1[i], seq2[i])) {
9817        return true;
9818      }
9819    }
9820    if (seq1.length < seq2.length) {
9821      return false;
9822    }
9823    return true;
9824  }
9825
9826  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9827  @Pure
9828  public static boolean lexGTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9829  if (seq1 == null) {
9830    return false;
9831  }
9832  if (seq2 == null) {
9833    return false;
9834  }
9835    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9836    for (int i = 0 ; i < minlength ; i++) {
9837      if (lt(seq1[i], seq2[i])) {
9838        return false;
9839      } else if (gt(seq1[i], seq2[i])) {
9840        return true;
9841      }
9842    }
9843    if (seq1.length < seq2.length) {
9844      return false;
9845    }
9846    return true;
9847  }
9848
9849  /** True iff for all applicable i, every seq[i] == seq[i+1].
9850   *
9851   * Meaning (in pseudo-FOL):
9852   *
9853   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
9854   *
9855   */
9856  @EnsuresNonNullIf(result=true, expression="#1")
9857  @Pure
9858  public static boolean eltwiseEqual(long @Nullable [] seq) {
9859  if (seq == null) {
9860    return false;
9861  }
9862    for (int i = 0 ; i < seq.length ; i++) {
9863      if (i < seq.length - 1) {
9864        if (ne(seq[i], seq[i + 1])) {
9865          return false;
9866        }
9867      }
9868    }
9869    return true;
9870  }
9871
9872  /** True iff for all applicable i, every seq[i] != seq[i+1].
9873   *
9874   * Meaning (in pseudo-FOL):
9875   *
9876   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
9877   *
9878   */
9879  @EnsuresNonNullIf(result=true, expression="#1")
9880  @Pure
9881  public static boolean eltwiseNotEqual(long @Nullable [] seq) {
9882  if (seq == null) {
9883    return false;
9884  }
9885    for (int i = 0 ; i < seq.length ; i++) {
9886      if (i < seq.length - 1) {
9887        if (eq(seq[i], seq[i + 1])) {
9888          return false;
9889        }
9890      }
9891    }
9892    return true;
9893  }
9894
9895  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
9896   *
9897   * Meaning (in pseudo-FOL):
9898   *
9899   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
9900   *
9901   */
9902  @EnsuresNonNullIf(result=true, expression="#1")
9903  @Pure
9904  public static boolean eltwiseLT(long @Nullable [] seq) {
9905  if (seq == null) {
9906    return false;
9907  }
9908    for (int i = 0 ; i < seq.length ; i++) {
9909      if (i < seq.length - 1) {
9910        if (gte(seq[i], seq[i + 1])) {
9911          return false;
9912        }
9913      }
9914    }
9915    return true;
9916  }
9917
9918  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
9919   *
9920   * Meaning (in pseudo-FOL):
9921   *
9922   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
9923   *
9924   */
9925  @EnsuresNonNullIf(result=true, expression="#1")
9926  @Pure
9927  public static boolean eltwiseLTE(long @Nullable [] seq) {
9928  if (seq == null) {
9929    return false;
9930  }
9931    for (int i = 0 ; i < seq.length ; i++) {
9932      if (i < seq.length - 1) {
9933        if (gt(seq[i], seq[i + 1])) {
9934          return false;
9935        }
9936      }
9937    }
9938    return true;
9939  }
9940
9941  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
9942   *
9943   * Meaning (in pseudo-FOL):
9944   *
9945   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
9946   *
9947   */
9948  @EnsuresNonNullIf(result=true, expression="#1")
9949  @Pure
9950  public static boolean eltwiseGT(long @Nullable [] seq) {
9951  if (seq == null) {
9952    return false;
9953  }
9954    for (int i = 0 ; i < seq.length ; i++) {
9955      if (i < seq.length - 1) {
9956        if (lte(seq[i], seq[i + 1])) {
9957          return false;
9958        }
9959      }
9960    }
9961    return true;
9962  }
9963
9964  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
9965   *
9966   * Meaning (in pseudo-FOL):
9967   *
9968   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
9969   *
9970   */
9971  @EnsuresNonNullIf(result=true, expression="#1")
9972  @Pure
9973  public static boolean eltwiseGTE(long @Nullable [] seq) {
9974  if (seq == null) {
9975    return false;
9976  }
9977    for (int i = 0 ; i < seq.length ; i++) {
9978      if (i < seq.length - 1) {
9979        if (lt(seq[i], seq[i + 1])) {
9980          return false;
9981        }
9982      }
9983    }
9984    return true;
9985  }
9986
9987  /** True iff for all applicable i, every seq[i] == i.
9988   *
9989   * Meaning (in pseudo-FOL):
9990   *
9991   * forall i in { 0..seq.length-1 } : seq[i] == i
9992   *
9993   */
9994  @EnsuresNonNullIf(result=true, expression="#1")
9995  @Pure
9996  public static boolean eltsEqualIndex(long @Nullable [] seq) {
9997  if (seq == null) {
9998    return false;
9999  }
10000    for (int i = 0 ; i < seq.length ; i++) {
10001      if (ne(seq[i], i)) {
10002        return false;
10003      }
10004    }
10005    return true;
10006  }
10007
10008  /** True iff for all applicable i, every seq[i] != i.
10009   *
10010   * Meaning (in pseudo-FOL):
10011   *
10012   * forall i in { 0..seq.length-1 } : seq[i] != i
10013   *
10014   */
10015  @EnsuresNonNullIf(result=true, expression="#1")
10016  @Pure
10017  public static boolean eltsNotEqualIndex(long @Nullable [] seq) {
10018  if (seq == null) {
10019    return false;
10020  }
10021    for (int i = 0 ; i < seq.length ; i++) {
10022      if (eq(seq[i], i)) {
10023        return false;
10024      }
10025    }
10026    return true;
10027  }
10028
10029  /** True iff for all applicable i, every seq[i] &lt; i.
10030   *
10031   * Meaning (in pseudo-FOL):
10032   *
10033   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
10034   *
10035   */
10036  @EnsuresNonNullIf(result=true, expression="#1")
10037  @Pure
10038  public static boolean eltsLtIndex(long @Nullable [] seq) {
10039  if (seq == null) {
10040    return false;
10041  }
10042    for (int i = 0 ; i < seq.length ; i++) {
10043      if (gte(seq[i], i)) {
10044        return false;
10045      }
10046    }
10047    return true;
10048  }
10049
10050  /** True iff for all applicable i, every seq[i] &le; i.
10051   *
10052   * Meaning (in pseudo-FOL):
10053   *
10054   * forall i in { 0..seq.length-1 } : seq[i] &le; i
10055   *
10056   */
10057  @EnsuresNonNullIf(result=true, expression="#1")
10058  @Pure
10059  public static boolean eltsLteIndex(long @Nullable [] seq) {
10060  if (seq == null) {
10061    return false;
10062  }
10063    for (int i = 0 ; i < seq.length ; i++) {
10064      if (gt(seq[i], i)) {
10065        return false;
10066      }
10067    }
10068    return true;
10069  }
10070
10071  /** True iff for all applicable i, every seq[i] &gt; i.
10072   *
10073   * Meaning (in pseudo-FOL):
10074   *
10075   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
10076   *
10077   */
10078  @EnsuresNonNullIf(result=true, expression="#1")
10079  @Pure
10080  public static boolean eltsGtIndex(long @Nullable [] seq) {
10081  if (seq == null) {
10082    return false;
10083  }
10084    for (int i = 0 ; i < seq.length ; i++) {
10085      if (lte(seq[i], i)) {
10086        return false;
10087      }
10088    }
10089    return true;
10090  }
10091
10092  /** True iff for all applicable i, every seq[i] &ge; i.
10093   *
10094   * Meaning (in pseudo-FOL):
10095   *
10096   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
10097   *
10098   */
10099  @EnsuresNonNullIf(result=true, expression="#1")
10100  @Pure
10101  public static boolean eltsGteIndex(long @Nullable [] seq) {
10102  if (seq == null) {
10103    return false;
10104  }
10105    for (int i = 0 ; i < seq.length ; i++) {
10106      if (lt(seq[i], i)) {
10107        return false;
10108      }
10109    }
10110    return true;
10111  }
10112
10113  /// Deferencing (accessing) fields
10114
10115  /**
10116   * collectlong accepts an object and a list of fields (one of which is of array type, and the
10117   * rest of which are not), and produces an array in which the original object has had the given
10118   * fields accessed.
10119   *
10120   * <p>Daikon creates invariants over "variables" such as the following.
10121   *
10122   * <dl>
10123   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
10124   *              for all y's in array x.arr.</dd>
10125   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
10126   *              for all x's in array arr.</dd>
10127   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
10128   * </dl>
10129   *
10130   * <p>The collectlong() method does this collecting work.
10131   *
10132   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
10133   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
10134   * elements that result from following the fields, one of which is assumed to be an array.
10135   *
10136   * <p>
10137   * requires: fieldStr.length() &gt; 0 and object != null
10138   * <p>
10139   * requires: fieldStr contains only field names, no "[]" strings.
10140   * <p>
10141   * requires: the method only works for field sequences with exactly one field representing an
10142   * array. For example, the collection a[].b[].c will fail.
10143   *
10144   * @return if the resulting collection is of non-primitive type, then returns an array of type
10145   * Object[]. Returns null if any array or field access causes an exception.
10146   */
10147
10148  @SideEffectFree
10149  public static long @Nullable [] collectlong(@Nullable Object object, @Nullable String fieldStr) {
10150
10151    if (object == null) {
10152      return null;
10153    }
10154    if (fieldStr == null) {
10155      return null;
10156    }
10157
10158    // assert fieldStr != null && !"".equals(fieldStr);
10159    String[] fieldNames = fieldStr.split("\\.");
10160    long[] retval = collectlong(object, fieldNames, 0);
10161    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
10162    return retval;
10163  }
10164
10165  /** Helper method for collectlong(Object, String).
10166   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
10167   * @see collectlong(Object, String)
10168   */
10169  // @PolyNull does not work for return type, because null is returned on error.
10170  @SideEffectFree
10171  private static long @Nullable [] collectlong(@Nullable Object object,
10172                                                   String[] fields, int fieldsStartIdx) {
10173
10174    if (object == null) {
10175      return null;
10176    }
10177    assert (fields != null);
10178    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
10179
10180    Object fieldObj;
10181    try {
10182      Field field = (object instanceof java.lang.Class<?>)
10183        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
10184        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
10185      field.setAccessible(true);
10186      // Class cls = field.getType();
10187      fieldObj = field.get(object);
10188      // System.out.println("***fieldObj="+fieldObj);
10189
10190    } catch (Exception e) {
10191      return null;
10192
10193    }
10194
10195    if (fieldObj == null) {
10196      return null;
10197    }
10198
10199    // base case: just accessed the last field
10200    if (fields.length - 1 == fieldsStartIdx) {
10201
10202      if (fieldObj.getClass().isArray()) {
10203        // last field is an array
10204        return (long[])fieldObj;
10205      } else {
10206        // This hack should be removed in favor of, at "oneEltArray = ..."
10207        // below, calling a version of collectlong_field that throws an
10208        // error.  Then, this case becomes a run-time error.  -MDE
10209
10210        // Just one element; return a one-element array.
10211        // assert cls.equals(Long.TYPE);
10212        return new long[] { ((Long)fieldObj).longValue() };
10213      }
10214    } else {
10215      // recursive case: more fields to access after this one
10216
10217      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
10218
10219        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
10220        long[] intermediate = new long[collection.size()];
10221        int index = 0;
10222        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
10223          Object obj = i.next();
10224          long[] oneEltArray = collectlong(obj, fields, fieldsStartIdx + 1);
10225          if (oneEltArray == null) {
10226            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
10227          }
10228          // assert oneEltArray.length == 1;
10229          intermediate[index++] = oneEltArray[0];
10230        }
10231        return intermediate;
10232      } else if (fieldObj.getClass().isArray()) {
10233
10234        // collect elements across array
10235        long[] intermediate = new long[Array.getLength(fieldObj)];
10236        for (int i = 0 ; i < intermediate.length ; i++) {
10237          Object obj = Array.get(fieldObj, i);
10238          long[] oneEltArray = collectlong(obj, fields, fieldsStartIdx + 1);
10239          if (oneEltArray == null) {
10240            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
10241          }
10242          // assert oneEltArray.length == 1;
10243          intermediate[i] = oneEltArray[0];
10244        }
10245        return intermediate;
10246      } else {
10247
10248        return collectlong(fieldObj, fields, fieldsStartIdx + 1);
10249      }
10250    }
10251  }
10252
10253  /**
10254   * Returns the results of dereferencing the fields for 'object'. For example, the call
10255   *
10256   * <pre>collectlong_field(x, "f.g.h")</pre>
10257   *
10258   * has the same value as
10259   *
10260   * <pre>x.f.g.h</pre>.
10261   * Returns a default value if any field access causes an exception.
10262   */
10263  @SideEffectFree
10264  public static long collectlong_field(Object object, String fieldStr) {
10265
10266    if (object == null) {
10267      return Long.MAX_VALUE; // return default value
10268    }
10269    if (fieldStr == null) {
10270      return Long.MAX_VALUE; // return default value
10271    }
10272
10273    String[] fieldNames = fieldStr.split("\\.");
10274
10275    // Holds the intermediate (and final) result
10276    Object fieldObj = object;
10277
10278    for (int i = 0 ; i < fieldNames.length ; i++) {
10279
10280      String fieldName = fieldNames[i];
10281
10282      try {
10283        Field field =
10284          (fieldObj instanceof java.lang.Class<?>)
10285          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
10286          : fieldObj.getClass().getDeclaredField(fieldName);
10287        field.setAccessible(true);
10288        fieldObj = field.get(fieldObj);
10289
10290        if (fieldObj == null) {
10291          return Long.MAX_VALUE; // return default value
10292        }
10293
10294      } catch (Exception e) {
10295        return Long.MAX_VALUE; // return default value
10296
10297      }
10298
10299    }
10300
10301    return ((Long)fieldObj).longValue();
10302  }
10303
10304  ///////////////////////////////////////////////////////////////////////////
10305  /// Methods for "short" (from QuantBody.java.jpp)
10306  ///
10307
10308  /**
10309   * Returns the ith element of the array or collection argument. If the argument is null or not an
10310   * array or collection, returns a default value (Short.MAX_VALUE).
10311   */
10312
10313  @Pure
10314  public static short getElement_short(Object o, long i) {
10315    if (o == null) {
10316      return Short.MAX_VALUE; // return default value
10317    }
10318    java.lang.Class<?> c = o.getClass();
10319    if (c.isArray()) {
10320      return java.lang.reflect.Array.getShort(o, (int)i);
10321    } else if (o instanceof java.util.AbstractCollection<?>) {
10322      return java.lang.reflect.Array.getShort(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
10323    } else {
10324      return Short.MAX_VALUE; // return default value
10325    }
10326  }
10327
10328  @Pure
10329  public static short getElement_short(short[] arr, long i) {
10330    if (arr == null) {
10331      return Short.MAX_VALUE; // return default value
10332    }
10333    return arr[(int)i];
10334  }
10335
10336  private static boolean eq(short x, short y) {
10337    return x == y;
10338  }
10339
10340  private static boolean ne(short x, short y) {
10341    return x != y;
10342  }
10343
10344  private static boolean lt(short x, short y) {
10345    return x < y;
10346  }
10347
10348  private static boolean lte(short x, short y) {
10349    return x <= y;
10350  }
10351
10352  private static boolean gt(short x, short y) {
10353    return x > y;
10354  }
10355
10356  private static boolean gte(short x, short y) {
10357    return x >= y;
10358  }
10359
10360  /** True iff both sequences are non-null and have the same length. */
10361  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
10362  @Pure
10363  public static boolean sameLength(short @Nullable [] seq1, short @Nullable [] seq2) {
10364    return ((seq1 != null)
10365            && (seq2 != null)
10366            && seq1.length == seq2.length);
10367  }
10368
10369  /**
10370   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
10371   *
10372   * <p>If either array is null, returns null. If either array is empty, returns only those
10373   * elements in the other array. If both arrays are empty, returns a new empty array.
10374   */
10375  @SideEffectFree
10376  public static short @PolyNull [] concat(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10377    if (seq1 == null) {
10378      return null;
10379    }
10380    if (seq2 == null) {
10381      return null;
10382    }
10383    return ArraysPlume.concat(seq1, seq2);
10384  }
10385
10386  /**
10387   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
10388   * assurances about the order or repetition of elements: elements may be repeated, and their
10389   * order may be different from the order of elements in seq1 and seq2.
10390   */
10391  @SideEffectFree
10392  public static short @PolyNull [] union(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10393    if (seq1 == null) {
10394      return null;
10395    }
10396    if (seq2 == null) {
10397      return null;
10398    }
10399    return concat(seq1, seq2);
10400  }
10401
10402  /**
10403   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
10404   * gives no assurances about the order or repetition of elements: elements may be repeated, and
10405   * their order may be different from the order of elements in seq1 and seq2.
10406   */
10407  @Pure
10408  public static short @PolyNull [] intersection(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10409    if (seq1 == null) {
10410      return null;
10411    }
10412    if (seq2 == null) {
10413      return null;
10414    }
10415    short[] intermediate = new short[Math.min(seq1.length, seq2.length)];
10416    int length = 0;
10417    for (int i = 0 ; i < seq1.length ; i++) {
10418      if (memberOf(seq1[i], seq2) ) {
10419        intermediate[length++] = seq1[i];
10420      }
10421    }
10422    return ArraysPlume.subarray(intermediate, 0, length);
10423  }
10424
10425  /**
10426   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
10427   * no assurances about the order or repetition of elements: elements may be repeated, and their
10428   * order may be different from the order of elements in seq1 and seq2.
10429   */
10430  @Pure
10431  public static short @PolyNull [] setDiff(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10432    if (seq1 == null) {
10433      return null;
10434    }
10435    if (seq2 == null) {
10436      return null;
10437    }
10438    short[] intermediate = new short[seq1.length];
10439    int length = 0;
10440    for (int i = 0 ; i < seq1.length ; i++) {
10441      if (!memberOf(seq1[i], seq2)) {
10442        intermediate[length++] = seq1[i];
10443      }
10444    }
10445    return ArraysPlume.subarray(intermediate, 0, length);
10446  }
10447
10448  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
10449  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10450  @Pure
10451  public static boolean setEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10452    if (seq1 == null) {
10453      return false;
10454    }
10455    if (seq2 == null) {
10456      return false;
10457    }
10458    for (int i = 0; i < seq1.length ; i++) {
10459      if (!memberOf(seq1[i], seq2) ) {
10460        return false;
10461      }
10462    }
10463    for (int i = 0; i < seq2.length ; i++) {
10464      if (!memberOf(seq2[i], seq1) ) {
10465        return false;
10466      }
10467    }
10468    return true;
10469  }
10470
10471  /** True iff seq1 is the reverse of seq2.
10472   *
10473   * Meaning (in pseudo-FOL):
10474   *
10475   * <pre>
10476   * /\ seq1.length == seq2.length
10477   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
10478   * </pre>
10479   *
10480   */
10481  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10482  @Pure
10483  public static boolean isReverse(short[] seq1, short[] seq2) {
10484    if (!sameLength(seq1, seq2)) {
10485      return false;
10486    }
10487    assert seq1 != null && seq2 != null; // because sameLength() = true
10488    int length = seq1.length;
10489    for (int i = 0 ; i < length ; i++) {
10490      if (ne(seq1[i], seq2[length - i - 1])) {
10491        return false;
10492      }
10493    }
10494    return true;
10495  }
10496
10497  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
10498  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10499  @Pure
10500  public static boolean subsetOf(short @Nullable [] seq1, short @Nullable [] seq2) {
10501    if (seq1 == null) {
10502      return false;
10503    }
10504    if (seq2 == null) {
10505      return false;
10506    }
10507    for (int i = 0 ; i < seq1.length ; i++) {
10508      if (!memberOf(seq1[i], seq2)) {
10509        return false;
10510      }
10511    }
10512    return true;
10513  }
10514
10515  /** Returns true iff seq contains no duplicate elements. */
10516  @EnsuresNonNullIf(result=true, expression="#1")
10517  @Pure
10518  public static boolean noDups(short @Nullable [] seq) {
10519    if (seq == null) {
10520      return false;
10521    }
10522    return ArraysPlume.noDuplicates(seq);
10523  }
10524
10525 /** Returns true iff elt is in array arr. */
10526  @EnsuresNonNullIf(result=true, expression="#2")
10527  @Pure
10528  public static boolean memberOf(short elt, short @Nullable [] arr) {
10529    if (arr == null) {
10530      return false;
10531    }
10532    for (int i = 0 ; i < arr.length ; i++) {
10533      if (eq(arr[i], elt)) {
10534        return true;
10535      }
10536    }
10537    return false;
10538  }
10539
10540  @EnsuresNonNullIf(result=true, expression="#2")
10541  @Pure
10542  public static boolean memberOf(long elt, short @Nullable [] arr) {
10543    if (arr == null) {
10544      return false;
10545    }
10546    for (int i = 0 ; i < arr.length ; i++) {
10547      if (eq(arr[i], elt)) {
10548        return true;
10549      }
10550    }
10551    return false;
10552  }
10553
10554  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
10555  @Pure
10556  public static short @PolyNull [] slice(short @PolyNull [] seq, int start, int end) {
10557    if (seq == null) {
10558      return null;
10559    }
10560    int sliceStart = start;
10561    int sliceEnd = end;
10562    if (start < 0) {
10563      return new short[] { };
10564    }
10565    if (end > seq.length - 1) {
10566      return new short[] { };
10567    }
10568    if (sliceStart > sliceEnd) {
10569      return new short[] { };
10570    }
10571    int length = sliceEnd - sliceStart + 1;
10572    return ArraysPlume.subarray(seq, sliceStart, length);
10573  }
10574
10575  @Pure
10576  public static short @PolyNull [] slice(short @PolyNull [] seq, long start, int end) {
10577    return slice(seq, (int)start, end);
10578  }
10579  @Pure
10580  public static short @PolyNull [] slice(short @PolyNull [] seq, int start, long end) {
10581    return slice(seq, start, (int)end);
10582  }
10583  @Pure
10584  public static short @PolyNull [] slice(short @PolyNull [] seq, long start, long end) {
10585    return slice(seq, (int)start, (int)end);
10586  }
10587
10588  /** True iff all elements in arr equal elt.
10589   *
10590   * Meaning (in pseudo-FOL):
10591   *
10592   * forall i in { 0..arr.length-1 } : arr[i] == elt
10593   *
10594   */
10595  @EnsuresNonNullIf(result=true, expression="#1")
10596  @Pure
10597  public static boolean eltsEqual(short @Nullable [] arr, short elt) {
10598    if (arr == null) {
10599      return false;
10600    }
10601    for (int i = 0 ; i < arr.length ; i++) {
10602      if (ne(arr[i], elt)) {
10603        return false;
10604      }
10605    }
10606    return true;
10607  }
10608
10609  /** True iff every element in arr does not equal elt.
10610   *
10611   * Meaning (in pseudo-FOL):
10612   *
10613   * forall i in { 0..arr.length-1 } : arr[i] != elt
10614   *
10615   */
10616  @EnsuresNonNullIf(result=true, expression="#1")
10617  @Pure
10618  public static boolean eltsNotEqual(short @Nullable [] arr, short elt) {
10619    if (arr == null) {
10620      return false;
10621    }
10622    for (int i = 0 ; i < arr.length ; i++) {
10623      if (eq(arr[i], elt)) {
10624        return false;
10625      }
10626    }
10627    return true;
10628  }
10629
10630  /** True iff every element in arr is greater than elt.
10631   *
10632   * Meaning (in pseudo-FOL):
10633   *
10634   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
10635   *
10636   */
10637  @EnsuresNonNullIf(result=true, expression="#1")
10638  @Pure
10639  public static boolean eltsGT(short @Nullable [] arr, short elt) {
10640    if (arr == null) {
10641      return false;
10642    }
10643    for (int i = 0 ; i < arr.length ; i++) {
10644      if (lte(arr[i], elt)) {
10645        return false;
10646      }
10647    }
10648    return true;
10649  }
10650
10651  /** True iff every element in arr is greater than or equal to elt.
10652   *
10653   * Meaning (in pseudo-FOL):
10654   *
10655   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
10656   *
10657   */
10658  @EnsuresNonNullIf(result=true, expression="#1")
10659  @Pure
10660  public static boolean eltsGTE(short @Nullable [] arr, short elt) {
10661    if (arr == null) {
10662      return false;
10663    }
10664    for (int i = 0 ; i < arr.length ; i++) {
10665      if (lt(arr[i], elt)) {
10666        return false;
10667      }
10668    }
10669    return true;
10670  }
10671
10672  /** True iff every element in arr is less than elt.
10673   *
10674   * Meaning (in pseudo-FOL):
10675   *
10676   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
10677   *
10678   */
10679  @EnsuresNonNullIf(result=true, expression="#1")
10680  @Pure
10681  public static boolean eltsLT(short @Nullable [] arr, short elt) {
10682    if (arr == null) {
10683      return false;
10684    }
10685    for (int i = 0 ; i < arr.length ; i++) {
10686      if (gte(arr[i], elt)) {
10687        return false;
10688      }
10689    }
10690    return true;
10691  }
10692
10693  /** True iff every element in arr is less than or equal to elt.
10694   *
10695   * Meaning (in pseudo-FOL):
10696   *
10697   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
10698   *
10699   */
10700  @EnsuresNonNullIf(result=true, expression="#1")
10701  @Pure
10702  public static boolean eltsLTE(short @Nullable [] arr, short elt) {
10703    if (arr == null) {
10704      return false;
10705    }
10706    for (int i = 0 ; i < arr.length ; i++) {
10707      if (gt(arr[i], elt)) {
10708        return false;
10709      }
10710    }
10711    return true;
10712  }
10713
10714  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
10715   *
10716   * Meaning (in pseudo-FOL):
10717   *
10718   * /\ seq1.length == se2.length
10719   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
10720   *
10721   */
10722
10723  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10724  @Pure
10725  public static boolean pairwiseEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10726    if (!sameLength(seq1, seq2)) {
10727      return false;
10728    }
10729    assert seq1 != null && seq2 != null; // because sameLength() = true
10730    for (int i = 0 ; i < seq1.length ; i++) {
10731      if (ne(seq1[i], seq2[i])) {
10732        return false;
10733      }
10734    }
10735    return true;
10736  }
10737
10738  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
10739   *
10740   * Meaning (in pseudo-FOL):
10741   *
10742   * /\ seq1.length == se2.length
10743   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
10744   *
10745   */
10746  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10747  @Pure
10748  public static boolean pairwiseNotEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10749    if (!sameLength(seq1, seq2)) {
10750      return false;
10751    }
10752    assert seq1 != null && seq2 != null; // because sameLength() = true
10753    for (int i = 0 ; i < seq1.length ; i++) {
10754      if (eq(seq1[i], seq2[i])) {
10755        return false;
10756      }
10757    }
10758    return true;
10759  }
10760
10761  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
10762   *
10763   * Meaning (in pseudo-FOL):
10764   *
10765   * /\ seq1.length == se2.length
10766   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
10767   *
10768   */
10769  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10770  @Pure
10771  public static boolean pairwiseLT(short @Nullable [] seq1, short @Nullable [] seq2) {
10772    if (!sameLength(seq1, seq2)) {
10773      return false;
10774    }
10775    assert seq1 != null && seq2 != null; // because sameLength() = true
10776    for (int i = 0 ; i < seq1.length ; i++) {
10777      if (gte(seq1[i], seq2[i])) {
10778        return false;
10779      }
10780    }
10781    return true;
10782  }
10783
10784  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
10785   * Meaning (in pseudo-FOL):
10786   *
10787   * /\ seq1.length == se2.length
10788   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
10789   *
10790   */
10791  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10792  @Pure
10793  public static boolean pairwiseLTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10794    if (!sameLength(seq1, seq2)) {
10795      return false;
10796    }
10797    assert seq1 != null && seq2 != null; // because sameLength() = true
10798    for (int i = 0 ; i < seq1.length ; i++) {
10799      if (gt(seq1[i], seq2[i])) {
10800        return false;
10801      }
10802    }
10803    return true;
10804  }
10805
10806  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
10807   * Meaning (in pseudo-FOL):
10808   *
10809   * /\ seq1.length == se2.length
10810   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
10811   *
10812   */
10813  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10814  @Pure
10815  public static boolean pairwiseGT(short @Nullable [] seq1, short @Nullable [] seq2) {
10816    if (!sameLength(seq1, seq2)) {
10817      return false;
10818    }
10819    assert seq1 != null && seq2 != null; // because sameLength() = true
10820    for (int i = 0 ; i < seq1.length ; i++) {
10821      if (lte(seq1[i], seq2[i])) {
10822        return false;
10823      }
10824    }
10825    return true;
10826  }
10827
10828  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
10829   * Meaning (in pseudo-FOL):
10830   *
10831   * /\ seq1.length == se2.length
10832   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
10833   *
10834   */
10835  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10836  @Pure
10837  public static boolean pairwiseGTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10838    if (!sameLength(seq1, seq2)) {
10839      return false;
10840    }
10841    assert seq1 != null && seq2 != null; // because sameLength() = true
10842    for (int i = 0 ; i < seq1.length ; i++) {
10843      if (lt(seq1[i], seq2[i])) {
10844        return false;
10845      }
10846    }
10847    return true;
10848  }
10849
10850  /**
10851   * Returns true iff seq1 is lexically equal to seq2.
10852   * For equality, "lexically" and "pairwise" are the same.
10853   */
10854  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10855  @Pure
10856  public static boolean lexEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10857    if (seq1 == null) {
10858      return false;
10859    }
10860    if (seq2 == null) {
10861      return false;
10862    }
10863    return pairwiseEqual(seq1, seq2);
10864  }
10865
10866  /** Returns true iff seq1 is lexically not equal to seq2. */
10867  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10868  @Pure
10869  public static boolean lexNotEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10870    if (seq1 == null) {
10871      return false;
10872    }
10873    if (seq2 == null) {
10874      return false;
10875    }
10876    return !lexEqual(seq1, seq2);
10877  }
10878
10879  /** Returns true iff seq1 is lexically &lt;  seq2. */
10880  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10881  @Pure
10882  public static boolean lexLT(short @Nullable [] seq1, short @Nullable [] seq2) {
10883    if (seq1 == null) {
10884      return false;
10885    }
10886    if (seq2 == null) {
10887      return false;
10888    }
10889    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10890    for (int i = 0 ; i < minlength ; i++) {
10891      if (gt(seq1[i], seq2[i])) {
10892        return false;
10893      } else if (lt(seq1[i], seq2[i])) {
10894        return true;
10895      }
10896    }
10897    if (seq1.length >= seq2.length) {
10898      return false;
10899    }
10900    return true;
10901  }
10902
10903  /** Returns true iff seq1 is lexically &le; to seq2. */
10904  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10905  @Pure
10906  public static boolean lexLTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10907    if (seq1 == null) {
10908      return false;
10909    }
10910    if (seq2 == null) {
10911      return false;
10912    }
10913    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10914    for (int i = 0 ; i < minlength ; i++) {
10915      if (gt(seq1[i], seq2[i])) {
10916        return false;
10917      } else if (lt(seq1[i], seq2[i])) {
10918        return true;
10919      }
10920    }
10921    if (seq1.length > seq2.length) {
10922      return false;
10923    }
10924    return true;
10925  }
10926
10927  /** Returns true iff seq1 is lexically &gt; to seq2. */
10928  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10929  @Pure
10930  public static boolean lexGT(short @Nullable [] seq1, short @Nullable [] seq2) {
10931  if (seq1 == null) {
10932    return false;
10933  }
10934  if (seq2 == null) {
10935    return false;
10936  }
10937    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10938    for (int i = 0 ; i < minlength ; i++) {
10939      if (lt(seq1[i], seq2[i])) {
10940        return false;
10941      } else if (gt(seq1[i], seq2[i])) {
10942        return true;
10943      }
10944    }
10945    if (seq1.length <= seq2.length) {
10946      return false;
10947    }
10948    return true;
10949  }
10950
10951  /** Returns true iff seq1 is lexically &ge; to seq2. */
10952  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10953  @Pure
10954  public static boolean lexGTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10955  if (seq1 == null) {
10956    return false;
10957  }
10958  if (seq2 == null) {
10959    return false;
10960  }
10961    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10962    for (int i = 0 ; i < minlength ; i++) {
10963      if (lt(seq1[i], seq2[i])) {
10964        return false;
10965      } else if (gt(seq1[i], seq2[i])) {
10966        return true;
10967      }
10968    }
10969    if (seq1.length < seq2.length) {
10970      return false;
10971    }
10972    return true;
10973  }
10974
10975  /** True iff for all applicable i, every seq[i] == seq[i+1].
10976   *
10977   * Meaning (in pseudo-FOL):
10978   *
10979   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
10980   *
10981   */
10982  @EnsuresNonNullIf(result=true, expression="#1")
10983  @Pure
10984  public static boolean eltwiseEqual(short @Nullable [] seq) {
10985  if (seq == null) {
10986    return false;
10987  }
10988    for (int i = 0 ; i < seq.length ; i++) {
10989      if (i < seq.length - 1) {
10990        if (ne(seq[i], seq[i + 1])) {
10991          return false;
10992        }
10993      }
10994    }
10995    return true;
10996  }
10997
10998  /** True iff for all applicable i, every seq[i] != seq[i+1].
10999   *
11000   * Meaning (in pseudo-FOL):
11001   *
11002   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
11003   *
11004   */
11005  @EnsuresNonNullIf(result=true, expression="#1")
11006  @Pure
11007  public static boolean eltwiseNotEqual(short @Nullable [] seq) {
11008  if (seq == null) {
11009    return false;
11010  }
11011    for (int i = 0 ; i < seq.length ; i++) {
11012      if (i < seq.length - 1) {
11013        if (eq(seq[i], seq[i + 1])) {
11014          return false;
11015        }
11016      }
11017    }
11018    return true;
11019  }
11020
11021  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
11022   *
11023   * Meaning (in pseudo-FOL):
11024   *
11025   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
11026   *
11027   */
11028  @EnsuresNonNullIf(result=true, expression="#1")
11029  @Pure
11030  public static boolean eltwiseLT(short @Nullable [] seq) {
11031  if (seq == null) {
11032    return false;
11033  }
11034    for (int i = 0 ; i < seq.length ; i++) {
11035      if (i < seq.length - 1) {
11036        if (gte(seq[i], seq[i + 1])) {
11037          return false;
11038        }
11039      }
11040    }
11041    return true;
11042  }
11043
11044  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
11045   *
11046   * Meaning (in pseudo-FOL):
11047   *
11048   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
11049   *
11050   */
11051  @EnsuresNonNullIf(result=true, expression="#1")
11052  @Pure
11053  public static boolean eltwiseLTE(short @Nullable [] seq) {
11054  if (seq == null) {
11055    return false;
11056  }
11057    for (int i = 0 ; i < seq.length ; i++) {
11058      if (i < seq.length - 1) {
11059        if (gt(seq[i], seq[i + 1])) {
11060          return false;
11061        }
11062      }
11063    }
11064    return true;
11065  }
11066
11067  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
11068   *
11069   * Meaning (in pseudo-FOL):
11070   *
11071   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
11072   *
11073   */
11074  @EnsuresNonNullIf(result=true, expression="#1")
11075  @Pure
11076  public static boolean eltwiseGT(short @Nullable [] seq) {
11077  if (seq == null) {
11078    return false;
11079  }
11080    for (int i = 0 ; i < seq.length ; i++) {
11081      if (i < seq.length - 1) {
11082        if (lte(seq[i], seq[i + 1])) {
11083          return false;
11084        }
11085      }
11086    }
11087    return true;
11088  }
11089
11090  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
11091   *
11092   * Meaning (in pseudo-FOL):
11093   *
11094   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
11095   *
11096   */
11097  @EnsuresNonNullIf(result=true, expression="#1")
11098  @Pure
11099  public static boolean eltwiseGTE(short @Nullable [] seq) {
11100  if (seq == null) {
11101    return false;
11102  }
11103    for (int i = 0 ; i < seq.length ; i++) {
11104      if (i < seq.length - 1) {
11105        if (lt(seq[i], seq[i + 1])) {
11106          return false;
11107        }
11108      }
11109    }
11110    return true;
11111  }
11112
11113  /** True iff for all applicable i, every seq[i] == i.
11114   *
11115   * Meaning (in pseudo-FOL):
11116   *
11117   * forall i in { 0..seq.length-1 } : seq[i] == i
11118   *
11119   */
11120  @EnsuresNonNullIf(result=true, expression="#1")
11121  @Pure
11122  public static boolean eltsEqualIndex(short @Nullable [] seq) {
11123  if (seq == null) {
11124    return false;
11125  }
11126    for (int i = 0 ; i < seq.length ; i++) {
11127      if (ne(seq[i], i)) {
11128        return false;
11129      }
11130    }
11131    return true;
11132  }
11133
11134  /** True iff for all applicable i, every seq[i] != i.
11135   *
11136   * Meaning (in pseudo-FOL):
11137   *
11138   * forall i in { 0..seq.length-1 } : seq[i] != i
11139   *
11140   */
11141  @EnsuresNonNullIf(result=true, expression="#1")
11142  @Pure
11143  public static boolean eltsNotEqualIndex(short @Nullable [] seq) {
11144  if (seq == null) {
11145    return false;
11146  }
11147    for (int i = 0 ; i < seq.length ; i++) {
11148      if (eq(seq[i], i)) {
11149        return false;
11150      }
11151    }
11152    return true;
11153  }
11154
11155  /** True iff for all applicable i, every seq[i] &lt; i.
11156   *
11157   * Meaning (in pseudo-FOL):
11158   *
11159   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
11160   *
11161   */
11162  @EnsuresNonNullIf(result=true, expression="#1")
11163  @Pure
11164  public static boolean eltsLtIndex(short @Nullable [] seq) {
11165  if (seq == null) {
11166    return false;
11167  }
11168    for (int i = 0 ; i < seq.length ; i++) {
11169      if (gte(seq[i], i)) {
11170        return false;
11171      }
11172    }
11173    return true;
11174  }
11175
11176  /** True iff for all applicable i, every seq[i] &le; i.
11177   *
11178   * Meaning (in pseudo-FOL):
11179   *
11180   * forall i in { 0..seq.length-1 } : seq[i] &le; i
11181   *
11182   */
11183  @EnsuresNonNullIf(result=true, expression="#1")
11184  @Pure
11185  public static boolean eltsLteIndex(short @Nullable [] seq) {
11186  if (seq == null) {
11187    return false;
11188  }
11189    for (int i = 0 ; i < seq.length ; i++) {
11190      if (gt(seq[i], i)) {
11191        return false;
11192      }
11193    }
11194    return true;
11195  }
11196
11197  /** True iff for all applicable i, every seq[i] &gt; i.
11198   *
11199   * Meaning (in pseudo-FOL):
11200   *
11201   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
11202   *
11203   */
11204  @EnsuresNonNullIf(result=true, expression="#1")
11205  @Pure
11206  public static boolean eltsGtIndex(short @Nullable [] seq) {
11207  if (seq == null) {
11208    return false;
11209  }
11210    for (int i = 0 ; i < seq.length ; i++) {
11211      if (lte(seq[i], i)) {
11212        return false;
11213      }
11214    }
11215    return true;
11216  }
11217
11218  /** True iff for all applicable i, every seq[i] &ge; i.
11219   *
11220   * Meaning (in pseudo-FOL):
11221   *
11222   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
11223   *
11224   */
11225  @EnsuresNonNullIf(result=true, expression="#1")
11226  @Pure
11227  public static boolean eltsGteIndex(short @Nullable [] seq) {
11228  if (seq == null) {
11229    return false;
11230  }
11231    for (int i = 0 ; i < seq.length ; i++) {
11232      if (lt(seq[i], i)) {
11233        return false;
11234      }
11235    }
11236    return true;
11237  }
11238
11239  /// Deferencing (accessing) fields
11240
11241  /**
11242   * collectshort accepts an object and a list of fields (one of which is of array type, and the
11243   * rest of which are not), and produces an array in which the original object has had the given
11244   * fields accessed.
11245   *
11246   * <p>Daikon creates invariants over "variables" such as the following.
11247   *
11248   * <dl>
11249   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
11250   *              for all y's in array x.arr.</dd>
11251   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
11252   *              for all x's in array arr.</dd>
11253   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
11254   * </dl>
11255   *
11256   * <p>The collectshort() method does this collecting work.
11257   *
11258   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
11259   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
11260   * elements that result from following the fields, one of which is assumed to be an array.
11261   *
11262   * <p>
11263   * requires: fieldStr.length() &gt; 0 and object != null
11264   * <p>
11265   * requires: fieldStr contains only field names, no "[]" strings.
11266   * <p>
11267   * requires: the method only works for field sequences with exactly one field representing an
11268   * array. For example, the collection a[].b[].c will fail.
11269   *
11270   * @return if the resulting collection is of non-primitive type, then returns an array of type
11271   * Object[]. Returns null if any array or field access causes an exception.
11272   */
11273
11274  @SideEffectFree
11275  public static short @Nullable [] collectshort(@Nullable Object object, @Nullable String fieldStr) {
11276
11277    if (object == null) {
11278      return null;
11279    }
11280    if (fieldStr == null) {
11281      return null;
11282    }
11283
11284    // assert fieldStr != null && !"".equals(fieldStr);
11285    String[] fieldNames = fieldStr.split("\\.");
11286    short[] retval = collectshort(object, fieldNames, 0);
11287    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
11288    return retval;
11289  }
11290
11291  /** Helper method for collectshort(Object, String).
11292   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
11293   * @see collectshort(Object, String)
11294   */
11295  // @PolyNull does not work for return type, because null is returned on error.
11296  @SideEffectFree
11297  private static short @Nullable [] collectshort(@Nullable Object object,
11298                                                   String[] fields, int fieldsStartIdx) {
11299
11300    if (object == null) {
11301      return null;
11302    }
11303    assert (fields != null);
11304    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
11305
11306    Object fieldObj;
11307    try {
11308      Field field = (object instanceof java.lang.Class<?>)
11309        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
11310        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
11311      field.setAccessible(true);
11312      // Class cls = field.getType();
11313      fieldObj = field.get(object);
11314      // System.out.println("***fieldObj="+fieldObj);
11315
11316    } catch (Exception e) {
11317      return null;
11318
11319    }
11320
11321    if (fieldObj == null) {
11322      return null;
11323    }
11324
11325    // base case: just accessed the last field
11326    if (fields.length - 1 == fieldsStartIdx) {
11327
11328      if (fieldObj.getClass().isArray()) {
11329        // last field is an array
11330        return (short[])fieldObj;
11331      } else {
11332        // This hack should be removed in favor of, at "oneEltArray = ..."
11333        // below, calling a version of collectshort_field that throws an
11334        // error.  Then, this case becomes a run-time error.  -MDE
11335
11336        // Just one element; return a one-element array.
11337        // assert cls.equals(Short.TYPE);
11338        return new short[] { ((Short)fieldObj).shortValue() };
11339      }
11340    } else {
11341      // recursive case: more fields to access after this one
11342
11343      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
11344
11345        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
11346        short[] intermediate = new short[collection.size()];
11347        int index = 0;
11348        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
11349          Object obj = i.next();
11350          short[] oneEltArray = collectshort(obj, fields, fieldsStartIdx + 1);
11351          if (oneEltArray == null) {
11352            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
11353          }
11354          // assert oneEltArray.length == 1;
11355          intermediate[index++] = oneEltArray[0];
11356        }
11357        return intermediate;
11358      } else if (fieldObj.getClass().isArray()) {
11359
11360        // collect elements across array
11361        short[] intermediate = new short[Array.getLength(fieldObj)];
11362        for (int i = 0 ; i < intermediate.length ; i++) {
11363          Object obj = Array.get(fieldObj, i);
11364          short[] oneEltArray = collectshort(obj, fields, fieldsStartIdx + 1);
11365          if (oneEltArray == null) {
11366            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
11367          }
11368          // assert oneEltArray.length == 1;
11369          intermediate[i] = oneEltArray[0];
11370        }
11371        return intermediate;
11372      } else {
11373
11374        return collectshort(fieldObj, fields, fieldsStartIdx + 1);
11375      }
11376    }
11377  }
11378
11379  /**
11380   * Returns the results of dereferencing the fields for 'object'. For example, the call
11381   *
11382   * <pre>collectshort_field(x, "f.g.h")</pre>
11383   *
11384   * has the same value as
11385   *
11386   * <pre>x.f.g.h</pre>.
11387   * Returns a default value if any field access causes an exception.
11388   */
11389  @SideEffectFree
11390  public static short collectshort_field(Object object, String fieldStr) {
11391
11392    if (object == null) {
11393      return Short.MAX_VALUE; // return default value
11394    }
11395    if (fieldStr == null) {
11396      return Short.MAX_VALUE; // return default value
11397    }
11398
11399    String[] fieldNames = fieldStr.split("\\.");
11400
11401    // Holds the intermediate (and final) result
11402    Object fieldObj = object;
11403
11404    for (int i = 0 ; i < fieldNames.length ; i++) {
11405
11406      String fieldName = fieldNames[i];
11407
11408      try {
11409        Field field =
11410          (fieldObj instanceof java.lang.Class<?>)
11411          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
11412          : fieldObj.getClass().getDeclaredField(fieldName);
11413        field.setAccessible(true);
11414        fieldObj = field.get(fieldObj);
11415
11416        if (fieldObj == null) {
11417          return Short.MAX_VALUE; // return default value
11418        }
11419
11420      } catch (Exception e) {
11421        return Short.MAX_VALUE; // return default value
11422
11423      }
11424
11425    }
11426
11427    return ((Short)fieldObj).shortValue();
11428  }
11429
11430  ///////////////////////////////////////////////////////////////////////////
11431  /// Methods for #@Interned Object (from QuantBody.java.jpp)
11432  ///
11433
11434  /**
11435   * Returns the ith element of the array or collection argument. If the argument is null or not an
11436   * array or collection, returns a default value (null).
11437   */
11438
11439  @SuppressWarnings("interning") // reflection
11440
11441  @Pure
11442  public static @Nullable @Interned Object getElement_Object(Object o, long i) {
11443    if (o == null) {
11444      return null; // return default value
11445    }
11446    java.lang.Class<?> c = o.getClass();
11447    if (c.isArray()) {
11448      return java.lang.reflect.Array.get(o, (int)i);
11449    } else if (o instanceof java.util.AbstractCollection<?>) {
11450      return java.lang.reflect.Array.get(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
11451    } else {
11452      return null; // return default value
11453    }
11454  }
11455
11456  @SuppressWarnings("interning") // called reflectively
11457
11458  @Pure
11459  public static @Nullable @Interned Object getElement_Object(Object[] arr, long i) {
11460    if (arr == null) {
11461      return null; // return default value
11462    }
11463    return arr[(int)i];
11464  }
11465
11466  private static boolean eq(@Interned Object x, @Interned Object y) {
11467    return x == y;
11468  }
11469
11470  private static boolean ne(@Interned Object x, @Interned Object y) {
11471    return x != y;
11472  }
11473
11474  /**
11475   * Returns an array of Strings, where the strings are the result of invoking
11476   * x.getClass().toString() for each element x in the array. If an element of the array is null,
11477   * its slot in the returned array is null.
11478   */
11479  @SideEffectFree
11480  public static @PolyNull/*("elt")*/ String @PolyNull/*("container")*/ [] typeArray(@PolyNull/*("elt")*/ @Interned Object @PolyNull/*("container")*/ [] seq) {
11481    if (seq == null) {
11482      return null;
11483    }
11484    @PolyNull/*("elt")*/ String[] retval = new @PolyNull/*("elt")*/ String[seq.length];
11485    for (int i = 0 ; i < seq.length ; i++) {
11486      if (seq[i] == null) {
11487        retval[i] = null;
11488      } else {
11489        retval[i] = seq[i].getClass().toString();
11490      }
11491    }
11492    return retval;
11493  }
11494
11495  /** True iff both sequences are non-null and have the same length. */
11496  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
11497  @Pure
11498  public static boolean sameLength(Object @Nullable [] seq1, Object @Nullable [] seq2) {
11499    return ((seq1 != null)
11500            && (seq2 != null)
11501            && seq1.length == seq2.length);
11502  }
11503
11504  /**
11505   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
11506   *
11507   * <p>If either array is null, returns null. If either array is empty, returns only those
11508   * elements in the other array. If both arrays are empty, returns a new empty array.
11509   */
11510  @SideEffectFree
11511  public static @Interned Object @PolyNull [] concat(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11512    if (seq1 == null) {
11513      return null;
11514    }
11515    if (seq2 == null) {
11516      return null;
11517    }
11518    return ArraysPlume.concat(seq1, seq2);
11519  }
11520
11521  /**
11522   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
11523   * assurances about the order or repetition of elements: elements may be repeated, and their
11524   * order may be different from the order of elements in seq1 and seq2.
11525   */
11526  @SideEffectFree
11527  public static @Interned Object @PolyNull [] union(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11528    if (seq1 == null) {
11529      return null;
11530    }
11531    if (seq2 == null) {
11532      return null;
11533    }
11534    return concat(seq1, seq2);
11535  }
11536
11537  /**
11538   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
11539   * gives no assurances about the order or repetition of elements: elements may be repeated, and
11540   * their order may be different from the order of elements in seq1 and seq2.
11541   */
11542  @Pure
11543  public static @Interned Object @PolyNull [] intersection(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11544    if (seq1 == null) {
11545      return null;
11546    }
11547    if (seq2 == null) {
11548      return null;
11549    }
11550    @Interned Object[] intermediate = new @Interned Object[Math.min(seq1.length, seq2.length)];
11551    int length = 0;
11552    for (int i = 0 ; i < seq1.length ; i++) {
11553      if (memberOf(seq1[i], seq2) ) {
11554        intermediate[length++] = seq1[i];
11555      }
11556    }
11557    return ArraysPlume.subarray(intermediate, 0, length);
11558  }
11559
11560  /**
11561   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
11562   * no assurances about the order or repetition of elements: elements may be repeated, and their
11563   * order may be different from the order of elements in seq1 and seq2.
11564   */
11565  @Pure
11566  public static @Interned Object @PolyNull [] setDiff(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11567    if (seq1 == null) {
11568      return null;
11569    }
11570    if (seq2 == null) {
11571      return null;
11572    }
11573    @Interned Object[] intermediate = new @Interned Object[seq1.length];
11574    int length = 0;
11575    for (int i = 0 ; i < seq1.length ; i++) {
11576      if (!memberOf(seq1[i], seq2)) {
11577        intermediate[length++] = seq1[i];
11578      }
11579    }
11580    return ArraysPlume.subarray(intermediate, 0, length);
11581  }
11582
11583  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
11584  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11585  @Pure
11586  public static boolean setEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11587    if (seq1 == null) {
11588      return false;
11589    }
11590    if (seq2 == null) {
11591      return false;
11592    }
11593    for (int i = 0; i < seq1.length ; i++) {
11594      if (!memberOf(seq1[i], seq2) ) {
11595        return false;
11596      }
11597    }
11598    for (int i = 0; i < seq2.length ; i++) {
11599      if (!memberOf(seq2[i], seq1) ) {
11600        return false;
11601      }
11602    }
11603    return true;
11604  }
11605
11606  /** True iff seq1 is the reverse of seq2.
11607   *
11608   * Meaning (in pseudo-FOL):
11609   *
11610   * <pre>
11611   * /\ seq1.length == seq2.length
11612   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
11613   * </pre>
11614   *
11615   */
11616  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11617  @Pure
11618  public static boolean isReverse(@Interned Object[] seq1, @Interned Object[] seq2) {
11619    if (!sameLength(seq1, seq2)) {
11620      return false;
11621    }
11622    assert seq1 != null && seq2 != null; // because sameLength() = true
11623    int length = seq1.length;
11624    for (int i = 0 ; i < length ; i++) {
11625      if (ne(seq1[i], seq2[length - i - 1])) {
11626        return false;
11627      }
11628    }
11629    return true;
11630  }
11631
11632  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11633  @Pure
11634  public static boolean isReverse(@PolyNull Collection<? extends @Interned Object> seq1, @Interned Object @Nullable [] seq2) {
11635    if (seq1 == null) {
11636      return false;
11637    }
11638    if (seq2 == null) {
11639      return false;
11640    }
11641    @Interned Object[] seq1_array = seq1.toArray(new @Interned Object[]{});
11642    return isReverse(seq1_array, seq2);
11643  }
11644
11645  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
11646  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11647  @Pure
11648  public static boolean subsetOf(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11649    if (seq1 == null) {
11650      return false;
11651    }
11652    if (seq2 == null) {
11653      return false;
11654    }
11655    for (int i = 0 ; i < seq1.length ; i++) {
11656      if (!memberOf(seq1[i], seq2)) {
11657        return false;
11658      }
11659    }
11660    return true;
11661  }
11662
11663  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11664  @Pure
11665  public static boolean subsetOf(@Nullable Collection<? extends @Interned Object> seq1, @Interned Object @Nullable [] seq2) {
11666    if (seq1 == null) {
11667      return false;
11668    }
11669    if (seq2 == null) {
11670      return false;
11671    }
11672    @Interned Object[] seq1_array = seq1.toArray(new @Interned Object[]{});
11673    return subsetOf(seq1_array, seq2);
11674  }
11675
11676  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11677  @Pure
11678  public static boolean subsetOf(@Interned Object @Nullable [] seq1, @Nullable Collection<? extends @Interned Object> seq2) {
11679    if (seq1 == null) {
11680      return false;
11681    }
11682    if (seq2 == null) {
11683      return false;
11684    }
11685    @Interned Object[] seq2_array = seq2.toArray(new @Interned Object[]{});
11686    return subsetOf(seq1, seq2_array);
11687  }
11688
11689  /** Returns true iff seq contains no duplicate elements. */
11690  @EnsuresNonNullIf(result=true, expression="#1")
11691  @Pure
11692  public static boolean noDups(@Interned Object @Nullable [] seq) {
11693    if (seq == null) {
11694      return false;
11695    }
11696    return ArraysPlume.noDuplicates(seq);
11697  }
11698
11699 /** Returns true iff elt is in array arr. */
11700  @EnsuresNonNullIf(result=true, expression="#2")
11701  @Pure
11702  public static boolean memberOf(@Interned Object elt, @Interned Object @Nullable [] arr) {
11703    if (arr == null) {
11704      return false;
11705    }
11706    for (int i = 0 ; i < arr.length ; i++) {
11707      if (eq(arr[i], elt)) {
11708        return true;
11709      }
11710    }
11711    return false;
11712  }
11713
11714  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
11715  @Pure
11716  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, int start, int end) {
11717    if (seq == null) {
11718      return null;
11719    }
11720    int sliceStart = start;
11721    int sliceEnd = end;
11722    if (start < 0) {
11723      return new @Interned Object[] { };
11724    }
11725    if (end > seq.length - 1) {
11726      return new @Interned Object[] { };
11727    }
11728    if (sliceStart > sliceEnd) {
11729      return new @Interned Object[] { };
11730    }
11731    int length = sliceEnd - sliceStart + 1;
11732    return ArraysPlume.subarray(seq, sliceStart, length);
11733  }
11734
11735  @Pure
11736  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, long start, int end) {
11737    return slice(seq, (int)start, end);
11738  }
11739  @Pure
11740  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, int start, long end) {
11741    return slice(seq, start, (int)end);
11742  }
11743  @Pure
11744  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, long start, long end) {
11745    return slice(seq, (int)start, (int)end);
11746  }
11747
11748  /** True iff all elements in arr equal elt.
11749   *
11750   * Meaning (in pseudo-FOL):
11751   *
11752   * forall i in { 0..arr.length-1 } : arr[i] == elt
11753   *
11754   */
11755  @EnsuresNonNullIf(result=true, expression="#1")
11756  @Pure
11757  public static boolean eltsEqual(@Interned Object @Nullable [] arr, @Interned Object elt) {
11758    if (arr == null) {
11759      return false;
11760    }
11761    for (int i = 0 ; i < arr.length ; i++) {
11762      if (ne(arr[i], elt)) {
11763        return false;
11764      }
11765    }
11766    return true;
11767  }
11768
11769  /** True iff every element in arr does not equal elt.
11770   *
11771   * Meaning (in pseudo-FOL):
11772   *
11773   * forall i in { 0..arr.length-1 } : arr[i] != elt
11774   *
11775   */
11776  @EnsuresNonNullIf(result=true, expression="#1")
11777  @Pure
11778  public static boolean eltsNotEqual(@Interned Object @Nullable [] arr, @Interned Object elt) {
11779    if (arr == null) {
11780      return false;
11781    }
11782    for (int i = 0 ; i < arr.length ; i++) {
11783      if (eq(arr[i], elt)) {
11784        return false;
11785      }
11786    }
11787    return true;
11788  }
11789
11790  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
11791   *
11792   * Meaning (in pseudo-FOL):
11793   *
11794   * /\ seq1.length == se2.length
11795   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
11796   *
11797   */
11798
11799  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11800  @Pure
11801  public static boolean pairwiseEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11802    if (!sameLength(seq1, seq2)) {
11803      return false;
11804    }
11805    assert seq1 != null && seq2 != null; // because sameLength() = true
11806    for (int i = 0 ; i < seq1.length ; i++) {
11807      if (ne(seq1[i], seq2[i])) {
11808        return false;
11809      }
11810    }
11811    return true;
11812  }
11813
11814  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11815  @Pure
11816  public static boolean pairwiseEqual(@Nullable AbstractCollection<@Interned Object> seq1, @Interned Object @Nullable [] seq2) {
11817    if (seq1 == null) {
11818      return false;
11819    }
11820    if (seq2 == null) {
11821      return false;
11822    }
11823    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
11824    @Interned Object[] seq1a = (@Interned Object[]) seq1.toArray(new @Interned Object[0]);
11825    return pairwiseEqual(seq1a, seq2);
11826  }
11827
11828  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11829  @Pure
11830  public static boolean pairwiseEqual(@Interned Object @Nullable [] seq1, @Nullable AbstractCollection<@Interned Object> seq2) {
11831    if (seq1 == null) {
11832      return false;
11833    }
11834    if (seq2 == null) {
11835      return false;
11836    }
11837    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
11838    @Interned Object[] seq2a = (@Interned Object[]) seq2.toArray();
11839    return pairwiseEqual(seq1, seq2a);
11840  }
11841
11842  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
11843   *
11844   * Meaning (in pseudo-FOL):
11845   *
11846   * /\ seq1.length == se2.length
11847   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
11848   *
11849   */
11850  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11851  @Pure
11852  public static boolean pairwiseNotEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11853    if (!sameLength(seq1, seq2)) {
11854      return false;
11855    }
11856    assert seq1 != null && seq2 != null; // because sameLength() = true
11857    for (int i = 0 ; i < seq1.length ; i++) {
11858      if (eq(seq1[i], seq2[i])) {
11859        return false;
11860      }
11861    }
11862    return true;
11863  }
11864
11865  /**
11866   * Returns true iff seq1 is lexically equal to seq2.
11867   * For equality, "lexically" and "pairwise" are the same.
11868   */
11869  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11870  @Pure
11871  public static boolean lexEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11872    if (seq1 == null) {
11873      return false;
11874    }
11875    if (seq2 == null) {
11876      return false;
11877    }
11878    return pairwiseEqual(seq1, seq2);
11879  }
11880
11881  /** Returns true iff seq1 is lexically not equal to seq2. */
11882  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11883  @Pure
11884  public static boolean lexNotEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11885    if (seq1 == null) {
11886      return false;
11887    }
11888    if (seq2 == null) {
11889      return false;
11890    }
11891    return !lexEqual(seq1, seq2);
11892  }
11893
11894  /** True iff for all applicable i, every seq[i] == seq[i+1].
11895   *
11896   * Meaning (in pseudo-FOL):
11897   *
11898   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
11899   *
11900   */
11901  @EnsuresNonNullIf(result=true, expression="#1")
11902  @Pure
11903  public static boolean eltwiseEqual(@Interned Object @Nullable [] seq) {
11904  if (seq == null) {
11905    return false;
11906  }
11907    for (int i = 0 ; i < seq.length ; i++) {
11908      if (i < seq.length - 1) {
11909        if (ne(seq[i], seq[i + 1])) {
11910          return false;
11911        }
11912      }
11913    }
11914    return true;
11915  }
11916
11917  /** True iff for all applicable i, every seq[i] != seq[i+1].
11918   *
11919   * Meaning (in pseudo-FOL):
11920   *
11921   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
11922   *
11923   */
11924  @EnsuresNonNullIf(result=true, expression="#1")
11925  @Pure
11926  public static boolean eltwiseNotEqual(@Interned Object @Nullable [] seq) {
11927  if (seq == null) {
11928    return false;
11929  }
11930    for (int i = 0 ; i < seq.length ; i++) {
11931      if (i < seq.length - 1) {
11932        if (eq(seq[i], seq[i + 1])) {
11933          return false;
11934        }
11935      }
11936    }
11937    return true;
11938  }
11939
11940  /// Deferencing (accessing) fields
11941
11942  /**
11943   * collectObject accepts an object and a list of fields (one of which is of array type, and the
11944   * rest of which are not), and produces an array in which the original object has had the given
11945   * fields accessed.
11946   *
11947   * <p>Daikon creates invariants over "variables" such as the following.
11948   *
11949   * <dl>
11950   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
11951   *              for all y's in array x.arr.</dd>
11952   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
11953   *              for all x's in array arr.</dd>
11954   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
11955   * </dl>
11956   *
11957   * <p>The collectObject() method does this collecting work.
11958   *
11959   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
11960   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
11961   * elements that result from following the fields, one of which is assumed to be an array.
11962   *
11963   * <p>
11964   * requires: fieldStr.length() &gt; 0 and object != null
11965   * <p>
11966   * requires: fieldStr contains only field names, no "[]" strings.
11967   * <p>
11968   * requires: the method only works for field sequences with exactly one field representing an
11969   * array. For example, the collection a[].b[].c will fail.
11970   *
11971   * @return if the resulting collection is of non-primitive type, then returns an array of type
11972   * Object[]. Returns null if any array or field access causes an exception.
11973   */
11974
11975  @SuppressWarnings("interning") // reflection
11976
11977  @SideEffectFree
11978  public static Object @Nullable [] collectObject(@Nullable Object object, @Nullable String fieldStr) {
11979
11980    if (object == null) {
11981      return null;
11982    }
11983    if (fieldStr == null) {
11984      return null;
11985    }
11986
11987    // assert fieldStr != null && !"".equals(fieldStr);
11988    String[] fieldNames = fieldStr.split("\\.");
11989    @Interned Object[] retval = collectObject(object, fieldNames, 0);
11990    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
11991    return retval;
11992  }
11993
11994  @SuppressWarnings("interning") // reflection
11995
11996  /** Helper method for collectObject(Object, String).
11997   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
11998   * @see collectObject(Object, String)
11999   */
12000  // @PolyNull does not work for return type, because null is returned on error.
12001  @SideEffectFree
12002  private static Object @Nullable [] collectObject(@Nullable Object object,
12003                                                   String[] fields, int fieldsStartIdx) {
12004
12005    if (object == null) {
12006      return null;
12007    }
12008    assert (fields != null);
12009    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
12010
12011    Object fieldObj;
12012    try {
12013      Field field = (object instanceof java.lang.Class<?>)
12014        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
12015        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
12016      field.setAccessible(true);
12017      // Class cls = field.getType();
12018      fieldObj = field.get(object);
12019      // System.out.println("***fieldObj="+fieldObj);
12020
12021    } catch (Exception e) {
12022      return null;
12023
12024    }
12025
12026    if (fieldObj == null) {
12027      return null;
12028    }
12029
12030    // base case: just accessed the last field
12031    if (fields.length - 1 == fieldsStartIdx) {
12032
12033      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12034        // last field is the collection
12035        @SuppressWarnings("unchecked")
12036        java.util.AbstractCollection<@Interned Object> ac = (java.util.AbstractCollection<@Interned Object>)fieldObj;
12037        return ac.toArray(new @Interned Object[]{});
12038      } else
12039
12040      if (fieldObj.getClass().isArray()) {
12041        // last field is an array
12042        return (@Interned Object[])fieldObj;
12043      } else {
12044        // This hack should be removed in favor of, at "oneEltArray = ..."
12045        // below, calling a version of collectObject_field that throws an
12046        // error.  Then, this case becomes a run-time error.  -MDE
12047
12048        // Just one element; return a one-element array.
12049        // assert cls.equals(_TYPE_WRAPPER_NAME.TYPE);
12050        return new @Interned Object[] { fieldObj };
12051      }
12052    } else {
12053      // recursive case: more fields to access after this one
12054
12055      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12056
12057        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
12058        @Interned Object[] intermediate = new @Interned Object[collection.size()];
12059        int index = 0;
12060        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
12061          Object obj = i.next();
12062          Object[] oneEltArray = collectObject(obj, fields, fieldsStartIdx + 1);
12063          if (oneEltArray == null) {
12064            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12065          }
12066          // assert oneEltArray.length == 1;
12067          intermediate[index++] = oneEltArray[0];
12068        }
12069        return intermediate;
12070      } else if (fieldObj.getClass().isArray()) {
12071
12072        // collect elements across array
12073        @Interned Object[] intermediate = new @Interned Object[Array.getLength(fieldObj)];
12074        for (int i = 0 ; i < intermediate.length ; i++) {
12075          Object obj = Array.get(fieldObj, i);
12076          Object[] oneEltArray = collectObject(obj, fields, fieldsStartIdx + 1);
12077          if (oneEltArray == null) {
12078            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12079          }
12080          // assert oneEltArray.length == 1;
12081          intermediate[i] = oneEltArray[0];
12082        }
12083        return intermediate;
12084      } else {
12085
12086        return collectObject(fieldObj, fields, fieldsStartIdx + 1);
12087      }
12088    }
12089  }
12090
12091  /**
12092   * Returns the results of dereferencing the fields for 'object'. For example, the call
12093   *
12094   * <pre>collectObject_field(x, "f.g.h")</pre>
12095   *
12096   * has the same value as
12097   *
12098   * <pre>x.f.g.h</pre>.
12099   * Returns a default value if any field access causes an exception.
12100   */
12101  @SideEffectFree
12102  public static @Nullable Object collectObject_field(Object object, String fieldStr) {
12103
12104    if (object == null) {
12105      return null; // return default value
12106    }
12107    if (fieldStr == null) {
12108      return null; // return default value
12109    }
12110
12111    String[] fieldNames = fieldStr.split("\\.");
12112
12113    // Holds the intermediate (and final) result
12114    Object fieldObj = object;
12115
12116    for (int i = 0 ; i < fieldNames.length ; i++) {
12117
12118      String fieldName = fieldNames[i];
12119
12120      try {
12121        Field field =
12122          (fieldObj instanceof java.lang.Class<?>)
12123          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
12124          : fieldObj.getClass().getDeclaredField(fieldName);
12125        field.setAccessible(true);
12126        fieldObj = field.get(fieldObj);
12127
12128        if (fieldObj == null) {
12129          return null; // return default value
12130        }
12131
12132      } catch (Exception e) {
12133        return null; // return default value
12134
12135      }
12136
12137    }
12138
12139    return fieldObj;
12140  }
12141
12142  ///////////////////////////////////////////////////////////////////////////
12143  /// Methods for #@Interned String (from QuantBody.java.jpp)
12144  ///
12145
12146  /**
12147   * Returns the ith element of the array or collection argument. If the argument is null or not an
12148   * array or collection, returns a default value (null).
12149   */
12150
12151  @SuppressWarnings("interning") // reflection
12152
12153  @Pure
12154  public static @Nullable @Interned String getElement_String(Object o, long i) {
12155    if (o == null) {
12156      return null; // return default value
12157    }
12158    java.lang.Class<?> c = o.getClass();
12159    if (c.isArray()) {
12160      return (String)java.lang.reflect.Array.get(o, (int)i);
12161    } else if (o instanceof java.util.AbstractCollection<?>) {
12162      return (String)java.lang.reflect.Array.get(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
12163    } else {
12164      return null; // return default value
12165    }
12166  }
12167
12168  @SuppressWarnings("interning") // called reflectively
12169
12170  @Pure
12171  public static @Nullable @Interned String getElement_String(String[] arr, long i) {
12172    if (arr == null) {
12173      return null; // return default value
12174    }
12175    return arr[(int)i];
12176  }
12177
12178  private static boolean eq(@Interned String x, @Interned String y) {
12179    return x == y;
12180  }
12181
12182  private static boolean ne(@Interned String x, @Interned String y) {
12183    return x != y;
12184  }
12185
12186  /** True iff both sequences are non-null and have the same length. */
12187  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
12188  @Pure
12189  public static boolean sameLength(String @Nullable [] seq1, String @Nullable [] seq2) {
12190    return ((seq1 != null)
12191            && (seq2 != null)
12192            && seq1.length == seq2.length);
12193  }
12194
12195  /**
12196   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
12197   *
12198   * <p>If either array is null, returns null. If either array is empty, returns only those
12199   * elements in the other array. If both arrays are empty, returns a new empty array.
12200   */
12201  @SideEffectFree
12202  public static @Interned String @PolyNull [] concat(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12203    if (seq1 == null) {
12204      return null;
12205    }
12206    if (seq2 == null) {
12207      return null;
12208    }
12209    return ArraysPlume.concat(seq1, seq2);
12210  }
12211
12212  /**
12213   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
12214   * assurances about the order or repetition of elements: elements may be repeated, and their
12215   * order may be different from the order of elements in seq1 and seq2.
12216   */
12217  @SideEffectFree
12218  public static @Interned String @PolyNull [] union(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12219    if (seq1 == null) {
12220      return null;
12221    }
12222    if (seq2 == null) {
12223      return null;
12224    }
12225    return concat(seq1, seq2);
12226  }
12227
12228  /**
12229   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
12230   * gives no assurances about the order or repetition of elements: elements may be repeated, and
12231   * their order may be different from the order of elements in seq1 and seq2.
12232   */
12233  @Pure
12234  public static @Interned String @PolyNull [] intersection(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12235    if (seq1 == null) {
12236      return null;
12237    }
12238    if (seq2 == null) {
12239      return null;
12240    }
12241    @Interned String[] intermediate = new @Interned String[Math.min(seq1.length, seq2.length)];
12242    int length = 0;
12243    for (int i = 0 ; i < seq1.length ; i++) {
12244      if (memberOf(seq1[i], seq2) ) {
12245        intermediate[length++] = seq1[i];
12246      }
12247    }
12248    return ArraysPlume.subarray(intermediate, 0, length);
12249  }
12250
12251  /**
12252   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
12253   * no assurances about the order or repetition of elements: elements may be repeated, and their
12254   * order may be different from the order of elements in seq1 and seq2.
12255   */
12256  @Pure
12257  public static @Interned String @PolyNull [] setDiff(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12258    if (seq1 == null) {
12259      return null;
12260    }
12261    if (seq2 == null) {
12262      return null;
12263    }
12264    @Interned String[] intermediate = new @Interned String[seq1.length];
12265    int length = 0;
12266    for (int i = 0 ; i < seq1.length ; i++) {
12267      if (!memberOf(seq1[i], seq2)) {
12268        intermediate[length++] = seq1[i];
12269      }
12270    }
12271    return ArraysPlume.subarray(intermediate, 0, length);
12272  }
12273
12274  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
12275  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12276  @Pure
12277  public static boolean setEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12278    if (seq1 == null) {
12279      return false;
12280    }
12281    if (seq2 == null) {
12282      return false;
12283    }
12284    for (int i = 0; i < seq1.length ; i++) {
12285      if (!memberOf(seq1[i], seq2) ) {
12286        return false;
12287      }
12288    }
12289    for (int i = 0; i < seq2.length ; i++) {
12290      if (!memberOf(seq2[i], seq1) ) {
12291        return false;
12292      }
12293    }
12294    return true;
12295  }
12296
12297  /** True iff seq1 is the reverse of seq2.
12298   *
12299   * Meaning (in pseudo-FOL):
12300   *
12301   * <pre>
12302   * /\ seq1.length == seq2.length
12303   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
12304   * </pre>
12305   *
12306   */
12307  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12308  @Pure
12309  public static boolean isReverse(@Interned String[] seq1, @Interned String[] seq2) {
12310    if (!sameLength(seq1, seq2)) {
12311      return false;
12312    }
12313    assert seq1 != null && seq2 != null; // because sameLength() = true
12314    int length = seq1.length;
12315    for (int i = 0 ; i < length ; i++) {
12316      if (ne(seq1[i], seq2[length - i - 1])) {
12317        return false;
12318      }
12319    }
12320    return true;
12321  }
12322
12323  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
12324  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12325  @Pure
12326  public static boolean subsetOf(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12327    if (seq1 == null) {
12328      return false;
12329    }
12330    if (seq2 == null) {
12331      return false;
12332    }
12333    for (int i = 0 ; i < seq1.length ; i++) {
12334      if (!memberOf(seq1[i], seq2)) {
12335        return false;
12336      }
12337    }
12338    return true;
12339  }
12340
12341  /** Returns true iff seq contains no duplicate elements. */
12342  @EnsuresNonNullIf(result=true, expression="#1")
12343  @Pure
12344  public static boolean noDups(@Interned String @Nullable [] seq) {
12345    if (seq == null) {
12346      return false;
12347    }
12348    return ArraysPlume.noDuplicates(seq);
12349  }
12350
12351 /** Returns true iff elt is in array arr. */
12352  @EnsuresNonNullIf(result=true, expression="#2")
12353  @Pure
12354  public static boolean memberOf(@Interned String elt, @Interned String @Nullable [] arr) {
12355    if (arr == null) {
12356      return false;
12357    }
12358    for (int i = 0 ; i < arr.length ; i++) {
12359      if (eq(arr[i], elt)) {
12360        return true;
12361      }
12362    }
12363    return false;
12364  }
12365
12366  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
12367  @Pure
12368  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, int start, int end) {
12369    if (seq == null) {
12370      return null;
12371    }
12372    int sliceStart = start;
12373    int sliceEnd = end;
12374    if (start < 0) {
12375      return new @Interned String[] { };
12376    }
12377    if (end > seq.length - 1) {
12378      return new @Interned String[] { };
12379    }
12380    if (sliceStart > sliceEnd) {
12381      return new @Interned String[] { };
12382    }
12383    int length = sliceEnd - sliceStart + 1;
12384    return ArraysPlume.subarray(seq, sliceStart, length);
12385  }
12386
12387  @Pure
12388  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, long start, int end) {
12389    return slice(seq, (int)start, end);
12390  }
12391  @Pure
12392  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, int start, long end) {
12393    return slice(seq, start, (int)end);
12394  }
12395  @Pure
12396  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, long start, long end) {
12397    return slice(seq, (int)start, (int)end);
12398  }
12399
12400  /** True iff all elements in arr equal elt.
12401   *
12402   * Meaning (in pseudo-FOL):
12403   *
12404   * forall i in { 0..arr.length-1 } : arr[i] == elt
12405   *
12406   */
12407  @EnsuresNonNullIf(result=true, expression="#1")
12408  @Pure
12409  public static boolean eltsEqual(@Interned String @Nullable [] arr, @Interned String elt) {
12410    if (arr == null) {
12411      return false;
12412    }
12413    for (int i = 0 ; i < arr.length ; i++) {
12414      if (ne(arr[i], elt)) {
12415        return false;
12416      }
12417    }
12418    return true;
12419  }
12420
12421  /** True iff every element in arr does not equal elt.
12422   *
12423   * Meaning (in pseudo-FOL):
12424   *
12425   * forall i in { 0..arr.length-1 } : arr[i] != elt
12426   *
12427   */
12428  @EnsuresNonNullIf(result=true, expression="#1")
12429  @Pure
12430  public static boolean eltsNotEqual(@Interned String @Nullable [] arr, @Interned String elt) {
12431    if (arr == null) {
12432      return false;
12433    }
12434    for (int i = 0 ; i < arr.length ; i++) {
12435      if (eq(arr[i], elt)) {
12436        return false;
12437      }
12438    }
12439    return true;
12440  }
12441
12442  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
12443   *
12444   * Meaning (in pseudo-FOL):
12445   *
12446   * /\ seq1.length == se2.length
12447   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
12448   *
12449   */
12450
12451  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12452  @Pure
12453  public static boolean pairwiseEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12454    if (!sameLength(seq1, seq2)) {
12455      return false;
12456    }
12457    assert seq1 != null && seq2 != null; // because sameLength() = true
12458    for (int i = 0 ; i < seq1.length ; i++) {
12459      if (ne(seq1[i], seq2[i])) {
12460        return false;
12461      }
12462    }
12463    return true;
12464  }
12465
12466  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12467  @Pure
12468  public static boolean pairwiseEqual(@Nullable AbstractCollection<@Interned String> seq1, @Interned String @Nullable [] seq2) {
12469    if (seq1 == null) {
12470      return false;
12471    }
12472    if (seq2 == null) {
12473      return false;
12474    }
12475    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
12476    @Interned String[] seq1a = (@Interned String[]) seq1.toArray(new @Interned String[0]);
12477    return pairwiseEqual(seq1a, seq2);
12478  }
12479
12480  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12481  @Pure
12482  public static boolean pairwiseEqual(@Interned String @Nullable [] seq1, @Nullable AbstractCollection<@Interned String> seq2) {
12483    if (seq1 == null) {
12484      return false;
12485    }
12486    if (seq2 == null) {
12487      return false;
12488    }
12489    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
12490    @Interned String[] seq2a = (@Interned String[]) seq2.toArray();
12491    return pairwiseEqual(seq1, seq2a);
12492  }
12493
12494  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
12495   *
12496   * Meaning (in pseudo-FOL):
12497   *
12498   * /\ seq1.length == se2.length
12499   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
12500   *
12501   */
12502  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12503  @Pure
12504  public static boolean pairwiseNotEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12505    if (!sameLength(seq1, seq2)) {
12506      return false;
12507    }
12508    assert seq1 != null && seq2 != null; // because sameLength() = true
12509    for (int i = 0 ; i < seq1.length ; i++) {
12510      if (eq(seq1[i], seq2[i])) {
12511        return false;
12512      }
12513    }
12514    return true;
12515  }
12516
12517  /**
12518   * Returns true iff seq1 is lexically equal to seq2.
12519   * For equality, "lexically" and "pairwise" are the same.
12520   */
12521  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12522  @Pure
12523  public static boolean lexEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12524    if (seq1 == null) {
12525      return false;
12526    }
12527    if (seq2 == null) {
12528      return false;
12529    }
12530    return pairwiseEqual(seq1, seq2);
12531  }
12532
12533  /** Returns true iff seq1 is lexically not equal to seq2. */
12534  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12535  @Pure
12536  public static boolean lexNotEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12537    if (seq1 == null) {
12538      return false;
12539    }
12540    if (seq2 == null) {
12541      return false;
12542    }
12543    return !lexEqual(seq1, seq2);
12544  }
12545
12546  /** True iff for all applicable i, every seq[i] == seq[i+1].
12547   *
12548   * Meaning (in pseudo-FOL):
12549   *
12550   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
12551   *
12552   */
12553  @EnsuresNonNullIf(result=true, expression="#1")
12554  @Pure
12555  public static boolean eltwiseEqual(@Interned String @Nullable [] seq) {
12556  if (seq == null) {
12557    return false;
12558  }
12559    for (int i = 0 ; i < seq.length ; i++) {
12560      if (i < seq.length - 1) {
12561        if (ne(seq[i], seq[i + 1])) {
12562          return false;
12563        }
12564      }
12565    }
12566    return true;
12567  }
12568
12569  /** True iff for all applicable i, every seq[i] != seq[i+1].
12570   *
12571   * Meaning (in pseudo-FOL):
12572   *
12573   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
12574   *
12575   */
12576  @EnsuresNonNullIf(result=true, expression="#1")
12577  @Pure
12578  public static boolean eltwiseNotEqual(@Interned String @Nullable [] seq) {
12579  if (seq == null) {
12580    return false;
12581  }
12582    for (int i = 0 ; i < seq.length ; i++) {
12583      if (i < seq.length - 1) {
12584        if (eq(seq[i], seq[i + 1])) {
12585          return false;
12586        }
12587      }
12588    }
12589    return true;
12590  }
12591
12592  /// Deferencing (accessing) fields
12593
12594  /**
12595   * collectString accepts an object and a list of fields (one of which is of array type, and the
12596   * rest of which are not), and produces an array in which the original object has had the given
12597   * fields accessed.
12598   *
12599   * <p>Daikon creates invariants over "variables" such as the following.
12600   *
12601   * <dl>
12602   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
12603   *              for all y's in array x.arr.</dd>
12604   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
12605   *              for all x's in array arr.</dd>
12606   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
12607   * </dl>
12608   *
12609   * <p>The collectString() method does this collecting work.
12610   *
12611   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
12612   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
12613   * elements that result from following the fields, one of which is assumed to be an array.
12614   *
12615   * <p>
12616   * requires: fieldStr.length() &gt; 0 and object != null
12617   * <p>
12618   * requires: fieldStr contains only field names, no "[]" strings.
12619   * <p>
12620   * requires: the method only works for field sequences with exactly one field representing an
12621   * array. For example, the collection a[].b[].c will fail.
12622   *
12623   * @return if the resulting collection is of non-primitive type, then returns an array of type
12624   * Object[]. Returns null if any array or field access causes an exception.
12625   */
12626
12627  @SuppressWarnings("interning") // reflection
12628
12629  @SideEffectFree
12630  public static String @Nullable [] collectString(@Nullable Object object, @Nullable String fieldStr) {
12631
12632    if (object == null) {
12633      return null;
12634    }
12635    if (fieldStr == null) {
12636      return null;
12637    }
12638
12639    // assert fieldStr != null && !"".equals(fieldStr);
12640    String[] fieldNames = fieldStr.split("\\.");
12641    @Interned String[] retval = collectString(object, fieldNames, 0);
12642    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
12643    return retval;
12644  }
12645
12646  @SuppressWarnings("interning") // reflection
12647
12648  /** Helper method for collectString(Object, String).
12649   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
12650   * @see collectString(Object, String)
12651   */
12652  // @PolyNull does not work for return type, because null is returned on error.
12653  @SideEffectFree
12654  private static String @Nullable [] collectString(@Nullable Object object,
12655                                                   String[] fields, int fieldsStartIdx) {
12656
12657    if (object == null) {
12658      return null;
12659    }
12660    assert (fields != null);
12661    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
12662
12663    Object fieldObj;
12664    try {
12665      Field field = (object instanceof java.lang.Class<?>)
12666        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
12667        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
12668      field.setAccessible(true);
12669      // Class cls = field.getType();
12670      fieldObj = field.get(object);
12671      // System.out.println("***fieldObj="+fieldObj);
12672
12673    } catch (Exception e) {
12674      return null;
12675
12676    }
12677
12678    if (fieldObj == null) {
12679      return null;
12680    }
12681
12682    // base case: just accessed the last field
12683    if (fields.length - 1 == fieldsStartIdx) {
12684
12685      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12686        // last field is the collection
12687        @SuppressWarnings("unchecked")
12688        java.util.AbstractCollection<@Interned String> ac = (java.util.AbstractCollection<@Interned String>)fieldObj;
12689        return ac.toArray(new @Interned String[]{});
12690      } else
12691
12692      if (fieldObj.getClass().isArray()) {
12693        // last field is an array
12694        return (@Interned String[])fieldObj;
12695      } else {
12696        // This hack should be removed in favor of, at "oneEltArray = ..."
12697        // below, calling a version of collectString_field that throws an
12698        // error.  Then, this case becomes a run-time error.  -MDE
12699
12700        // Just one element; return a one-element array.
12701        // assert cls.equals(_TYPE_WRAPPER_NAME.TYPE);
12702        return new @Interned String[] { (String)fieldObj };
12703      }
12704    } else {
12705      // recursive case: more fields to access after this one
12706
12707      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12708
12709        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
12710        @Interned String[] intermediate = new @Interned String[collection.size()];
12711        int index = 0;
12712        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
12713          Object obj = i.next();
12714          String[] oneEltArray = collectString(obj, fields, fieldsStartIdx + 1);
12715          if (oneEltArray == null) {
12716            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12717          }
12718          // assert oneEltArray.length == 1;
12719          intermediate[index++] = oneEltArray[0];
12720        }
12721        return intermediate;
12722      } else if (fieldObj.getClass().isArray()) {
12723
12724        // collect elements across array
12725        @Interned String[] intermediate = new @Interned String[Array.getLength(fieldObj)];
12726        for (int i = 0 ; i < intermediate.length ; i++) {
12727          Object obj = Array.get(fieldObj, i);
12728          String[] oneEltArray = collectString(obj, fields, fieldsStartIdx + 1);
12729          if (oneEltArray == null) {
12730            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12731          }
12732          // assert oneEltArray.length == 1;
12733          intermediate[i] = oneEltArray[0];
12734        }
12735        return intermediate;
12736      } else {
12737
12738        return collectString(fieldObj, fields, fieldsStartIdx + 1);
12739      }
12740    }
12741  }
12742
12743  /**
12744   * Returns the results of dereferencing the fields for 'object'. For example, the call
12745   *
12746   * <pre>collectString_field(x, "f.g.h")</pre>
12747   *
12748   * has the same value as
12749   *
12750   * <pre>x.f.g.h</pre>.
12751   * Returns a default value if any field access causes an exception.
12752   */
12753  @SideEffectFree
12754  public static @Nullable String collectString_field(Object object, String fieldStr) {
12755
12756    if (object == null) {
12757      return null; // return default value
12758    }
12759    if (fieldStr == null) {
12760      return null; // return default value
12761    }
12762
12763    String[] fieldNames = fieldStr.split("\\.");
12764
12765    // Holds the intermediate (and final) result
12766    Object fieldObj = object;
12767
12768    for (int i = 0 ; i < fieldNames.length ; i++) {
12769
12770      String fieldName = fieldNames[i];
12771
12772      try {
12773        Field field =
12774          (fieldObj instanceof java.lang.Class<?>)
12775          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
12776          : fieldObj.getClass().getDeclaredField(fieldName);
12777        field.setAccessible(true);
12778        fieldObj = field.get(fieldObj);
12779
12780        if (fieldObj == null) {
12781          return null; // return default value
12782        }
12783
12784      } catch (Exception e) {
12785        return null; // return default value
12786
12787      }
12788
12789    }
12790
12791    return (String)fieldObj;
12792  }
12793
12794  ///////////////////////////////////////////////////////////////////////////
12795  /// Collection methods (dispatch to array methods)
12796  //
12797
12798  // These methods handle calls to quant methods that instead of passing an
12799  // Object[] array, pass a Collection.  Each method handles arrays or
12800  // Collections.  They convert any Collection to an array, then invoke the
12801  // Object[] version of the method.
12802
12803  /**
12804   * See {@link #noDups(Object[])}.
12805   * @see #noDups(Object[])
12806   */
12807  @SuppressWarnings("interning") // cast from Object
12808  @EnsuresNonNullIf(result=true, expression="#1")
12809  @Pure
12810  public static boolean noDups(Object seq) {
12811    if (seq == null) {
12812      return false;
12813    }
12814    return noDups(toObjArray(seq));
12815  }
12816
12817  /**
12818   * See {@link #typeArray(Object[])}.
12819   * @see #typeArray(Object[])
12820   */
12821  @SuppressWarnings("interning") // cast from Object
12822  /*TODO: @AssertNonNullIfNonNull({"#1"})*/
12823  /* pure */ public static String @PolyNull [] typeArray(@PolyNull Object seq) {
12824    if (seq == null) {
12825      return null;
12826    }
12827    return typeArray(toObjArray(seq));
12828  }
12829
12830  /**
12831   * See {@link #eltwiseEqual(Object[])}.
12832   * @see #eltwiseEqual(Object[])
12833   */
12834  @SuppressWarnings("interning") // cast from Object
12835  @EnsuresNonNullIf(result=true, expression="#1")
12836  @Pure
12837  public static boolean eltwiseEqual(Object seq) {
12838    if (seq == null) {
12839      return false;
12840    }
12841    return eltwiseEqual(toObjArray(seq));
12842  }
12843
12844  /**
12845   * See {@link #eltwiseNotEqual(Object[])}.
12846   * @see #eltwiseNotEqual(Object[])
12847   */
12848  @SuppressWarnings("interning") // cast from Object
12849  @EnsuresNonNullIf(result=true, expression="#1")
12850  @Pure
12851  public static boolean eltwiseNotEqual(Object seq) {
12852    if (seq == null) {
12853      return false;
12854    }
12855    return eltwiseNotEqual(toObjArray(seq));
12856  }
12857
12858  /**
12859   * See {@link #concat(Object[], Object[])}.
12860   * @see #concat(Object[], Object[])
12861   */
12862  @SuppressWarnings("interning") // cast from Object
12863  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12864  @SideEffectFree
12865  public static java.lang.Object @PolyNull [] concat(@PolyNull Object seq1, @PolyNull Object seq2) {
12866    if (seq1 == null) {
12867      return null;
12868    }
12869    if (seq2 == null) {
12870      return null;
12871    }
12872    return concat(toObjArray(seq1), toObjArray(seq2));
12873  }
12874
12875  /**
12876   * See {@link #union(Object[], Object[])}.
12877   * @see #union(Object[], Object[])
12878   */
12879  @SuppressWarnings("interning") // cast from Object
12880  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12881  @SideEffectFree
12882  public static java.lang.Object @PolyNull [] union(@PolyNull Object seq1, @PolyNull Object seq2) {
12883    if (seq1 == null) {
12884      return null;
12885    }
12886    if (seq2 == null) {
12887      return null;
12888    }
12889    return union(toObjArray(seq1), toObjArray(seq2));
12890  }
12891
12892  /**
12893   * See {@link #intersection(Object[], Object[])}.
12894   * @see #intersection(Object[], Object[])
12895   */
12896  @SuppressWarnings("interning") // cast from Object
12897  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12898  @SideEffectFree
12899  public static java.lang.Object @PolyNull [] intersection(@PolyNull Object seq1, @PolyNull Object seq2) {
12900    if (seq1 == null) {
12901      return null;
12902    }
12903    if (seq2 == null) {
12904      return null;
12905    }
12906    return intersection(toObjArray(seq1), toObjArray(seq2));
12907  }
12908
12909  /**
12910   * See {@link #setDiff(Object[], Object[])}.
12911   * @see #setDiff(Object[], Object[])
12912   */
12913  @SuppressWarnings("interning") // cast from Object
12914  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12915  @SideEffectFree
12916  public static java.lang.Object @PolyNull [] setDiff(@PolyNull Object seq1, @PolyNull Object seq2) {
12917    if (seq1 == null) {
12918      return null;
12919    }
12920    if (seq2 == null) {
12921      return null;
12922    }
12923    return setDiff(toObjArray(seq1), toObjArray(seq2));
12924  }
12925
12926  /**
12927   * See {@link #setEqual(Object[], Object[])}.
12928   * @see #setEqual(Object[], Object[])
12929   */
12930  @SuppressWarnings("interning")  // cast from Object
12931  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12932  @Pure
12933  public static boolean setEqual(@Nullable Object seq1, @Nullable Object seq2) {
12934    if (seq1 == null) {
12935      return false;
12936    }
12937    if (seq2 == null) {
12938      return false;
12939    }
12940    return setEqual(toObjArray(seq1), toObjArray(seq2));
12941  }
12942
12943  /**
12944   * See {@link #isReverse(Object[], Object[])}.
12945   * @see #isReverse(Object[], Object[])
12946   */
12947  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12948  @SuppressWarnings("interning")  // cast from Object
12949  @Pure
12950  public static boolean isReverse(@Nullable Object seq1, @Nullable Object seq2) {
12951    if (seq1 == null) {
12952      return false;
12953    }
12954    if (seq2 == null) {
12955      return false;
12956    }
12957    return isReverse(toObjArray(seq1), toObjArray(seq2));
12958  }
12959
12960  /**
12961   * See {@link #pairwiseEqual(Object[], Object[])}.
12962   * @see #pairwiseEqual(Object[], Object[])
12963   */
12964  @SuppressWarnings("interning")  // cast from Object
12965  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12966  @Pure
12967  public static boolean pairwiseEqual(@Nullable Object seq1, @Nullable Object seq2) {
12968    if (seq1 == null) {
12969      return false;
12970    }
12971    if (seq2 == null) {
12972      return false;
12973    }
12974    return pairwiseEqual(toObjArray(seq1), toObjArray(seq2));
12975  }
12976
12977  /**
12978   * See {@link #pairwiseNotEqual(Object[], Object[])}.
12979   * @see #pairwiseNotEqual(Object[], Object[])
12980   */
12981  @SuppressWarnings("interning")  // cast from Object
12982  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12983  @Pure
12984  public static boolean pairwiseNotEqual(@Nullable Object seq1, @Nullable Object seq2) {
12985    if (seq1 == null) {
12986      return false;
12987    }
12988    if (seq2 == null) {
12989      return false;
12990    }
12991    return pairwiseNotEqual(toObjArray(seq1), toObjArray(seq2));
12992  }
12993
12994  /**
12995   * See {@link #lexEqual(Object[], Object[])}.
12996   * @see #lexEqual(Object[], Object[])
12997   */
12998  @SuppressWarnings("interning")  // cast from Object
12999  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
13000  @Pure
13001  public static boolean lexEqual(@Nullable Object seq1, @Nullable Object seq2) {
13002    if (seq1 == null) {
13003      return false;
13004    }
13005    if (seq2 == null) {
13006      return false;
13007    }
13008    return lexEqual(toObjArray(seq1), toObjArray(seq2));
13009  }
13010
13011  /**
13012   * See {@link #lexNotEqual(Object[], Object[])}.
13013   * @see #lexNotEqual(Object[], Object[])
13014   */
13015  @SuppressWarnings("interning")  // cast from Object
13016  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
13017  @Pure
13018  public static boolean lexNotEqual(@Nullable Object seq1, @Nullable Object seq2) {
13019    if (seq1 == null) {
13020      return false;
13021    }
13022    if (seq2 == null) {
13023      return false;
13024    }
13025    return lexNotEqual(toObjArray(seq1), toObjArray(seq2));
13026  }
13027
13028  /**
13029   * See {@link #memberOf(Object, Object[])}.
13030   * @see #memberOf(Object, Object[])
13031   */
13032  @SuppressWarnings("interning")  // cast from Object
13033  @EnsuresNonNullIf(result=true, expression="#2")
13034  @Pure
13035  public static boolean memberOf(Object elt, @Nullable Object arr) {
13036    if (arr == null) {
13037      return false;
13038    }
13039    return memberOf(elt, toObjArray(arr));
13040  }
13041
13042  /**
13043   * See {@link #slice(Object[], int, int)}.
13044   * @see #slice(Object[], int, int)
13045   */
13046  @SuppressWarnings("interning")  // cast from Object
13047  /*TODO: @AssertNonNullIfNonNull("#1")*/
13048  @SideEffectFree
13049  public static Object @PolyNull [] slice(@PolyNull Object seq, int start, int end) {
13050    if (seq == null) {
13051      return null;
13052    }
13053    return slice(toObjArray(seq), start, end);
13054  }
13055
13056  /**
13057   * See {@link #eltsEqual(Object[], Object)}.
13058   * @see #eltsEqual(Object[], Object)
13059   */
13060  @SuppressWarnings("interning")  // cast from Object
13061  @EnsuresNonNullIf(result=true, expression="#1")
13062  @Pure
13063  public static boolean eltsEqual(@Nullable Object arr, Object elt) {
13064    if (arr == null) {
13065      return false;
13066    }
13067    return eltsEqual(toObjArray(arr), elt);
13068  }
13069
13070  /**
13071   * See {@link #eltsNotEqual(Object[], Object)}.
13072   * @see #eltsNotEqual(Object[], Object)
13073   */
13074  @SuppressWarnings("interning")  // cast from Object
13075  @EnsuresNonNullIf(result=true, expression="#1")
13076  @Pure
13077  public static boolean eltsNotEqual(@Nullable Object arr, Object elt) {
13078    if (arr == null) {
13079      return false;
13080    }
13081    return eltsNotEqual(toObjArray(arr), elt);
13082  }
13083
13084  @EnsuresNonNullIf(result=true, expression="#1")
13085  @Pure
13086  public static boolean isIntegralType(@Nullable Class<?> c) {
13087    if (c == null) {
13088      return false;
13089    }
13090    return
13091      (c.equals(Byte.TYPE)
13092       || c.equals(Short.TYPE)
13093       || c.equals(Integer.TYPE)
13094       || c.equals(Long.TYPE));
13095  }
13096
13097  @EnsuresNonNullIf(result=true, expression="#1")
13098  @Pure
13099  public static boolean isRealType(@Nullable Class<?> c) {
13100    if (c == null) {
13101      return false;
13102    }
13103    return
13104      (c.equals(Float.TYPE)
13105       || c.equals(Double.TYPE));
13106  }
13107
13108  @EnsuresNonNullIf(result=true, expression="#1")
13109  @Pure
13110  public static boolean isNumericType(Class<?> c) {
13111    if (c == null) {
13112      return false;
13113    }
13114    return isIntegralType(c) || isRealType(c);
13115  }
13116
13117  /** Returns an Object[] array, either by casting or by conversion from an
13118   * AbstractCollection.
13119   */
13120  /*TODO: @AssertNonNullIfNonNull("#1")*/
13121  public static Object @PolyNull [] toObjArray(@PolyNull Object o) {
13122    if (o == null) {
13123      return null;
13124    }
13125    if (o instanceof java.util.AbstractCollection<?>) {
13126      @SuppressWarnings({"unchecked"})
13127        AbstractCollection<Object> ac = (AbstractCollection<Object>)o;
13128      Object [] result = ac.toArray(new java.lang.Object []{});
13129      return result;
13130    } else if (o.getClass().isArray()) {
13131      return (Object[])o;
13132    } else {
13133      throw new IllegalArgumentException("not an array or collection: " + o);
13134    }
13135  }
13136}