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.hasNoDuplicates(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  // @PolyNull does not work for return type, because null is returned on error.
604  /** Helper method for collectboolean(Object, String).
605   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
606   * @see collectboolean(Object, String)
607   */
608
609  @SideEffectFree
610  private static boolean @Nullable [] collectboolean(@Nullable Object object,
611                                                   String[] fields, int fieldsStartIdx) {
612
613    if (object == null) {
614      return null;
615    }
616    assert (fields != null);
617    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
618
619    Object fieldObj;
620    try {
621      Field field = (object instanceof java.lang.Class<?>)
622        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
623        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
624      field.setAccessible(true);
625      // Class cls = field.getType();
626      fieldObj = field.get(object);
627      // System.out.println("***fieldObj="+fieldObj);
628
629    } catch (Exception e) {
630      return null;
631
632    }
633
634    if (fieldObj == null) {
635      return null;
636    }
637
638    // base case: just accessed the last field
639    if (fields.length - 1 == fieldsStartIdx) {
640
641      if (fieldObj.getClass().isArray()) {
642        // last field is an array
643        return (boolean[])fieldObj;
644      } else {
645        // This hack should be removed in favor of, at "oneEltArray = ..."
646        // below, calling a version of collectboolean_field that throws an
647        // error.  Then, this case becomes a run-time error.  -MDE
648
649        // Just one element; return a one-element array.
650        // assert cls.equals(Boolean.TYPE);
651        return new boolean[] { ((Boolean)fieldObj).booleanValue() };
652      }
653    } else {
654      // recursive case: more fields to access after this one
655
656      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
657
658        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
659        boolean[] intermediate = new boolean[collection.size()];
660        int index = 0;
661        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
662          Object obj = i.next();
663          boolean[] oneEltArray = collectboolean(obj, fields, fieldsStartIdx + 1);
664          if (oneEltArray == null) {
665            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
666          }
667          // assert oneEltArray.length == 1;
668          intermediate[index++] = oneEltArray[0];
669        }
670        return intermediate;
671      } else if (fieldObj.getClass().isArray()) {
672
673        // collect elements across array
674        boolean[] intermediate = new boolean[Array.getLength(fieldObj)];
675        for (int i = 0 ; i < intermediate.length ; i++) {
676          Object obj = Array.get(fieldObj, i);
677          boolean[] oneEltArray = collectboolean(obj, fields, fieldsStartIdx + 1);
678          if (oneEltArray == null) {
679            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
680          }
681          // assert oneEltArray.length == 1;
682          intermediate[i] = oneEltArray[0];
683        }
684        return intermediate;
685      } else {
686
687        return collectboolean(fieldObj, fields, fieldsStartIdx + 1);
688      }
689    }
690  }
691
692  /**
693   * Returns the results of dereferencing the fields for 'object'. For example, the call
694   *
695   * <pre>collectboolean_field(x, "f.g.h")</pre>
696   *
697   * has the same value as
698   *
699   * <pre>x.f.g.h</pre>.
700   * Returns a default value if any field access causes an exception.
701   */
702  @SideEffectFree
703  public static boolean collectboolean_field(Object object, String fieldStr) {
704
705    if (object == null) {
706      return false; // return default value
707    }
708    if (fieldStr == null) {
709      return false; // return default value
710    }
711
712    String[] fieldNames = fieldStr.split("\\.");
713
714    // Holds the intermediate (and final) result
715    Object fieldObj = object;
716
717    for (int i = 0 ; i < fieldNames.length ; i++) {
718
719      String fieldName = fieldNames[i];
720
721      try {
722        Field field =
723          (fieldObj instanceof java.lang.Class<?>)
724          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
725          : fieldObj.getClass().getDeclaredField(fieldName);
726        field.setAccessible(true);
727        fieldObj = field.get(fieldObj);
728
729        if (fieldObj == null) {
730          return false; // return default value
731        }
732
733      } catch (Exception e) {
734        return false; // return default value
735
736      }
737
738    }
739
740    return ((Boolean)fieldObj).booleanValue();
741  }
742
743  // ///////////////////////////////////////////////////////////////////////////
744  // Methods for "byte" (from QuantBody.java.jpp)
745  //
746
747  /**
748   * Returns the ith element of the array or collection argument. If the argument is null or not an
749   * array or collection, returns a default value (Byte.MAX_VALUE).
750   */
751
752  @Pure
753  public static byte getElement_byte(Object o, long i) {
754    if (o == null) {
755      return Byte.MAX_VALUE; // return default value
756    }
757    java.lang.Class<?> c = o.getClass();
758    if (c.isArray()) {
759      return java.lang.reflect.Array.getByte(o, (int)i);
760    } else if (o instanceof java.util.AbstractCollection<?>) {
761      return java.lang.reflect.Array.getByte(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
762    } else {
763      return Byte.MAX_VALUE; // return default value
764    }
765  }
766
767  @Pure
768  public static byte getElement_byte(byte[] arr, long i) {
769    if (arr == null) {
770      return Byte.MAX_VALUE; // return default value
771    }
772    return arr[(int)i];
773  }
774
775  private static boolean eq(byte x, byte y) {
776    return x == y;
777  }
778
779  private static boolean ne(byte x, byte y) {
780    return x != y;
781  }
782
783  private static boolean lt(byte x, byte y) {
784    return x < y;
785  }
786
787  private static boolean lte(byte x, byte y) {
788    return x <= y;
789  }
790
791  private static boolean gt(byte x, byte y) {
792    return x > y;
793  }
794
795  private static boolean gte(byte x, byte y) {
796    return x >= y;
797  }
798
799  /** True iff both sequences are non-null and have the same length. */
800  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
801  @Pure
802  public static boolean sameLength(byte @Nullable [] seq1, byte @Nullable [] seq2) {
803    return ((seq1 != null)
804            && (seq2 != null)
805            && seq1.length == seq2.length);
806  }
807
808  /** True iff both sequences are non-null and have the same length. */
809  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
810  @Pure
811  public static boolean sameLength(byte @Nullable [] seq1, int @Nullable [] seq2) {
812    return ((seq1 != null)
813            && (seq2 != null)
814            && seq1.length == seq2.length);
815  }
816
817  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
818   *
819   * Meaning (in pseudo-FOL):
820   *
821   * <pre>
822   * /\ seq1.length == seq2.length
823   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
824   * </pre>
825   *
826   */
827  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
828  @Pure
829  public static boolean pairwiseDivides(byte[] seq1, byte[] seq2) {
830    if (!sameLength(seq1, seq2)) {
831      return false;
832    }
833    assert seq1 != null && seq2 != null; // because sameLength() = true
834    for (int i = 0 ; i < seq1.length ; i++) {
835      if (ne(seq1[i] % seq2[i], 0)) {
836        return false;
837      }
838    }
839    return true;
840  }
841  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
842  @Pure
843  public static boolean pairwiseDivides(byte[] seq1, int[] seq2) {
844    if (!sameLength(seq1, seq2)) {
845      return false;
846    }
847    assert seq1 != null && seq2 != null; // because sameLength() = true
848    for (int i = 0 ; i < seq1.length ; i++) {
849      if (ne(seq1[i] % seq2[i], 0)) {
850        return false;
851      }
852    }
853    return true;
854  }
855
856  /**
857   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
858   *
859   * Meaning (in pseudo-FOL):
860   *
861   * <pre>
862   * /\ seq1.length == seq2.length
863   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
864   * </pre>
865   *
866   */
867  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
868  @Pure
869  public static boolean pairwiseSquare(byte[] seq1, byte[] seq2) {
870    if (!sameLength(seq1, seq2)) {
871      return false;
872    }
873    assert seq1 != null && seq2 != null; // because sameLength() = true
874    for (int i = 0 ; i < seq1.length ; i++) {
875      if (ne(seq1[i], seq2[i] * seq2[i])) {
876        return false;
877      }
878    }
879    return true;
880  }
881  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
882  @Pure
883  public static boolean pairwiseSquare(byte[] seq1, int[] seq2) {
884    if (!sameLength(seq1, seq2)) {
885      return false;
886    }
887    assert seq1 != null && seq2 != null; // because sameLength() = true
888    for (int i = 0 ; i < seq1.length ; i++) {
889
890      if (ne(seq1[i], seq2[i] * seq2[i])) {
891
892        return false;
893      }
894    }
895    return true;
896  }
897
898  /**
899   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
900   *
901   * <p>If either array is null, returns null. If either array is empty, returns only those
902   * elements in the other array. If both arrays are empty, returns a new empty array.
903   */
904  @SideEffectFree
905  public static byte @PolyNull [] concat(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
906    if (seq1 == null) {
907      return null;
908    }
909    if (seq2 == null) {
910      return null;
911    }
912    return ArraysPlume.concat(seq1, seq2);
913  }
914
915  @SideEffectFree
916  public static int @PolyNull [] concat(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
917    if (seq1 == null) {
918      return null;
919    }
920    if (seq2 == null) {
921      return null;
922    }
923    // Cannot just use ArraysPlume.concat because the two arrays
924    // have different types.  This essentially inlines that method.
925    int newLength = seq1.length + seq2.length;
926    int[] retval = new int[newLength];
927
928    for (int j = 0 ; j < seq1.length ; j++) {
929      retval[j] = seq1[j];
930    }
931    System.arraycopy(seq2, 0, retval, seq1.length, seq2.length);
932
933    return retval;
934  }
935
936  /**
937   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
938   * assurances about the order or repetition of elements: elements may be repeated, and their
939   * order may be different from the order of elements in seq1 and seq2.
940   */
941  @SideEffectFree
942  public static byte @PolyNull [] union(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
943    if (seq1 == null) {
944      return null;
945    }
946    if (seq2 == null) {
947      return null;
948    }
949    return concat(seq1, seq2);
950  }
951
952  @Pure
953  public static int @PolyNull [] union(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
954    if (seq1 == null) {
955      return null;
956    }
957    if (seq2 == null) {
958      return null;
959    }
960    return concat(seq1, seq2);
961  }
962
963  /**
964   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
965   * gives no assurances about the order or repetition of elements: elements may be repeated, and
966   * their order may be different from the order of elements in seq1 and seq2.
967   */
968  @Pure
969  public static byte @PolyNull [] intersection(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
970    if (seq1 == null) {
971      return null;
972    }
973    if (seq2 == null) {
974      return null;
975    }
976    byte[] intermediate = new byte[Math.min(seq1.length, seq2.length)];
977    int length = 0;
978    for (int i = 0 ; i < seq1.length ; i++) {
979      if (memberOf(seq1[i], seq2) ) {
980        intermediate[length++] = seq1[i];
981      }
982    }
983    return ArraysPlume.subarray(intermediate, 0, length);
984  }
985
986  @Pure
987  public static int @PolyNull [] intersection(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
988    if (seq1 == null) {
989      return null;
990    }
991    if (seq2 == null) {
992      return null;
993    }
994    int[] intermediate = new int[Math.min(seq1.length, seq2.length)];
995    int length = 0;
996    for (int i = 0 ; i < seq1.length ; i++) {
997      if (memberOf(seq1[i], seq2) ) {
998        intermediate[length++] = seq1[i];
999      }
1000    }
1001    return ArraysPlume.subarray(intermediate, 0, length);
1002  }
1003
1004  /**
1005   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
1006   * no assurances about the order or repetition of elements: elements may be repeated, and their
1007   * order may be different from the order of elements in seq1 and seq2.
1008   */
1009  @Pure
1010  public static byte @PolyNull [] setDiff(byte @PolyNull [] seq1, byte @PolyNull [] seq2) {
1011    if (seq1 == null) {
1012      return null;
1013    }
1014    if (seq2 == null) {
1015      return null;
1016    }
1017    byte[] intermediate = new byte[seq1.length];
1018    int length = 0;
1019    for (int i = 0 ; i < seq1.length ; i++) {
1020      if (!memberOf(seq1[i], seq2)) {
1021        intermediate[length++] = seq1[i];
1022      }
1023    }
1024    return ArraysPlume.subarray(intermediate, 0, length);
1025  }
1026
1027  @Pure
1028  public static int @PolyNull [] setDiff(byte @PolyNull [] seq1, int @PolyNull [] seq2) {
1029    if (seq1 == null) {
1030      return null;
1031    }
1032    if (seq2 == null) {
1033      return null;
1034    }
1035    int[] intermediate = new int[seq1.length];
1036    int length = 0;
1037    for (int i = 0 ; i < seq1.length ; i++) {
1038      if (!memberOf(seq1[i], seq2)) {
1039        intermediate[length++] = seq1[i];
1040      }
1041    }
1042    return ArraysPlume.subarray(intermediate, 0, length);
1043  }
1044
1045  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
1046  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1047  @Pure
1048  public static boolean setEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1049    if (seq1 == null) {
1050      return false;
1051    }
1052    if (seq2 == null) {
1053      return false;
1054    }
1055    for (int i = 0; i < seq1.length ; i++) {
1056      if (!memberOf(seq1[i], seq2) ) {
1057        return false;
1058      }
1059    }
1060    for (int i = 0; i < seq2.length ; i++) {
1061      if (!memberOf(seq2[i], seq1) ) {
1062        return false;
1063      }
1064    }
1065    return true;
1066  }
1067
1068  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1069  @Pure
1070  public static boolean setEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1071    if (seq1 == null) {
1072      return false;
1073    }
1074    if (seq2 == null) {
1075      return false;
1076    }
1077    for (int i = 0; i < seq1.length ; i++) {
1078      if (!memberOf(seq1[i], seq2) ) {
1079        return false;
1080      }
1081    }
1082    for (int i = 0; i < seq2.length ; i++) {
1083      if (!memberOf(seq2[i], seq1) ) {
1084        return false;
1085      }
1086    }
1087    return true;
1088  }
1089
1090  /** True iff seq1 is the reverse of seq2.
1091   *
1092   * Meaning (in pseudo-FOL):
1093   *
1094   * <pre>
1095   * /\ seq1.length == seq2.length
1096   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
1097   * </pre>
1098   *
1099   */
1100  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1101  @Pure
1102  public static boolean isReverse(byte[] seq1, byte[] seq2) {
1103    if (!sameLength(seq1, seq2)) {
1104      return false;
1105    }
1106    assert seq1 != null && seq2 != null; // because sameLength() = true
1107    int length = seq1.length;
1108    for (int i = 0 ; i < length ; i++) {
1109      if (ne(seq1[i], seq2[length - i - 1])) {
1110        return false;
1111      }
1112    }
1113    return true;
1114  }
1115
1116  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1117  @Pure
1118  public static boolean isReverse(byte @Nullable [] seq1, int @Nullable [] seq2) {
1119    if (!sameLength(seq1, seq2)) {
1120      return false;
1121    }
1122    assert seq1 != null && seq2 != null; // because sameLength() = true
1123    int length = seq1.length;
1124    for (int i = 0 ; i < length ; i++) {
1125      if (ne(seq1[i], seq2[length - i - 1])) {
1126        return false;
1127      }
1128    }
1129    return true;
1130  }
1131
1132  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
1133  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1134  @Pure
1135  public static boolean subsetOf(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1136    if (seq1 == null) {
1137      return false;
1138    }
1139    if (seq2 == null) {
1140      return false;
1141    }
1142    for (int i = 0 ; i < seq1.length ; i++) {
1143      if (!memberOf(seq1[i], seq2)) {
1144        return false;
1145      }
1146    }
1147    return true;
1148  }
1149
1150  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1151  @Pure
1152  public static boolean subsetOf(byte @Nullable [] seq1, int @Nullable [] seq2) {
1153    if (seq1 == null) {
1154      return false;
1155    }
1156    if (seq2 == null) {
1157      return false;
1158    }
1159    for (int i = 0 ; i < seq1.length ; i++) {
1160      if (!memberOf(seq1[i], seq2)) {
1161        return false;
1162      }
1163    }
1164    return true;
1165  }
1166
1167  /** Returns true iff seq contains no duplicate elements. */
1168  @EnsuresNonNullIf(result=true, expression="#1")
1169  @Pure
1170  public static boolean noDups(byte @Nullable [] seq) {
1171    if (seq == null) {
1172      return false;
1173    }
1174    return ArraysPlume.hasNoDuplicates(seq);
1175  }
1176
1177 /** Returns true iff elt is in array arr. */
1178  @EnsuresNonNullIf(result=true, expression="#2")
1179  @Pure
1180  public static boolean memberOf(byte elt, byte @Nullable [] arr) {
1181    if (arr == null) {
1182      return false;
1183    }
1184    for (int i = 0 ; i < arr.length ; i++) {
1185      if (eq(arr[i], elt)) {
1186        return true;
1187      }
1188    }
1189    return false;
1190  }
1191
1192  @EnsuresNonNullIf(result=true, expression="#2")
1193  @Pure
1194  public static boolean memberOf(byte elt, int @Nullable [] arr) {
1195    if (arr == null) {
1196      return false;
1197    }
1198    for (int i = 0 ; i < arr.length ; i++) {
1199      if (eq(arr[i], elt)) {
1200        return true;
1201      }
1202    }
1203    return false;
1204  }
1205
1206  @EnsuresNonNullIf(result=true, expression="#2")
1207  @Pure
1208  public static boolean memberOf(long elt, byte @Nullable [] arr) {
1209    if (arr == null) {
1210      return false;
1211    }
1212    for (int i = 0 ; i < arr.length ; i++) {
1213      if (eq(arr[i], elt)) {
1214        return true;
1215      }
1216    }
1217    return false;
1218  }
1219
1220  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
1221  @Pure
1222  public static byte @PolyNull [] slice(byte @PolyNull [] seq, int start, int end) {
1223    if (seq == null) {
1224      return null;
1225    }
1226    int sliceStart = start;
1227    int sliceEnd = end;
1228    if (start < 0) {
1229      return new byte[] { };
1230    }
1231    if (end > seq.length - 1) {
1232      return new byte[] { };
1233    }
1234    if (sliceStart > sliceEnd) {
1235      return new byte[] { };
1236    }
1237    int length = sliceEnd - sliceStart + 1;
1238    return ArraysPlume.subarray(seq, sliceStart, length);
1239  }
1240
1241  @Pure
1242  public static byte @PolyNull [] slice(byte @PolyNull [] seq, long start, int end) {
1243    return slice(seq, (int)start, end);
1244  }
1245  @Pure
1246  public static byte @PolyNull [] slice(byte @PolyNull [] seq, int start, long end) {
1247    return slice(seq, start, (int)end);
1248  }
1249  @Pure
1250  public static byte @PolyNull [] slice(byte @PolyNull [] seq, long start, long end) {
1251    return slice(seq, (int)start, (int)end);
1252  }
1253
1254  /** True iff all elements in arr equal elt.
1255   *
1256   * Meaning (in pseudo-FOL):
1257   *
1258   * forall i in { 0..arr.length-1 } : arr[i] == elt
1259   *
1260   */
1261  @EnsuresNonNullIf(result=true, expression="#1")
1262  @Pure
1263  public static boolean eltsEqual(byte @Nullable [] arr, byte elt) {
1264    if (arr == null) {
1265      return false;
1266    }
1267    for (int i = 0 ; i < arr.length ; i++) {
1268      if (ne(arr[i], elt)) {
1269        return false;
1270      }
1271    }
1272    return true;
1273  }
1274
1275  @EnsuresNonNullIf(result=true, expression="#1")
1276  @Pure
1277  public static boolean eltsEqual(byte @Nullable [] arr, int elt) {
1278    if (arr == null) {
1279      return false;
1280    }
1281    for (int i = 0 ; i < arr.length ; i++) {
1282      if (ne(arr[i], elt)) {
1283        return false;
1284      }
1285    }
1286    return true;
1287  }
1288
1289  /** True iff every element in arr does not equal elt.
1290   *
1291   * Meaning (in pseudo-FOL):
1292   *
1293   * forall i in { 0..arr.length-1 } : arr[i] != elt
1294   *
1295   */
1296  @EnsuresNonNullIf(result=true, expression="#1")
1297  @Pure
1298  public static boolean eltsNotEqual(byte @Nullable [] arr, byte elt) {
1299    if (arr == null) {
1300      return false;
1301    }
1302    for (int i = 0 ; i < arr.length ; i++) {
1303      if (eq(arr[i], elt)) {
1304        return false;
1305      }
1306    }
1307    return true;
1308  }
1309
1310  @EnsuresNonNullIf(result=true, expression="#1")
1311  @Pure
1312  public static boolean eltsNotEqual(byte @Nullable [] arr, int elt) {
1313    if (arr == null) {
1314      return false;
1315    }
1316    for (int i = 0 ; i < arr.length ; i++) {
1317      if (eq(arr[i], elt)) {
1318        return false;
1319      }
1320    }
1321    return true;
1322  }
1323
1324  /** True iff every element in arr is greater than elt.
1325   *
1326   * Meaning (in pseudo-FOL):
1327   *
1328   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
1329   *
1330   */
1331  @EnsuresNonNullIf(result=true, expression="#1")
1332  @Pure
1333  public static boolean eltsGT(byte @Nullable [] arr, byte elt) {
1334    if (arr == null) {
1335      return false;
1336    }
1337    for (int i = 0 ; i < arr.length ; i++) {
1338      if (lte(arr[i], elt)) {
1339        return false;
1340      }
1341    }
1342    return true;
1343  }
1344
1345  @EnsuresNonNullIf(result=true, expression="#1")
1346  @Pure
1347  public static boolean eltsGT(byte @Nullable [] arr, int elt) {
1348    if (arr == null) {
1349      return false;
1350    }
1351    for (int i = 0 ; i < arr.length ; i++) {
1352      if (lte(arr[i], elt)) {
1353        return false;
1354      }
1355    }
1356    return true;
1357  }
1358
1359  /** True iff every element in arr is greater than or equal to elt.
1360   *
1361   * Meaning (in pseudo-FOL):
1362   *
1363   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
1364   *
1365   */
1366  @EnsuresNonNullIf(result=true, expression="#1")
1367  @Pure
1368  public static boolean eltsGTE(byte @Nullable [] arr, byte elt) {
1369    if (arr == null) {
1370      return false;
1371    }
1372    for (int i = 0 ; i < arr.length ; i++) {
1373      if (lt(arr[i], elt)) {
1374        return false;
1375      }
1376    }
1377    return true;
1378  }
1379
1380  @EnsuresNonNullIf(result=true, expression="#1")
1381  @Pure
1382  public static boolean eltsGTE(byte @Nullable [] arr, int elt) {
1383    if (arr == null) {
1384      return false;
1385    }
1386    for (int i = 0 ; i < arr.length ; i++) {
1387      if (lt(arr[i], elt)) {
1388        return false;
1389      }
1390    }
1391    return true;
1392  }
1393
1394  /** True iff every element in arr is less than elt.
1395   *
1396   * Meaning (in pseudo-FOL):
1397   *
1398   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
1399   *
1400   */
1401  @EnsuresNonNullIf(result=true, expression="#1")
1402  @Pure
1403  public static boolean eltsLT(byte @Nullable [] arr, byte elt) {
1404    if (arr == null) {
1405      return false;
1406    }
1407    for (int i = 0 ; i < arr.length ; i++) {
1408      if (gte(arr[i], elt)) {
1409        return false;
1410      }
1411    }
1412    return true;
1413  }
1414
1415  @EnsuresNonNullIf(result=true, expression="#1")
1416  @Pure
1417  public static boolean eltsLT(byte @Nullable [] arr, int elt) {
1418    if (arr == null) {
1419      return false;
1420    }
1421    for (int i = 0 ; i < arr.length ; i++) {
1422      if (gte(arr[i], elt)) {
1423        return false;
1424      }
1425    }
1426    return true;
1427  }
1428
1429  /** True iff every element in arr is less than or equal to elt.
1430   *
1431   * Meaning (in pseudo-FOL):
1432   *
1433   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
1434   *
1435   */
1436  @EnsuresNonNullIf(result=true, expression="#1")
1437  @Pure
1438  public static boolean eltsLTE(byte @Nullable [] arr, byte elt) {
1439    if (arr == null) {
1440      return false;
1441    }
1442    for (int i = 0 ; i < arr.length ; i++) {
1443      if (gt(arr[i], elt)) {
1444        return false;
1445      }
1446    }
1447    return true;
1448  }
1449
1450  @EnsuresNonNullIf(result=true, expression="#1")
1451  @Pure
1452  public static boolean eltsLTE(byte @Nullable [] arr, int elt) {
1453    if (arr == null) {
1454      return false;
1455    }
1456    for (int i = 0 ; i < arr.length ; i++) {
1457      if (gt(arr[i], elt)) {
1458        return false;
1459      }
1460    }
1461    return true;
1462  }
1463
1464  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
1465   *
1466   * Meaning (in pseudo-FOL):
1467   *
1468   * /\ seq1.length == se2.length
1469   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
1470   *
1471   */
1472
1473  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1474  @Pure
1475  public static boolean pairwiseEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1476    if (!sameLength(seq1, seq2)) {
1477      return false;
1478    }
1479    assert seq1 != null && seq2 != null; // because sameLength() = true
1480    for (int i = 0 ; i < seq1.length ; i++) {
1481      if (ne(seq1[i], seq2[i])) {
1482        return false;
1483      }
1484    }
1485    return true;
1486  }
1487
1488  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1489  @Pure
1490  public static boolean pairwiseEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1491    if (!sameLength(seq1, seq2)) {
1492      return false;
1493    }
1494    assert seq1 != null && seq2 != null; // because sameLength() = true
1495    for (int i = 0 ; i < seq1.length ; i++) {
1496      if (ne(seq1[i], seq2[i])) {
1497        return false;
1498      }
1499    }
1500    return true;
1501  }
1502
1503  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
1504   *
1505   * Meaning (in pseudo-FOL):
1506   *
1507   * /\ seq1.length == se2.length
1508   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
1509   *
1510   */
1511  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1512  @Pure
1513  public static boolean pairwiseNotEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1514    if (!sameLength(seq1, seq2)) {
1515      return false;
1516    }
1517    assert seq1 != null && seq2 != null; // because sameLength() = true
1518    for (int i = 0 ; i < seq1.length ; i++) {
1519      if (eq(seq1[i], seq2[i])) {
1520        return false;
1521      }
1522    }
1523    return true;
1524  }
1525
1526  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1527  @Pure
1528  public static boolean pairwiseNotEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1529    if (!sameLength(seq1, seq2)) {
1530      return false;
1531    }
1532    assert seq1 != null && seq2 != null; // because sameLength() = true
1533    for (int i = 0 ; i < seq1.length ; i++) {
1534      if (eq(seq1[i], seq2[i])) {
1535        return false;
1536      }
1537    }
1538    return true;
1539  }
1540
1541  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
1542   *
1543   * Meaning (in pseudo-FOL):
1544   *
1545   * /\ seq1.length == se2.length
1546   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
1547   *
1548   */
1549  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1550  @Pure
1551  public static boolean pairwiseLT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1552    if (!sameLength(seq1, seq2)) {
1553      return false;
1554    }
1555    assert seq1 != null && seq2 != null; // because sameLength() = true
1556    for (int i = 0 ; i < seq1.length ; i++) {
1557      if (gte(seq1[i], seq2[i])) {
1558        return false;
1559      }
1560    }
1561    return true;
1562  }
1563
1564  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1565  @Pure
1566  public static boolean pairwiseLT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1567    if (!sameLength(seq1, seq2)) {
1568      return false;
1569    }
1570    assert seq1 != null && seq2 != null; // because sameLength() = true
1571    for (int i = 0 ; i < seq1.length ; i++) {
1572      if (gte(seq1[i], seq2[i])) {
1573        return false;
1574      }
1575    }
1576    return true;
1577  }
1578
1579  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
1580   * Meaning (in pseudo-FOL):
1581   *
1582   * /\ seq1.length == se2.length
1583   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
1584   *
1585   */
1586  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1587  @Pure
1588  public static boolean pairwiseLTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1589    if (!sameLength(seq1, seq2)) {
1590      return false;
1591    }
1592    assert seq1 != null && seq2 != null; // because sameLength() = true
1593    for (int i = 0 ; i < seq1.length ; i++) {
1594      if (gt(seq1[i], seq2[i])) {
1595        return false;
1596      }
1597    }
1598    return true;
1599  }
1600
1601  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1602  @Pure
1603  public static boolean pairwiseLTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1604    if (!sameLength(seq1, seq2)) {
1605      return false;
1606    }
1607    assert seq1 != null && seq2 != null; // because sameLength() = true
1608    for (int i = 0 ; i < seq1.length ; i++) {
1609      if (gt(seq1[i], seq2[i])) {
1610        return false;
1611      }
1612    }
1613    return true;
1614  }
1615
1616  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
1617   * Meaning (in pseudo-FOL):
1618   *
1619   * /\ seq1.length == se2.length
1620   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
1621   *
1622   */
1623  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1624  @Pure
1625  public static boolean pairwiseGT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1626    if (!sameLength(seq1, seq2)) {
1627      return false;
1628    }
1629    assert seq1 != null && seq2 != null; // because sameLength() = true
1630    for (int i = 0 ; i < seq1.length ; i++) {
1631      if (lte(seq1[i], seq2[i])) {
1632        return false;
1633      }
1634    }
1635    return true;
1636  }
1637
1638  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1639  @Pure
1640  public static boolean pairwiseGT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1641    if (!sameLength(seq1, seq2)) {
1642      return false;
1643    }
1644    assert seq1 != null && seq2 != null; // because sameLength() = true
1645    for (int i = 0 ; i < seq1.length ; i++) {
1646      if (lte(seq1[i], seq2[i])) {
1647        return false;
1648      }
1649    }
1650    return true;
1651  }
1652
1653  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
1654   * Meaning (in pseudo-FOL):
1655   *
1656   * /\ seq1.length == se2.length
1657   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
1658   *
1659   */
1660  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1661  @Pure
1662  public static boolean pairwiseGTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1663    if (!sameLength(seq1, seq2)) {
1664      return false;
1665    }
1666    assert seq1 != null && seq2 != null; // because sameLength() = true
1667    for (int i = 0 ; i < seq1.length ; i++) {
1668      if (lt(seq1[i], seq2[i])) {
1669        return false;
1670      }
1671    }
1672    return true;
1673  }
1674
1675  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1676  @Pure
1677  public static boolean pairwiseGTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1678    if (!sameLength(seq1, seq2)) {
1679      return false;
1680    }
1681    assert seq1 != null && seq2 != null; // because sameLength() = true
1682    for (int i = 0 ; i < seq1.length ; i++) {
1683      if (lt(seq1[i], seq2[i])) {
1684        return false;
1685      }
1686    }
1687    return true;
1688  }
1689
1690  /**
1691   * Returns true iff seq1 is lexically equal to seq2.
1692   * For equality, "lexically" and "pairwise" are the same.
1693   */
1694  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1695  @Pure
1696  public static boolean lexEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1697    if (seq1 == null) {
1698      return false;
1699    }
1700    if (seq2 == null) {
1701      return false;
1702    }
1703    return pairwiseEqual(seq1, seq2);
1704  }
1705
1706  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1707  @Pure
1708  public static boolean lexEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1709    if (seq1 == null) {
1710      return false;
1711    }
1712    if (seq2 == null) {
1713      return false;
1714    }
1715    return pairwiseEqual(seq1, seq2);
1716  }
1717
1718  /** Returns true iff seq1 is lexically not equal to seq2. */
1719  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1720  @Pure
1721  public static boolean lexNotEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1722    if (seq1 == null) {
1723      return false;
1724    }
1725    if (seq2 == null) {
1726      return false;
1727    }
1728    return !lexEqual(seq1, seq2);
1729  }
1730
1731  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1732  @Pure
1733  public static boolean lexNotEqual(byte @Nullable [] seq1, int @Nullable [] seq2) {
1734    if (seq1 == null) {
1735      return false;
1736    }
1737    if (seq2 == null) {
1738      return false;
1739    }
1740    return !lexEqual(seq1, seq2);
1741  }
1742
1743  /** Returns true iff seq1 is lexically &lt;  seq2. */
1744  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1745  @Pure
1746  public static boolean lexLT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1747    if (seq1 == null) {
1748      return false;
1749    }
1750    if (seq2 == null) {
1751      return false;
1752    }
1753    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1754    for (int i = 0 ; i < minlength ; i++) {
1755      if (gt(seq1[i], seq2[i])) {
1756        return false;
1757      } else if (lt(seq1[i], seq2[i])) {
1758        return true;
1759      }
1760    }
1761    if (seq1.length >= seq2.length) {
1762      return false;
1763    }
1764    return true;
1765  }
1766
1767  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1768  @Pure
1769  public static boolean lexLT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1770    if (seq1 == null) {
1771      return false;
1772    }
1773    if (seq2 == null) {
1774      return false;
1775    }
1776    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1777    for (int i = 0 ; i < minlength ; i++) {
1778      if (gt(seq1[i], seq2[i])) {
1779        return false;
1780        } else if (lt(seq1[i], seq2[i])) {
1781          return true;
1782        }
1783      }
1784      if (seq1.length >= seq2.length) {
1785        return false;
1786      }
1787      return true;
1788    }
1789
1790  /** Returns true iff seq1 is lexically &le; to seq2. */
1791  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1792  @Pure
1793  public static boolean lexLTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1794    if (seq1 == null) {
1795      return false;
1796    }
1797    if (seq2 == null) {
1798      return false;
1799    }
1800    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1801    for (int i = 0 ; i < minlength ; i++) {
1802      if (gt(seq1[i], seq2[i])) {
1803        return false;
1804      } else if (lt(seq1[i], seq2[i])) {
1805        return true;
1806      }
1807    }
1808    if (seq1.length > seq2.length) {
1809      return false;
1810    }
1811    return true;
1812  }
1813
1814  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1815  @Pure
1816  public static boolean lexLTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1817  if (seq1 == null) {
1818    return false;
1819  }
1820  if (seq2 == null) {
1821    return false;
1822  }
1823    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1824    for (int i = 0 ; i < minlength ; i++) {
1825      if (gt(seq1[i], seq2[i])) {
1826        return false;
1827      } else if (lt(seq1[i], seq2[i])) {
1828        return true;
1829      }
1830    }
1831    if (seq1.length > seq2.length) {
1832      return false;
1833    }
1834    return true;
1835  }
1836
1837  /** Returns true iff seq1 is lexically &gt; to seq2. */
1838  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1839  @Pure
1840  public static boolean lexGT(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1841  if (seq1 == null) {
1842    return false;
1843  }
1844  if (seq2 == null) {
1845    return false;
1846  }
1847    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1848    for (int i = 0 ; i < minlength ; i++) {
1849      if (lt(seq1[i], seq2[i])) {
1850        return false;
1851      } else if (gt(seq1[i], seq2[i])) {
1852        return true;
1853      }
1854    }
1855    if (seq1.length <= seq2.length) {
1856      return false;
1857    }
1858    return true;
1859  }
1860
1861  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1862  @Pure
1863  public static boolean lexGT(byte @Nullable [] seq1, int @Nullable [] seq2) {
1864  if (seq1 == null) {
1865    return false;
1866  }
1867  if (seq2 == null) {
1868    return false;
1869  }
1870    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1871    for (int i = 0 ; i < minlength ; i++) {
1872      if (lt(seq1[i], seq2[i])) {
1873        return false;
1874      } else if (gt(seq1[i], seq2[i])) {
1875        return true;
1876      }
1877    }
1878    if (seq1.length <= seq2.length) {
1879      return false;
1880    }
1881    return true;
1882  }
1883
1884  /** Returns true iff seq1 is lexically &ge; to seq2. */
1885  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1886  @Pure
1887  public static boolean lexGTE(byte @Nullable [] seq1, byte @Nullable [] seq2) {
1888  if (seq1 == null) {
1889    return false;
1890  }
1891  if (seq2 == null) {
1892    return false;
1893  }
1894    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1895    for (int i = 0 ; i < minlength ; i++) {
1896      if (lt(seq1[i], seq2[i])) {
1897        return false;
1898      } else if (gt(seq1[i], seq2[i])) {
1899        return true;
1900      }
1901    }
1902    if (seq1.length < seq2.length) {
1903      return false;
1904    }
1905    return true;
1906  }
1907
1908  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
1909  @Pure
1910  public static boolean lexGTE(byte @Nullable [] seq1, int @Nullable [] seq2) {
1911  if (seq1 == null) {
1912    return false;
1913  }
1914  if (seq2 == null) {
1915    return false;
1916  }
1917    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
1918    for (int i = 0 ; i < minlength ; i++) {
1919      if (lt(seq1[i], seq2[i])) {
1920        return false;
1921      } else if (gt(seq1[i], seq2[i])) {
1922        return true;
1923      }
1924    }
1925    if (seq1.length < seq2.length) {
1926      return false;
1927    }
1928    return true;
1929  }
1930
1931  /** True iff for all applicable i, every seq[i] == seq[i+1].
1932   *
1933   * Meaning (in pseudo-FOL):
1934   *
1935   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
1936   *
1937   */
1938  @EnsuresNonNullIf(result=true, expression="#1")
1939  @Pure
1940  public static boolean eltwiseEqual(byte @Nullable [] seq) {
1941  if (seq == null) {
1942    return false;
1943  }
1944    for (int i = 0 ; i < seq.length ; i++) {
1945      if (i < seq.length - 1) {
1946        if (ne(seq[i], seq[i + 1])) {
1947          return false;
1948        }
1949      }
1950    }
1951    return true;
1952  }
1953
1954  /** True iff for all applicable i, every seq[i] != seq[i+1].
1955   *
1956   * Meaning (in pseudo-FOL):
1957   *
1958   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
1959   *
1960   */
1961  @EnsuresNonNullIf(result=true, expression="#1")
1962  @Pure
1963  public static boolean eltwiseNotEqual(byte @Nullable [] seq) {
1964  if (seq == null) {
1965    return false;
1966  }
1967    for (int i = 0 ; i < seq.length ; i++) {
1968      if (i < seq.length - 1) {
1969        if (eq(seq[i], seq[i + 1])) {
1970          return false;
1971        }
1972      }
1973    }
1974    return true;
1975  }
1976
1977  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
1978   *
1979   * Meaning (in pseudo-FOL):
1980   *
1981   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
1982   *
1983   */
1984  @EnsuresNonNullIf(result=true, expression="#1")
1985  @Pure
1986  public static boolean eltwiseLT(byte @Nullable [] seq) {
1987  if (seq == null) {
1988    return false;
1989  }
1990    for (int i = 0 ; i < seq.length ; i++) {
1991      if (i < seq.length - 1) {
1992        if (gte(seq[i], seq[i + 1])) {
1993          return false;
1994        }
1995      }
1996    }
1997    return true;
1998  }
1999
2000  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
2001   *
2002   * Meaning (in pseudo-FOL):
2003   *
2004   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
2005   *
2006   */
2007  @EnsuresNonNullIf(result=true, expression="#1")
2008  @Pure
2009  public static boolean eltwiseLTE(byte @Nullable [] seq) {
2010  if (seq == null) {
2011    return false;
2012  }
2013    for (int i = 0 ; i < seq.length ; i++) {
2014      if (i < seq.length - 1) {
2015        if (gt(seq[i], seq[i + 1])) {
2016          return false;
2017        }
2018      }
2019    }
2020    return true;
2021  }
2022
2023  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
2024   *
2025   * Meaning (in pseudo-FOL):
2026   *
2027   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
2028   *
2029   */
2030  @EnsuresNonNullIf(result=true, expression="#1")
2031  @Pure
2032  public static boolean eltwiseGT(byte @Nullable [] seq) {
2033  if (seq == null) {
2034    return false;
2035  }
2036    for (int i = 0 ; i < seq.length ; i++) {
2037      if (i < seq.length - 1) {
2038        if (lte(seq[i], seq[i + 1])) {
2039          return false;
2040        }
2041      }
2042    }
2043    return true;
2044  }
2045
2046  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
2047   *
2048   * Meaning (in pseudo-FOL):
2049   *
2050   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
2051   *
2052   */
2053  @EnsuresNonNullIf(result=true, expression="#1")
2054  @Pure
2055  public static boolean eltwiseGTE(byte @Nullable [] seq) {
2056  if (seq == null) {
2057    return false;
2058  }
2059    for (int i = 0 ; i < seq.length ; i++) {
2060      if (i < seq.length - 1) {
2061        if (lt(seq[i], seq[i + 1])) {
2062          return false;
2063        }
2064      }
2065    }
2066    return true;
2067  }
2068
2069  /** True iff for all applicable i, every seq[i] == i.
2070   *
2071   * Meaning (in pseudo-FOL):
2072   *
2073   * forall i in { 0..seq.length-1 } : seq[i] == i
2074   *
2075   */
2076  @EnsuresNonNullIf(result=true, expression="#1")
2077  @Pure
2078  public static boolean eltsEqualIndex(byte @Nullable [] seq) {
2079  if (seq == null) {
2080    return false;
2081  }
2082    for (int i = 0 ; i < seq.length ; i++) {
2083      if (ne(seq[i], i)) {
2084        return false;
2085      }
2086    }
2087    return true;
2088  }
2089
2090  /** True iff for all applicable i, every seq[i] != i.
2091   *
2092   * Meaning (in pseudo-FOL):
2093   *
2094   * forall i in { 0..seq.length-1 } : seq[i] != i
2095   *
2096   */
2097  @EnsuresNonNullIf(result=true, expression="#1")
2098  @Pure
2099  public static boolean eltsNotEqualIndex(byte @Nullable [] seq) {
2100  if (seq == null) {
2101    return false;
2102  }
2103    for (int i = 0 ; i < seq.length ; i++) {
2104      if (eq(seq[i], i)) {
2105        return false;
2106      }
2107    }
2108    return true;
2109  }
2110
2111  /** True iff for all applicable i, every seq[i] &lt; i.
2112   *
2113   * Meaning (in pseudo-FOL):
2114   *
2115   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
2116   *
2117   */
2118  @EnsuresNonNullIf(result=true, expression="#1")
2119  @Pure
2120  public static boolean eltsLtIndex(byte @Nullable [] seq) {
2121  if (seq == null) {
2122    return false;
2123  }
2124    for (int i = 0 ; i < seq.length ; i++) {
2125      if (gte(seq[i], i)) {
2126        return false;
2127      }
2128    }
2129    return true;
2130  }
2131
2132  /** True iff for all applicable i, every seq[i] &le; i.
2133   *
2134   * Meaning (in pseudo-FOL):
2135   *
2136   * forall i in { 0..seq.length-1 } : seq[i] &le; i
2137   *
2138   */
2139  @EnsuresNonNullIf(result=true, expression="#1")
2140  @Pure
2141  public static boolean eltsLteIndex(byte @Nullable [] seq) {
2142  if (seq == null) {
2143    return false;
2144  }
2145    for (int i = 0 ; i < seq.length ; i++) {
2146      if (gt(seq[i], i)) {
2147        return false;
2148      }
2149    }
2150    return true;
2151  }
2152
2153  /** True iff for all applicable i, every seq[i] &gt; i.
2154   *
2155   * Meaning (in pseudo-FOL):
2156   *
2157   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
2158   *
2159   */
2160  @EnsuresNonNullIf(result=true, expression="#1")
2161  @Pure
2162  public static boolean eltsGtIndex(byte @Nullable [] seq) {
2163  if (seq == null) {
2164    return false;
2165  }
2166    for (int i = 0 ; i < seq.length ; i++) {
2167      if (lte(seq[i], i)) {
2168        return false;
2169      }
2170    }
2171    return true;
2172  }
2173
2174  /** True iff for all applicable i, every seq[i] &ge; i.
2175   *
2176   * Meaning (in pseudo-FOL):
2177   *
2178   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
2179   *
2180   */
2181  @EnsuresNonNullIf(result=true, expression="#1")
2182  @Pure
2183  public static boolean eltsGteIndex(byte @Nullable [] seq) {
2184  if (seq == null) {
2185    return false;
2186  }
2187    for (int i = 0 ; i < seq.length ; i++) {
2188      if (lt(seq[i], i)) {
2189        return false;
2190      }
2191    }
2192    return true;
2193  }
2194
2195  // Deferencing (accessing) fields
2196
2197  /**
2198   * collectbyte accepts an object and a list of fields (one of which is of array type, and the
2199   * rest of which are not), and produces an array in which the original object has had the given
2200   * fields accessed.
2201   *
2202   * <p>Daikon creates invariants over "variables" such as the following.
2203   *
2204   * <dl>
2205   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
2206   *              for all y's in array x.arr.</dd>
2207   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
2208   *              for all x's in array arr.</dd>
2209   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
2210   * </dl>
2211   *
2212   * <p>The collectbyte() method does this collecting work.
2213   *
2214   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
2215   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
2216   * elements that result from following the fields, one of which is assumed to be an array.
2217   *
2218   * <p>
2219   * requires: fieldStr.length() &gt; 0 and object != null
2220   * <p>
2221   * requires: fieldStr contains only field names, no "[]" strings.
2222   * <p>
2223   * requires: the method only works for field sequences with exactly one field representing an
2224   * array. For example, the collection a[].b[].c will fail.
2225   *
2226   * @return if the resulting collection is of non-primitive type, then returns an array of type
2227   * Object[]. Returns null if any array or field access causes an exception.
2228   */
2229
2230  @SideEffectFree
2231  public static byte @Nullable [] collectbyte(@Nullable Object object, @Nullable String fieldStr) {
2232
2233    if (object == null) {
2234      return null;
2235    }
2236    if (fieldStr == null) {
2237      return null;
2238    }
2239
2240    // assert fieldStr != null && !"".equals(fieldStr);
2241    String[] fieldNames = fieldStr.split("\\.");
2242    byte[] retval = collectbyte(object, fieldNames, 0);
2243    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
2244    return retval;
2245  }
2246
2247  // @PolyNull does not work for return type, because null is returned on error.
2248  /** Helper method for collectbyte(Object, String).
2249   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
2250   * @see collectbyte(Object, String)
2251   */
2252
2253  @SideEffectFree
2254  private static byte @Nullable [] collectbyte(@Nullable Object object,
2255                                                   String[] fields, int fieldsStartIdx) {
2256
2257    if (object == null) {
2258      return null;
2259    }
2260    assert (fields != null);
2261    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
2262
2263    Object fieldObj;
2264    try {
2265      Field field = (object instanceof java.lang.Class<?>)
2266        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
2267        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
2268      field.setAccessible(true);
2269      // Class cls = field.getType();
2270      fieldObj = field.get(object);
2271      // System.out.println("***fieldObj="+fieldObj);
2272
2273    } catch (Exception e) {
2274      return null;
2275
2276    }
2277
2278    if (fieldObj == null) {
2279      return null;
2280    }
2281
2282    // base case: just accessed the last field
2283    if (fields.length - 1 == fieldsStartIdx) {
2284
2285      if (fieldObj.getClass().isArray()) {
2286        // last field is an array
2287        return (byte[])fieldObj;
2288      } else {
2289        // This hack should be removed in favor of, at "oneEltArray = ..."
2290        // below, calling a version of collectbyte_field that throws an
2291        // error.  Then, this case becomes a run-time error.  -MDE
2292
2293        // Just one element; return a one-element array.
2294        // assert cls.equals(Byte.TYPE);
2295        return new byte[] { ((Byte)fieldObj).byteValue() };
2296      }
2297    } else {
2298      // recursive case: more fields to access after this one
2299
2300      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
2301
2302        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
2303        byte[] intermediate = new byte[collection.size()];
2304        int index = 0;
2305        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
2306          Object obj = i.next();
2307          byte[] oneEltArray = collectbyte(obj, fields, fieldsStartIdx + 1);
2308          if (oneEltArray == null) {
2309            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
2310          }
2311          // assert oneEltArray.length == 1;
2312          intermediate[index++] = oneEltArray[0];
2313        }
2314        return intermediate;
2315      } else if (fieldObj.getClass().isArray()) {
2316
2317        // collect elements across array
2318        byte[] intermediate = new byte[Array.getLength(fieldObj)];
2319        for (int i = 0 ; i < intermediate.length ; i++) {
2320          Object obj = Array.get(fieldObj, i);
2321          byte[] oneEltArray = collectbyte(obj, fields, fieldsStartIdx + 1);
2322          if (oneEltArray == null) {
2323            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
2324          }
2325          // assert oneEltArray.length == 1;
2326          intermediate[i] = oneEltArray[0];
2327        }
2328        return intermediate;
2329      } else {
2330
2331        return collectbyte(fieldObj, fields, fieldsStartIdx + 1);
2332      }
2333    }
2334  }
2335
2336  /**
2337   * Returns the results of dereferencing the fields for 'object'. For example, the call
2338   *
2339   * <pre>collectbyte_field(x, "f.g.h")</pre>
2340   *
2341   * has the same value as
2342   *
2343   * <pre>x.f.g.h</pre>.
2344   * Returns a default value if any field access causes an exception.
2345   */
2346  @SideEffectFree
2347  public static byte collectbyte_field(Object object, String fieldStr) {
2348
2349    if (object == null) {
2350      return Byte.MAX_VALUE; // return default value
2351    }
2352    if (fieldStr == null) {
2353      return Byte.MAX_VALUE; // return default value
2354    }
2355
2356    String[] fieldNames = fieldStr.split("\\.");
2357
2358    // Holds the intermediate (and final) result
2359    Object fieldObj = object;
2360
2361    for (int i = 0 ; i < fieldNames.length ; i++) {
2362
2363      String fieldName = fieldNames[i];
2364
2365      try {
2366        Field field =
2367          (fieldObj instanceof java.lang.Class<?>)
2368          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
2369          : fieldObj.getClass().getDeclaredField(fieldName);
2370        field.setAccessible(true);
2371        fieldObj = field.get(fieldObj);
2372
2373        if (fieldObj == null) {
2374          return Byte.MAX_VALUE; // return default value
2375        }
2376
2377      } catch (Exception e) {
2378        return Byte.MAX_VALUE; // return default value
2379
2380      }
2381
2382    }
2383
2384    return ((Byte)fieldObj).byteValue();
2385  }
2386
2387  // ///////////////////////////////////////////////////////////////////////////
2388  // Methods for "char" (from QuantBody.java.jpp)
2389  //
2390
2391  /**
2392   * Returns the ith element of the array or collection argument. If the argument is null or not an
2393   * array or collection, returns a default value (Character.MAX_VALUE).
2394   */
2395
2396  @Pure
2397  public static char getElement_char(Object o, long i) {
2398    if (o == null) {
2399      return Character.MAX_VALUE; // return default value
2400    }
2401    java.lang.Class<?> c = o.getClass();
2402    if (c.isArray()) {
2403      return java.lang.reflect.Array.getChar(o, (int)i);
2404    } else if (o instanceof java.util.AbstractCollection<?>) {
2405      return java.lang.reflect.Array.getChar(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
2406    } else {
2407      return Character.MAX_VALUE; // return default value
2408    }
2409  }
2410
2411  @Pure
2412  public static char getElement_char(char[] arr, long i) {
2413    if (arr == null) {
2414      return Character.MAX_VALUE; // return default value
2415    }
2416    return arr[(int)i];
2417  }
2418
2419  private static boolean eq(char x, char y) {
2420    return x == y;
2421  }
2422
2423  private static boolean ne(char x, char y) {
2424    return x != y;
2425  }
2426
2427  private static boolean lt(char x, char y) {
2428    return x < y;
2429  }
2430
2431  private static boolean lte(char x, char y) {
2432    return x <= y;
2433  }
2434
2435  private static boolean gt(char x, char y) {
2436    return x > y;
2437  }
2438
2439  private static boolean gte(char x, char y) {
2440    return x >= y;
2441  }
2442
2443  /** True iff both sequences are non-null and have the same length. */
2444  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
2445  @Pure
2446  public static boolean sameLength(char @Nullable [] seq1, char @Nullable [] seq2) {
2447    return ((seq1 != null)
2448            && (seq2 != null)
2449            && seq1.length == seq2.length);
2450  }
2451
2452  /**
2453   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
2454   *
2455   * <p>If either array is null, returns null. If either array is empty, returns only those
2456   * elements in the other array. If both arrays are empty, returns a new empty array.
2457   */
2458  @SideEffectFree
2459  public static char @PolyNull [] concat(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2460    if (seq1 == null) {
2461      return null;
2462    }
2463    if (seq2 == null) {
2464      return null;
2465    }
2466    return ArraysPlume.concat(seq1, seq2);
2467  }
2468
2469  /**
2470   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
2471   * assurances about the order or repetition of elements: elements may be repeated, and their
2472   * order may be different from the order of elements in seq1 and seq2.
2473   */
2474  @SideEffectFree
2475  public static char @PolyNull [] union(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2476    if (seq1 == null) {
2477      return null;
2478    }
2479    if (seq2 == null) {
2480      return null;
2481    }
2482    return concat(seq1, seq2);
2483  }
2484
2485  /**
2486   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
2487   * gives no assurances about the order or repetition of elements: elements may be repeated, and
2488   * their order may be different from the order of elements in seq1 and seq2.
2489   */
2490  @Pure
2491  public static char @PolyNull [] intersection(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2492    if (seq1 == null) {
2493      return null;
2494    }
2495    if (seq2 == null) {
2496      return null;
2497    }
2498    char[] intermediate = new char[Math.min(seq1.length, seq2.length)];
2499    int length = 0;
2500    for (int i = 0 ; i < seq1.length ; i++) {
2501      if (memberOf(seq1[i], seq2) ) {
2502        intermediate[length++] = seq1[i];
2503      }
2504    }
2505    return ArraysPlume.subarray(intermediate, 0, length);
2506  }
2507
2508  /**
2509   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
2510   * no assurances about the order or repetition of elements: elements may be repeated, and their
2511   * order may be different from the order of elements in seq1 and seq2.
2512   */
2513  @Pure
2514  public static char @PolyNull [] setDiff(char @PolyNull [] seq1, char @PolyNull [] seq2) {
2515    if (seq1 == null) {
2516      return null;
2517    }
2518    if (seq2 == null) {
2519      return null;
2520    }
2521    char[] intermediate = new char[seq1.length];
2522    int length = 0;
2523    for (int i = 0 ; i < seq1.length ; i++) {
2524      if (!memberOf(seq1[i], seq2)) {
2525        intermediate[length++] = seq1[i];
2526      }
2527    }
2528    return ArraysPlume.subarray(intermediate, 0, length);
2529  }
2530
2531  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
2532  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2533  @Pure
2534  public static boolean setEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2535    if (seq1 == null) {
2536      return false;
2537    }
2538    if (seq2 == null) {
2539      return false;
2540    }
2541    for (int i = 0; i < seq1.length ; i++) {
2542      if (!memberOf(seq1[i], seq2) ) {
2543        return false;
2544      }
2545    }
2546    for (int i = 0; i < seq2.length ; i++) {
2547      if (!memberOf(seq2[i], seq1) ) {
2548        return false;
2549      }
2550    }
2551    return true;
2552  }
2553
2554  /** True iff seq1 is the reverse of seq2.
2555   *
2556   * Meaning (in pseudo-FOL):
2557   *
2558   * <pre>
2559   * /\ seq1.length == seq2.length
2560   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
2561   * </pre>
2562   *
2563   */
2564  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2565  @Pure
2566  public static boolean isReverse(char[] seq1, char[] seq2) {
2567    if (!sameLength(seq1, seq2)) {
2568      return false;
2569    }
2570    assert seq1 != null && seq2 != null; // because sameLength() = true
2571    int length = seq1.length;
2572    for (int i = 0 ; i < length ; i++) {
2573      if (ne(seq1[i], seq2[length - i - 1])) {
2574        return false;
2575      }
2576    }
2577    return true;
2578  }
2579
2580  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
2581  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2582  @Pure
2583  public static boolean subsetOf(char @Nullable [] seq1, char @Nullable [] seq2) {
2584    if (seq1 == null) {
2585      return false;
2586    }
2587    if (seq2 == null) {
2588      return false;
2589    }
2590    for (int i = 0 ; i < seq1.length ; i++) {
2591      if (!memberOf(seq1[i], seq2)) {
2592        return false;
2593      }
2594    }
2595    return true;
2596  }
2597
2598  /** Returns true iff seq contains no duplicate elements. */
2599  @EnsuresNonNullIf(result=true, expression="#1")
2600  @Pure
2601  public static boolean noDups(char @Nullable [] seq) {
2602    if (seq == null) {
2603      return false;
2604    }
2605    return ArraysPlume.hasNoDuplicates(seq);
2606  }
2607
2608 /** Returns true iff elt is in array arr. */
2609  @EnsuresNonNullIf(result=true, expression="#2")
2610  @Pure
2611  public static boolean memberOf(char elt, char @Nullable [] arr) {
2612    if (arr == null) {
2613      return false;
2614    }
2615    for (int i = 0 ; i < arr.length ; i++) {
2616      if (eq(arr[i], elt)) {
2617        return true;
2618      }
2619    }
2620    return false;
2621  }
2622
2623  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
2624  @Pure
2625  public static char @PolyNull [] slice(char @PolyNull [] seq, int start, int end) {
2626    if (seq == null) {
2627      return null;
2628    }
2629    int sliceStart = start;
2630    int sliceEnd = end;
2631    if (start < 0) {
2632      return new char[] { };
2633    }
2634    if (end > seq.length - 1) {
2635      return new char[] { };
2636    }
2637    if (sliceStart > sliceEnd) {
2638      return new char[] { };
2639    }
2640    int length = sliceEnd - sliceStart + 1;
2641    return ArraysPlume.subarray(seq, sliceStart, length);
2642  }
2643
2644  @Pure
2645  public static char @PolyNull [] slice(char @PolyNull [] seq, long start, int end) {
2646    return slice(seq, (int)start, end);
2647  }
2648  @Pure
2649  public static char @PolyNull [] slice(char @PolyNull [] seq, int start, long end) {
2650    return slice(seq, start, (int)end);
2651  }
2652  @Pure
2653  public static char @PolyNull [] slice(char @PolyNull [] seq, long start, long end) {
2654    return slice(seq, (int)start, (int)end);
2655  }
2656
2657  /** True iff all elements in arr equal elt.
2658   *
2659   * Meaning (in pseudo-FOL):
2660   *
2661   * forall i in { 0..arr.length-1 } : arr[i] == elt
2662   *
2663   */
2664  @EnsuresNonNullIf(result=true, expression="#1")
2665  @Pure
2666  public static boolean eltsEqual(char @Nullable [] arr, char elt) {
2667    if (arr == null) {
2668      return false;
2669    }
2670    for (int i = 0 ; i < arr.length ; i++) {
2671      if (ne(arr[i], elt)) {
2672        return false;
2673      }
2674    }
2675    return true;
2676  }
2677
2678  /** True iff every element in arr does not equal elt.
2679   *
2680   * Meaning (in pseudo-FOL):
2681   *
2682   * forall i in { 0..arr.length-1 } : arr[i] != elt
2683   *
2684   */
2685  @EnsuresNonNullIf(result=true, expression="#1")
2686  @Pure
2687  public static boolean eltsNotEqual(char @Nullable [] arr, char elt) {
2688    if (arr == null) {
2689      return false;
2690    }
2691    for (int i = 0 ; i < arr.length ; i++) {
2692      if (eq(arr[i], elt)) {
2693        return false;
2694      }
2695    }
2696    return true;
2697  }
2698
2699  /** True iff every element in arr is greater than elt.
2700   *
2701   * Meaning (in pseudo-FOL):
2702   *
2703   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
2704   *
2705   */
2706  @EnsuresNonNullIf(result=true, expression="#1")
2707  @Pure
2708  public static boolean eltsGT(char @Nullable [] arr, char elt) {
2709    if (arr == null) {
2710      return false;
2711    }
2712    for (int i = 0 ; i < arr.length ; i++) {
2713      if (lte(arr[i], elt)) {
2714        return false;
2715      }
2716    }
2717    return true;
2718  }
2719
2720  /** True iff every element in arr is greater than or equal to elt.
2721   *
2722   * Meaning (in pseudo-FOL):
2723   *
2724   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
2725   *
2726   */
2727  @EnsuresNonNullIf(result=true, expression="#1")
2728  @Pure
2729  public static boolean eltsGTE(char @Nullable [] arr, char elt) {
2730    if (arr == null) {
2731      return false;
2732    }
2733    for (int i = 0 ; i < arr.length ; i++) {
2734      if (lt(arr[i], elt)) {
2735        return false;
2736      }
2737    }
2738    return true;
2739  }
2740
2741  /** True iff every element in arr is less than elt.
2742   *
2743   * Meaning (in pseudo-FOL):
2744   *
2745   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
2746   *
2747   */
2748  @EnsuresNonNullIf(result=true, expression="#1")
2749  @Pure
2750  public static boolean eltsLT(char @Nullable [] arr, char elt) {
2751    if (arr == null) {
2752      return false;
2753    }
2754    for (int i = 0 ; i < arr.length ; i++) {
2755      if (gte(arr[i], elt)) {
2756        return false;
2757      }
2758    }
2759    return true;
2760  }
2761
2762  /** True iff every element in arr is less than or equal to elt.
2763   *
2764   * Meaning (in pseudo-FOL):
2765   *
2766   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
2767   *
2768   */
2769  @EnsuresNonNullIf(result=true, expression="#1")
2770  @Pure
2771  public static boolean eltsLTE(char @Nullable [] arr, char elt) {
2772    if (arr == null) {
2773      return false;
2774    }
2775    for (int i = 0 ; i < arr.length ; i++) {
2776      if (gt(arr[i], elt)) {
2777        return false;
2778      }
2779    }
2780    return true;
2781  }
2782
2783  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
2784   *
2785   * Meaning (in pseudo-FOL):
2786   *
2787   * /\ seq1.length == se2.length
2788   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
2789   *
2790   */
2791
2792  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2793  @Pure
2794  public static boolean pairwiseEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2795    if (!sameLength(seq1, seq2)) {
2796      return false;
2797    }
2798    assert seq1 != null && seq2 != null; // because sameLength() = true
2799    for (int i = 0 ; i < seq1.length ; i++) {
2800      if (ne(seq1[i], seq2[i])) {
2801        return false;
2802      }
2803    }
2804    return true;
2805  }
2806
2807  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
2808   *
2809   * Meaning (in pseudo-FOL):
2810   *
2811   * /\ seq1.length == se2.length
2812   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
2813   *
2814   */
2815  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2816  @Pure
2817  public static boolean pairwiseNotEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2818    if (!sameLength(seq1, seq2)) {
2819      return false;
2820    }
2821    assert seq1 != null && seq2 != null; // because sameLength() = true
2822    for (int i = 0 ; i < seq1.length ; i++) {
2823      if (eq(seq1[i], seq2[i])) {
2824        return false;
2825      }
2826    }
2827    return true;
2828  }
2829
2830  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
2831   *
2832   * Meaning (in pseudo-FOL):
2833   *
2834   * /\ seq1.length == se2.length
2835   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
2836   *
2837   */
2838  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2839  @Pure
2840  public static boolean pairwiseLT(char @Nullable [] seq1, char @Nullable [] seq2) {
2841    if (!sameLength(seq1, seq2)) {
2842      return false;
2843    }
2844    assert seq1 != null && seq2 != null; // because sameLength() = true
2845    for (int i = 0 ; i < seq1.length ; i++) {
2846      if (gte(seq1[i], seq2[i])) {
2847        return false;
2848      }
2849    }
2850    return true;
2851  }
2852
2853  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
2854   * Meaning (in pseudo-FOL):
2855   *
2856   * /\ seq1.length == se2.length
2857   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
2858   *
2859   */
2860  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2861  @Pure
2862  public static boolean pairwiseLTE(char @Nullable [] seq1, char @Nullable [] seq2) {
2863    if (!sameLength(seq1, seq2)) {
2864      return false;
2865    }
2866    assert seq1 != null && seq2 != null; // because sameLength() = true
2867    for (int i = 0 ; i < seq1.length ; i++) {
2868      if (gt(seq1[i], seq2[i])) {
2869        return false;
2870      }
2871    }
2872    return true;
2873  }
2874
2875  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
2876   * Meaning (in pseudo-FOL):
2877   *
2878   * /\ seq1.length == se2.length
2879   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
2880   *
2881   */
2882  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2883  @Pure
2884  public static boolean pairwiseGT(char @Nullable [] seq1, char @Nullable [] seq2) {
2885    if (!sameLength(seq1, seq2)) {
2886      return false;
2887    }
2888    assert seq1 != null && seq2 != null; // because sameLength() = true
2889    for (int i = 0 ; i < seq1.length ; i++) {
2890      if (lte(seq1[i], seq2[i])) {
2891        return false;
2892      }
2893    }
2894    return true;
2895  }
2896
2897  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
2898   * Meaning (in pseudo-FOL):
2899   *
2900   * /\ seq1.length == se2.length
2901   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
2902   *
2903   */
2904  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2905  @Pure
2906  public static boolean pairwiseGTE(char @Nullable [] seq1, char @Nullable [] seq2) {
2907    if (!sameLength(seq1, seq2)) {
2908      return false;
2909    }
2910    assert seq1 != null && seq2 != null; // because sameLength() = true
2911    for (int i = 0 ; i < seq1.length ; i++) {
2912      if (lt(seq1[i], seq2[i])) {
2913        return false;
2914      }
2915    }
2916    return true;
2917  }
2918
2919  /**
2920   * Returns true iff seq1 is lexically equal to seq2.
2921   * For equality, "lexically" and "pairwise" are the same.
2922   */
2923  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2924  @Pure
2925  public static boolean lexEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2926    if (seq1 == null) {
2927      return false;
2928    }
2929    if (seq2 == null) {
2930      return false;
2931    }
2932    return pairwiseEqual(seq1, seq2);
2933  }
2934
2935  /** Returns true iff seq1 is lexically not equal to seq2. */
2936  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2937  @Pure
2938  public static boolean lexNotEqual(char @Nullable [] seq1, char @Nullable [] seq2) {
2939    if (seq1 == null) {
2940      return false;
2941    }
2942    if (seq2 == null) {
2943      return false;
2944    }
2945    return !lexEqual(seq1, seq2);
2946  }
2947
2948  /** Returns true iff seq1 is lexically &lt;  seq2. */
2949  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2950  @Pure
2951  public static boolean lexLT(char @Nullable [] seq1, char @Nullable [] seq2) {
2952    if (seq1 == null) {
2953      return false;
2954    }
2955    if (seq2 == null) {
2956      return false;
2957    }
2958    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
2959    for (int i = 0 ; i < minlength ; i++) {
2960      if (gt(seq1[i], seq2[i])) {
2961        return false;
2962      } else if (lt(seq1[i], seq2[i])) {
2963        return true;
2964      }
2965    }
2966    if (seq1.length >= seq2.length) {
2967      return false;
2968    }
2969    return true;
2970  }
2971
2972  /** Returns true iff seq1 is lexically &le; to seq2. */
2973  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2974  @Pure
2975  public static boolean lexLTE(char @Nullable [] seq1, char @Nullable [] seq2) {
2976    if (seq1 == null) {
2977      return false;
2978    }
2979    if (seq2 == null) {
2980      return false;
2981    }
2982    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
2983    for (int i = 0 ; i < minlength ; i++) {
2984      if (gt(seq1[i], seq2[i])) {
2985        return false;
2986      } else if (lt(seq1[i], seq2[i])) {
2987        return true;
2988      }
2989    }
2990    if (seq1.length > seq2.length) {
2991      return false;
2992    }
2993    return true;
2994  }
2995
2996  /** Returns true iff seq1 is lexically &gt; to seq2. */
2997  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
2998  @Pure
2999  public static boolean lexGT(char @Nullable [] seq1, char @Nullable [] seq2) {
3000  if (seq1 == null) {
3001    return false;
3002  }
3003  if (seq2 == null) {
3004    return false;
3005  }
3006    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
3007    for (int i = 0 ; i < minlength ; i++) {
3008      if (lt(seq1[i], seq2[i])) {
3009        return false;
3010      } else if (gt(seq1[i], seq2[i])) {
3011        return true;
3012      }
3013    }
3014    if (seq1.length <= seq2.length) {
3015      return false;
3016    }
3017    return true;
3018  }
3019
3020  /** Returns true iff seq1 is lexically &ge; to seq2. */
3021  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3022  @Pure
3023  public static boolean lexGTE(char @Nullable [] seq1, char @Nullable [] seq2) {
3024  if (seq1 == null) {
3025    return false;
3026  }
3027  if (seq2 == null) {
3028    return false;
3029  }
3030    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
3031    for (int i = 0 ; i < minlength ; i++) {
3032      if (lt(seq1[i], seq2[i])) {
3033        return false;
3034      } else if (gt(seq1[i], seq2[i])) {
3035        return true;
3036      }
3037    }
3038    if (seq1.length < seq2.length) {
3039      return false;
3040    }
3041    return true;
3042  }
3043
3044  /** True iff for all applicable i, every seq[i] == seq[i+1].
3045   *
3046   * Meaning (in pseudo-FOL):
3047   *
3048   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
3049   *
3050   */
3051  @EnsuresNonNullIf(result=true, expression="#1")
3052  @Pure
3053  public static boolean eltwiseEqual(char @Nullable [] seq) {
3054  if (seq == null) {
3055    return false;
3056  }
3057    for (int i = 0 ; i < seq.length ; i++) {
3058      if (i < seq.length - 1) {
3059        if (ne(seq[i], seq[i + 1])) {
3060          return false;
3061        }
3062      }
3063    }
3064    return true;
3065  }
3066
3067  /** True iff for all applicable i, every seq[i] != seq[i+1].
3068   *
3069   * Meaning (in pseudo-FOL):
3070   *
3071   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
3072   *
3073   */
3074  @EnsuresNonNullIf(result=true, expression="#1")
3075  @Pure
3076  public static boolean eltwiseNotEqual(char @Nullable [] seq) {
3077  if (seq == null) {
3078    return false;
3079  }
3080    for (int i = 0 ; i < seq.length ; i++) {
3081      if (i < seq.length - 1) {
3082        if (eq(seq[i], seq[i + 1])) {
3083          return false;
3084        }
3085      }
3086    }
3087    return true;
3088  }
3089
3090  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
3091   *
3092   * Meaning (in pseudo-FOL):
3093   *
3094   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
3095   *
3096   */
3097  @EnsuresNonNullIf(result=true, expression="#1")
3098  @Pure
3099  public static boolean eltwiseLT(char @Nullable [] seq) {
3100  if (seq == null) {
3101    return false;
3102  }
3103    for (int i = 0 ; i < seq.length ; i++) {
3104      if (i < seq.length - 1) {
3105        if (gte(seq[i], seq[i + 1])) {
3106          return false;
3107        }
3108      }
3109    }
3110    return true;
3111  }
3112
3113  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
3114   *
3115   * Meaning (in pseudo-FOL):
3116   *
3117   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
3118   *
3119   */
3120  @EnsuresNonNullIf(result=true, expression="#1")
3121  @Pure
3122  public static boolean eltwiseLTE(char @Nullable [] seq) {
3123  if (seq == null) {
3124    return false;
3125  }
3126    for (int i = 0 ; i < seq.length ; i++) {
3127      if (i < seq.length - 1) {
3128        if (gt(seq[i], seq[i + 1])) {
3129          return false;
3130        }
3131      }
3132    }
3133    return true;
3134  }
3135
3136  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
3137   *
3138   * Meaning (in pseudo-FOL):
3139   *
3140   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
3141   *
3142   */
3143  @EnsuresNonNullIf(result=true, expression="#1")
3144  @Pure
3145  public static boolean eltwiseGT(char @Nullable [] seq) {
3146  if (seq == null) {
3147    return false;
3148  }
3149    for (int i = 0 ; i < seq.length ; i++) {
3150      if (i < seq.length - 1) {
3151        if (lte(seq[i], seq[i + 1])) {
3152          return false;
3153        }
3154      }
3155    }
3156    return true;
3157  }
3158
3159  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
3160   *
3161   * Meaning (in pseudo-FOL):
3162   *
3163   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
3164   *
3165   */
3166  @EnsuresNonNullIf(result=true, expression="#1")
3167  @Pure
3168  public static boolean eltwiseGTE(char @Nullable [] seq) {
3169  if (seq == null) {
3170    return false;
3171  }
3172    for (int i = 0 ; i < seq.length ; i++) {
3173      if (i < seq.length - 1) {
3174        if (lt(seq[i], seq[i + 1])) {
3175          return false;
3176        }
3177      }
3178    }
3179    return true;
3180  }
3181
3182  /** True iff for all applicable i, every seq[i] == i.
3183   *
3184   * Meaning (in pseudo-FOL):
3185   *
3186   * forall i in { 0..seq.length-1 } : seq[i] == i
3187   *
3188   */
3189  @EnsuresNonNullIf(result=true, expression="#1")
3190  @Pure
3191  public static boolean eltsEqualIndex(char @Nullable [] seq) {
3192  if (seq == null) {
3193    return false;
3194  }
3195    for (int i = 0 ; i < seq.length ; i++) {
3196      if (ne(seq[i], i)) {
3197        return false;
3198      }
3199    }
3200    return true;
3201  }
3202
3203  /** True iff for all applicable i, every seq[i] != i.
3204   *
3205   * Meaning (in pseudo-FOL):
3206   *
3207   * forall i in { 0..seq.length-1 } : seq[i] != i
3208   *
3209   */
3210  @EnsuresNonNullIf(result=true, expression="#1")
3211  @Pure
3212  public static boolean eltsNotEqualIndex(char @Nullable [] seq) {
3213  if (seq == null) {
3214    return false;
3215  }
3216    for (int i = 0 ; i < seq.length ; i++) {
3217      if (eq(seq[i], i)) {
3218        return false;
3219      }
3220    }
3221    return true;
3222  }
3223
3224  /** True iff for all applicable i, every seq[i] &lt; i.
3225   *
3226   * Meaning (in pseudo-FOL):
3227   *
3228   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
3229   *
3230   */
3231  @EnsuresNonNullIf(result=true, expression="#1")
3232  @Pure
3233  public static boolean eltsLtIndex(char @Nullable [] seq) {
3234  if (seq == null) {
3235    return false;
3236  }
3237    for (int i = 0 ; i < seq.length ; i++) {
3238      if (gte(seq[i], i)) {
3239        return false;
3240      }
3241    }
3242    return true;
3243  }
3244
3245  /** True iff for all applicable i, every seq[i] &le; i.
3246   *
3247   * Meaning (in pseudo-FOL):
3248   *
3249   * forall i in { 0..seq.length-1 } : seq[i] &le; i
3250   *
3251   */
3252  @EnsuresNonNullIf(result=true, expression="#1")
3253  @Pure
3254  public static boolean eltsLteIndex(char @Nullable [] seq) {
3255  if (seq == null) {
3256    return false;
3257  }
3258    for (int i = 0 ; i < seq.length ; i++) {
3259      if (gt(seq[i], i)) {
3260        return false;
3261      }
3262    }
3263    return true;
3264  }
3265
3266  /** True iff for all applicable i, every seq[i] &gt; i.
3267   *
3268   * Meaning (in pseudo-FOL):
3269   *
3270   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
3271   *
3272   */
3273  @EnsuresNonNullIf(result=true, expression="#1")
3274  @Pure
3275  public static boolean eltsGtIndex(char @Nullable [] seq) {
3276  if (seq == null) {
3277    return false;
3278  }
3279    for (int i = 0 ; i < seq.length ; i++) {
3280      if (lte(seq[i], i)) {
3281        return false;
3282      }
3283    }
3284    return true;
3285  }
3286
3287  /** True iff for all applicable i, every seq[i] &ge; i.
3288   *
3289   * Meaning (in pseudo-FOL):
3290   *
3291   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
3292   *
3293   */
3294  @EnsuresNonNullIf(result=true, expression="#1")
3295  @Pure
3296  public static boolean eltsGteIndex(char @Nullable [] seq) {
3297  if (seq == null) {
3298    return false;
3299  }
3300    for (int i = 0 ; i < seq.length ; i++) {
3301      if (lt(seq[i], i)) {
3302        return false;
3303      }
3304    }
3305    return true;
3306  }
3307
3308  // Deferencing (accessing) fields
3309
3310  /**
3311   * collectchar accepts an object and a list of fields (one of which is of array type, and the
3312   * rest of which are not), and produces an array in which the original object has had the given
3313   * fields accessed.
3314   *
3315   * <p>Daikon creates invariants over "variables" such as the following.
3316   *
3317   * <dl>
3318   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
3319   *              for all y's in array x.arr.</dd>
3320   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
3321   *              for all x's in array arr.</dd>
3322   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
3323   * </dl>
3324   *
3325   * <p>The collectchar() method does this collecting work.
3326   *
3327   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
3328   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
3329   * elements that result from following the fields, one of which is assumed to be an array.
3330   *
3331   * <p>
3332   * requires: fieldStr.length() &gt; 0 and object != null
3333   * <p>
3334   * requires: fieldStr contains only field names, no "[]" strings.
3335   * <p>
3336   * requires: the method only works for field sequences with exactly one field representing an
3337   * array. For example, the collection a[].b[].c will fail.
3338   *
3339   * @return if the resulting collection is of non-primitive type, then returns an array of type
3340   * Object[]. Returns null if any array or field access causes an exception.
3341   */
3342
3343  @SideEffectFree
3344  public static char @Nullable [] collectchar(@Nullable Object object, @Nullable String fieldStr) {
3345
3346    if (object == null) {
3347      return null;
3348    }
3349    if (fieldStr == null) {
3350      return null;
3351    }
3352
3353    // assert fieldStr != null && !"".equals(fieldStr);
3354    String[] fieldNames = fieldStr.split("\\.");
3355    char[] retval = collectchar(object, fieldNames, 0);
3356    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
3357    return retval;
3358  }
3359
3360  // @PolyNull does not work for return type, because null is returned on error.
3361  /** Helper method for collectchar(Object, String).
3362   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
3363   * @see collectchar(Object, String)
3364   */
3365
3366  @SideEffectFree
3367  private static char @Nullable [] collectchar(@Nullable Object object,
3368                                                   String[] fields, int fieldsStartIdx) {
3369
3370    if (object == null) {
3371      return null;
3372    }
3373    assert (fields != null);
3374    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
3375
3376    Object fieldObj;
3377    try {
3378      Field field = (object instanceof java.lang.Class<?>)
3379        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
3380        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
3381      field.setAccessible(true);
3382      // Class cls = field.getType();
3383      fieldObj = field.get(object);
3384      // System.out.println("***fieldObj="+fieldObj);
3385
3386    } catch (Exception e) {
3387      return null;
3388
3389    }
3390
3391    if (fieldObj == null) {
3392      return null;
3393    }
3394
3395    // base case: just accessed the last field
3396    if (fields.length - 1 == fieldsStartIdx) {
3397
3398      if (fieldObj.getClass().isArray()) {
3399        // last field is an array
3400        return (char[])fieldObj;
3401      } else {
3402        // This hack should be removed in favor of, at "oneEltArray = ..."
3403        // below, calling a version of collectchar_field that throws an
3404        // error.  Then, this case becomes a run-time error.  -MDE
3405
3406        // Just one element; return a one-element array.
3407        // assert cls.equals(Character.TYPE);
3408        return new char[] { ((Character)fieldObj).charValue() };
3409      }
3410    } else {
3411      // recursive case: more fields to access after this one
3412
3413      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
3414
3415        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
3416        char[] intermediate = new char[collection.size()];
3417        int index = 0;
3418        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
3419          Object obj = i.next();
3420          char[] oneEltArray = collectchar(obj, fields, fieldsStartIdx + 1);
3421          if (oneEltArray == null) {
3422            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
3423          }
3424          // assert oneEltArray.length == 1;
3425          intermediate[index++] = oneEltArray[0];
3426        }
3427        return intermediate;
3428      } else if (fieldObj.getClass().isArray()) {
3429
3430        // collect elements across array
3431        char[] intermediate = new char[Array.getLength(fieldObj)];
3432        for (int i = 0 ; i < intermediate.length ; i++) {
3433          Object obj = Array.get(fieldObj, i);
3434          char[] oneEltArray = collectchar(obj, fields, fieldsStartIdx + 1);
3435          if (oneEltArray == null) {
3436            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
3437          }
3438          // assert oneEltArray.length == 1;
3439          intermediate[i] = oneEltArray[0];
3440        }
3441        return intermediate;
3442      } else {
3443
3444        return collectchar(fieldObj, fields, fieldsStartIdx + 1);
3445      }
3446    }
3447  }
3448
3449  /**
3450   * Returns the results of dereferencing the fields for 'object'. For example, the call
3451   *
3452   * <pre>collectchar_field(x, "f.g.h")</pre>
3453   *
3454   * has the same value as
3455   *
3456   * <pre>x.f.g.h</pre>.
3457   * Returns a default value if any field access causes an exception.
3458   */
3459  @SideEffectFree
3460  public static char collectchar_field(Object object, String fieldStr) {
3461
3462    if (object == null) {
3463      return Character.MAX_VALUE; // return default value
3464    }
3465    if (fieldStr == null) {
3466      return Character.MAX_VALUE; // return default value
3467    }
3468
3469    String[] fieldNames = fieldStr.split("\\.");
3470
3471    // Holds the intermediate (and final) result
3472    Object fieldObj = object;
3473
3474    for (int i = 0 ; i < fieldNames.length ; i++) {
3475
3476      String fieldName = fieldNames[i];
3477
3478      try {
3479        Field field =
3480          (fieldObj instanceof java.lang.Class<?>)
3481          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
3482          : fieldObj.getClass().getDeclaredField(fieldName);
3483        field.setAccessible(true);
3484        fieldObj = field.get(fieldObj);
3485
3486        if (fieldObj == null) {
3487          return Character.MAX_VALUE; // return default value
3488        }
3489
3490      } catch (Exception e) {
3491        return Character.MAX_VALUE; // return default value
3492
3493      }
3494
3495    }
3496
3497    return ((Character)fieldObj).charValue();
3498  }
3499
3500  // ///////////////////////////////////////////////////////////////////////////
3501  // Methods for "double" (from QuantBody.java.jpp)
3502  //
3503
3504  /**
3505   * Returns the ith element of the array or collection argument. If the argument is null or not an
3506   * array or collection, returns a default value (Double.NaN).
3507   */
3508
3509  @Pure
3510  public static double getElement_double(Object o, long i) {
3511    if (o == null) {
3512      return Double.NaN; // return default value
3513    }
3514    java.lang.Class<?> c = o.getClass();
3515    if (c.isArray()) {
3516      return java.lang.reflect.Array.getDouble(o, (int)i);
3517    } else if (o instanceof java.util.AbstractCollection<?>) {
3518      return java.lang.reflect.Array.getDouble(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
3519    } else {
3520      return Double.NaN; // return default value
3521    }
3522  }
3523
3524  @Pure
3525  public static double getElement_double(double[] arr, long i) {
3526    if (arr == null) {
3527      return Double.NaN; // return default value
3528    }
3529    return arr[(int)i];
3530  }
3531
3532  private static boolean eq(double x, double y) {
3533    return fuzzy.eq(x,y);
3534  }
3535
3536  private static boolean ne(double x, double y) {
3537    return fuzzy.ne(x,y);
3538  }
3539
3540  private static boolean lt(double x, double y) {
3541    return fuzzy.lt(x,y);
3542  }
3543
3544  private static boolean lte(double x, double y) {
3545    return fuzzy.lte(x,y);
3546  }
3547
3548  private static boolean gt(double x, double y) {
3549    return fuzzy.gt(x,y);
3550  }
3551
3552  private static boolean gte(double x, double y) {
3553    return fuzzy.gte(x,y);
3554  }
3555
3556  /** True iff both sequences are non-null and have the same length. */
3557  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
3558  @Pure
3559  public static boolean sameLength(double @Nullable [] seq1, double @Nullable [] seq2) {
3560    return ((seq1 != null)
3561            && (seq2 != null)
3562            && seq1.length == seq2.length);
3563  }
3564
3565  /** True iff both sequences are non-null and have the same length. */
3566  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
3567  @Pure
3568  public static boolean sameLength(double @Nullable [] seq1, float @Nullable [] seq2) {
3569    return ((seq1 != null)
3570            && (seq2 != null)
3571            && seq1.length == seq2.length);
3572  }
3573
3574  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
3575   *
3576   * Meaning (in pseudo-FOL):
3577   *
3578   * <pre>
3579   * /\ seq1.length == seq2.length
3580   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
3581   * </pre>
3582   *
3583   */
3584  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3585  @Pure
3586  public static boolean pairwiseDivides(double[] seq1, double[] seq2) {
3587    if (!sameLength(seq1, seq2)) {
3588      return false;
3589    }
3590    assert seq1 != null && seq2 != null; // because sameLength() = true
3591    for (int i = 0 ; i < seq1.length ; i++) {
3592      if (ne(seq1[i] % seq2[i], 0)) {
3593        return false;
3594      }
3595    }
3596    return true;
3597  }
3598  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3599  @Pure
3600  public static boolean pairwiseDivides(double[] seq1, float[] seq2) {
3601    if (!sameLength(seq1, seq2)) {
3602      return false;
3603    }
3604    assert seq1 != null && seq2 != null; // because sameLength() = true
3605    for (int i = 0 ; i < seq1.length ; i++) {
3606      if (ne(seq1[i] % seq2[i], 0)) {
3607        return false;
3608      }
3609    }
3610    return true;
3611  }
3612
3613  /**
3614   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
3615   *
3616   * Meaning (in pseudo-FOL):
3617   *
3618   * <pre>
3619   * /\ seq1.length == seq2.length
3620   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
3621   * </pre>
3622   *
3623   */
3624  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3625  @Pure
3626  public static boolean pairwiseSquare(double[] seq1, double[] seq2) {
3627    if (!sameLength(seq1, seq2)) {
3628      return false;
3629    }
3630    assert seq1 != null && seq2 != null; // because sameLength() = true
3631    for (int i = 0 ; i < seq1.length ; i++) {
3632      if (ne(seq1[i], seq2[i] * seq2[i])) {
3633        return false;
3634      }
3635    }
3636    return true;
3637  }
3638  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3639  @Pure
3640  public static boolean pairwiseSquare(double[] seq1, float[] seq2) {
3641    if (!sameLength(seq1, seq2)) {
3642      return false;
3643    }
3644    assert seq1 != null && seq2 != null; // because sameLength() = true
3645    for (int i = 0 ; i < seq1.length ; i++) {
3646
3647      if (ne(seq1[i], ((double) seq2[i]) * ((double) seq2[i]))) {
3648
3649        return false;
3650      }
3651    }
3652    return true;
3653  }
3654
3655  /**
3656   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
3657   *
3658   * <p>If either array is null, returns null. If either array is empty, returns only those
3659   * elements in the other array. If both arrays are empty, returns a new empty array.
3660   */
3661  @SideEffectFree
3662  public static double @PolyNull [] concat(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3663    if (seq1 == null) {
3664      return null;
3665    }
3666    if (seq2 == null) {
3667      return null;
3668    }
3669    return ArraysPlume.concat(seq1, seq2);
3670  }
3671
3672  @SideEffectFree
3673  public static double @PolyNull [] concat(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3674    if (seq1 == null) {
3675      return null;
3676    }
3677    if (seq2 == null) {
3678      return null;
3679    }
3680    // Cannot just use ArraysPlume.concat because the two arrays
3681    // have different types.  This essentially inlines that method.
3682    int newLength = seq1.length + seq2.length;
3683    double[] retval = new double[newLength];
3684
3685    System.arraycopy(seq1, 0, retval, 0, seq1.length);
3686    for (int j = 0 ; j < seq2.length ; j++) {
3687      retval[seq1.length + j] = seq2[j];
3688    }
3689
3690    return retval;
3691  }
3692
3693  /**
3694   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
3695   * assurances about the order or repetition of elements: elements may be repeated, and their
3696   * order may be different from the order of elements in seq1 and seq2.
3697   */
3698  @SideEffectFree
3699  public static double @PolyNull [] union(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3700    if (seq1 == null) {
3701      return null;
3702    }
3703    if (seq2 == null) {
3704      return null;
3705    }
3706    return concat(seq1, seq2);
3707  }
3708
3709  @Pure
3710  public static double @PolyNull [] union(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3711    if (seq1 == null) {
3712      return null;
3713    }
3714    if (seq2 == null) {
3715      return null;
3716    }
3717    return concat(seq1, seq2);
3718  }
3719
3720  /**
3721   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
3722   * gives no assurances about the order or repetition of elements: elements may be repeated, and
3723   * their order may be different from the order of elements in seq1 and seq2.
3724   */
3725  @Pure
3726  public static double @PolyNull [] intersection(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3727    if (seq1 == null) {
3728      return null;
3729    }
3730    if (seq2 == null) {
3731      return null;
3732    }
3733    double[] intermediate = new double[Math.min(seq1.length, seq2.length)];
3734    int length = 0;
3735    for (int i = 0 ; i < seq1.length ; i++) {
3736      if (memberOf(seq1[i], seq2) ) {
3737        intermediate[length++] = seq1[i];
3738      }
3739    }
3740    return ArraysPlume.subarray(intermediate, 0, length);
3741  }
3742
3743  @Pure
3744  public static double @PolyNull [] intersection(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3745    if (seq1 == null) {
3746      return null;
3747    }
3748    if (seq2 == null) {
3749      return null;
3750    }
3751    double[] intermediate = new double[Math.min(seq1.length, seq2.length)];
3752    int length = 0;
3753    for (int i = 0 ; i < seq1.length ; i++) {
3754      if (memberOf(seq1[i], seq2) ) {
3755        intermediate[length++] = seq1[i];
3756      }
3757    }
3758    return ArraysPlume.subarray(intermediate, 0, length);
3759  }
3760
3761  /**
3762   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
3763   * no assurances about the order or repetition of elements: elements may be repeated, and their
3764   * order may be different from the order of elements in seq1 and seq2.
3765   */
3766  @Pure
3767  public static double @PolyNull [] setDiff(double @PolyNull [] seq1, double @PolyNull [] seq2) {
3768    if (seq1 == null) {
3769      return null;
3770    }
3771    if (seq2 == null) {
3772      return null;
3773    }
3774    double[] intermediate = new double[seq1.length];
3775    int length = 0;
3776    for (int i = 0 ; i < seq1.length ; i++) {
3777      if (!memberOf(seq1[i], seq2)) {
3778        intermediate[length++] = seq1[i];
3779      }
3780    }
3781    return ArraysPlume.subarray(intermediate, 0, length);
3782  }
3783
3784  @Pure
3785  public static double @PolyNull [] setDiff(double @PolyNull [] seq1, float @PolyNull [] seq2) {
3786    if (seq1 == null) {
3787      return null;
3788    }
3789    if (seq2 == null) {
3790      return null;
3791    }
3792    double[] intermediate = new double[seq1.length];
3793    int length = 0;
3794    for (int i = 0 ; i < seq1.length ; i++) {
3795      if (!memberOf(seq1[i], seq2)) {
3796        intermediate[length++] = seq1[i];
3797      }
3798    }
3799    return ArraysPlume.subarray(intermediate, 0, length);
3800  }
3801
3802  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
3803  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3804  @Pure
3805  public static boolean setEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
3806    if (seq1 == null) {
3807      return false;
3808    }
3809    if (seq2 == null) {
3810      return false;
3811    }
3812    for (int i = 0; i < seq1.length ; i++) {
3813      if (!memberOf(seq1[i], seq2) ) {
3814        return false;
3815      }
3816    }
3817    for (int i = 0; i < seq2.length ; i++) {
3818      if (!memberOf(seq2[i], seq1) ) {
3819        return false;
3820      }
3821    }
3822    return true;
3823  }
3824
3825  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3826  @Pure
3827  public static boolean setEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
3828    if (seq1 == null) {
3829      return false;
3830    }
3831    if (seq2 == null) {
3832      return false;
3833    }
3834    for (int i = 0; i < seq1.length ; i++) {
3835      if (!memberOf(seq1[i], seq2) ) {
3836        return false;
3837      }
3838    }
3839    for (int i = 0; i < seq2.length ; i++) {
3840      if (!memberOf(seq2[i], seq1) ) {
3841        return false;
3842      }
3843    }
3844    return true;
3845  }
3846
3847  /** True iff seq1 is the reverse of seq2.
3848   *
3849   * Meaning (in pseudo-FOL):
3850   *
3851   * <pre>
3852   * /\ seq1.length == seq2.length
3853   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
3854   * </pre>
3855   *
3856   */
3857  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3858  @Pure
3859  public static boolean isReverse(double[] seq1, double[] seq2) {
3860    if (!sameLength(seq1, seq2)) {
3861      return false;
3862    }
3863    assert seq1 != null && seq2 != null; // because sameLength() = true
3864    int length = seq1.length;
3865    for (int i = 0 ; i < length ; i++) {
3866      if (ne(seq1[i], seq2[length - i - 1])) {
3867        return false;
3868      }
3869    }
3870    return true;
3871  }
3872
3873  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3874  @Pure
3875  public static boolean isReverse(double @Nullable [] seq1, float @Nullable [] seq2) {
3876    if (!sameLength(seq1, seq2)) {
3877      return false;
3878    }
3879    assert seq1 != null && seq2 != null; // because sameLength() = true
3880    int length = seq1.length;
3881    for (int i = 0 ; i < length ; i++) {
3882      if (ne(seq1[i], seq2[length - i - 1])) {
3883        return false;
3884      }
3885    }
3886    return true;
3887  }
3888
3889  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
3890  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3891  @Pure
3892  public static boolean subsetOf(double @Nullable [] seq1, double @Nullable [] seq2) {
3893    if (seq1 == null) {
3894      return false;
3895    }
3896    if (seq2 == null) {
3897      return false;
3898    }
3899    for (int i = 0 ; i < seq1.length ; i++) {
3900      if (!memberOf(seq1[i], seq2)) {
3901        return false;
3902      }
3903    }
3904    return true;
3905  }
3906
3907  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
3908  @Pure
3909  public static boolean subsetOf(double @Nullable [] seq1, float @Nullable [] seq2) {
3910    if (seq1 == null) {
3911      return false;
3912    }
3913    if (seq2 == null) {
3914      return false;
3915    }
3916    for (int i = 0 ; i < seq1.length ; i++) {
3917      if (!memberOf(seq1[i], seq2)) {
3918        return false;
3919      }
3920    }
3921    return true;
3922  }
3923
3924  /** Returns true iff seq contains no duplicate elements. */
3925  @EnsuresNonNullIf(result=true, expression="#1")
3926  @Pure
3927  public static boolean noDups(double @Nullable [] seq) {
3928    if (seq == null) {
3929      return false;
3930    }
3931    return ArraysPlume.hasNoDuplicates(seq);
3932  }
3933
3934 /** Returns true iff elt is in array arr. */
3935  @EnsuresNonNullIf(result=true, expression="#2")
3936  @Pure
3937  public static boolean memberOf(double elt, double @Nullable [] arr) {
3938    if (arr == null) {
3939      return false;
3940    }
3941    for (int i = 0 ; i < arr.length ; i++) {
3942      if (eq(arr[i], elt)) {
3943        return true;
3944      }
3945    }
3946    return false;
3947  }
3948
3949  @EnsuresNonNullIf(result=true, expression="#2")
3950  @Pure
3951  public static boolean memberOf(double elt, float @Nullable [] arr) {
3952    if (arr == null) {
3953      return false;
3954    }
3955    for (int i = 0 ; i < arr.length ; i++) {
3956      if (eq(arr[i], elt)) {
3957        return true;
3958      }
3959    }
3960    return false;
3961  }
3962
3963  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
3964  @Pure
3965  public static double @PolyNull [] slice(double @PolyNull [] seq, int start, int end) {
3966    if (seq == null) {
3967      return null;
3968    }
3969    int sliceStart = start;
3970    int sliceEnd = end;
3971    if (start < 0) {
3972      return new double[] { };
3973    }
3974    if (end > seq.length - 1) {
3975      return new double[] { };
3976    }
3977    if (sliceStart > sliceEnd) {
3978      return new double[] { };
3979    }
3980    int length = sliceEnd - sliceStart + 1;
3981    return ArraysPlume.subarray(seq, sliceStart, length);
3982  }
3983
3984  @Pure
3985  public static double @PolyNull [] slice(double @PolyNull [] seq, long start, int end) {
3986    return slice(seq, (int)start, end);
3987  }
3988  @Pure
3989  public static double @PolyNull [] slice(double @PolyNull [] seq, int start, long end) {
3990    return slice(seq, start, (int)end);
3991  }
3992  @Pure
3993  public static double @PolyNull [] slice(double @PolyNull [] seq, long start, long end) {
3994    return slice(seq, (int)start, (int)end);
3995  }
3996
3997  /** True iff all elements in arr equal elt.
3998   *
3999   * Meaning (in pseudo-FOL):
4000   *
4001   * forall i in { 0..arr.length-1 } : arr[i] == elt
4002   *
4003   */
4004  @EnsuresNonNullIf(result=true, expression="#1")
4005  @Pure
4006  public static boolean eltsEqual(double @Nullable [] arr, double elt) {
4007    if (arr == null) {
4008      return false;
4009    }
4010    for (int i = 0 ; i < arr.length ; i++) {
4011      if (ne(arr[i], elt)) {
4012        return false;
4013      }
4014    }
4015    return true;
4016  }
4017
4018  @EnsuresNonNullIf(result=true, expression="#1")
4019  @Pure
4020  public static boolean eltsEqual(double @Nullable [] arr, float elt) {
4021    if (arr == null) {
4022      return false;
4023    }
4024    for (int i = 0 ; i < arr.length ; i++) {
4025      if (ne(arr[i], elt)) {
4026        return false;
4027      }
4028    }
4029    return true;
4030  }
4031
4032  /** True iff every element in arr does not equal elt.
4033   *
4034   * Meaning (in pseudo-FOL):
4035   *
4036   * forall i in { 0..arr.length-1 } : arr[i] != elt
4037   *
4038   */
4039  @EnsuresNonNullIf(result=true, expression="#1")
4040  @Pure
4041  public static boolean eltsNotEqual(double @Nullable [] arr, double elt) {
4042    if (arr == null) {
4043      return false;
4044    }
4045    for (int i = 0 ; i < arr.length ; i++) {
4046      if (eq(arr[i], elt)) {
4047        return false;
4048      }
4049    }
4050    return true;
4051  }
4052
4053  @EnsuresNonNullIf(result=true, expression="#1")
4054  @Pure
4055  public static boolean eltsNotEqual(double @Nullable [] arr, float elt) {
4056    if (arr == null) {
4057      return false;
4058    }
4059    for (int i = 0 ; i < arr.length ; i++) {
4060      if (eq(arr[i], elt)) {
4061        return false;
4062      }
4063    }
4064    return true;
4065  }
4066
4067  /** True iff every element in arr is greater than elt.
4068   *
4069   * Meaning (in pseudo-FOL):
4070   *
4071   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
4072   *
4073   */
4074  @EnsuresNonNullIf(result=true, expression="#1")
4075  @Pure
4076  public static boolean eltsGT(double @Nullable [] arr, double elt) {
4077    if (arr == null) {
4078      return false;
4079    }
4080    for (int i = 0 ; i < arr.length ; i++) {
4081      if (lte(arr[i], elt)) {
4082        return false;
4083      }
4084    }
4085    return true;
4086  }
4087
4088  @EnsuresNonNullIf(result=true, expression="#1")
4089  @Pure
4090  public static boolean eltsGT(double @Nullable [] arr, float elt) {
4091    if (arr == null) {
4092      return false;
4093    }
4094    for (int i = 0 ; i < arr.length ; i++) {
4095      if (lte(arr[i], elt)) {
4096        return false;
4097      }
4098    }
4099    return true;
4100  }
4101
4102  /** True iff every element in arr is greater than or equal to elt.
4103   *
4104   * Meaning (in pseudo-FOL):
4105   *
4106   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
4107   *
4108   */
4109  @EnsuresNonNullIf(result=true, expression="#1")
4110  @Pure
4111  public static boolean eltsGTE(double @Nullable [] arr, double elt) {
4112    if (arr == null) {
4113      return false;
4114    }
4115    for (int i = 0 ; i < arr.length ; i++) {
4116      if (lt(arr[i], elt)) {
4117        return false;
4118      }
4119    }
4120    return true;
4121  }
4122
4123  @EnsuresNonNullIf(result=true, expression="#1")
4124  @Pure
4125  public static boolean eltsGTE(double @Nullable [] arr, float elt) {
4126    if (arr == null) {
4127      return false;
4128    }
4129    for (int i = 0 ; i < arr.length ; i++) {
4130      if (lt(arr[i], elt)) {
4131        return false;
4132      }
4133    }
4134    return true;
4135  }
4136
4137  /** True iff every element in arr is less than elt.
4138   *
4139   * Meaning (in pseudo-FOL):
4140   *
4141   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
4142   *
4143   */
4144  @EnsuresNonNullIf(result=true, expression="#1")
4145  @Pure
4146  public static boolean eltsLT(double @Nullable [] arr, double elt) {
4147    if (arr == null) {
4148      return false;
4149    }
4150    for (int i = 0 ; i < arr.length ; i++) {
4151      if (gte(arr[i], elt)) {
4152        return false;
4153      }
4154    }
4155    return true;
4156  }
4157
4158  @EnsuresNonNullIf(result=true, expression="#1")
4159  @Pure
4160  public static boolean eltsLT(double @Nullable [] arr, float elt) {
4161    if (arr == null) {
4162      return false;
4163    }
4164    for (int i = 0 ; i < arr.length ; i++) {
4165      if (gte(arr[i], elt)) {
4166        return false;
4167      }
4168    }
4169    return true;
4170  }
4171
4172  /** True iff every element in arr is less than or equal to elt.
4173   *
4174   * Meaning (in pseudo-FOL):
4175   *
4176   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
4177   *
4178   */
4179  @EnsuresNonNullIf(result=true, expression="#1")
4180  @Pure
4181  public static boolean eltsLTE(double @Nullable [] arr, double elt) {
4182    if (arr == null) {
4183      return false;
4184    }
4185    for (int i = 0 ; i < arr.length ; i++) {
4186      if (gt(arr[i], elt)) {
4187        return false;
4188      }
4189    }
4190    return true;
4191  }
4192
4193  @EnsuresNonNullIf(result=true, expression="#1")
4194  @Pure
4195  public static boolean eltsLTE(double @Nullable [] arr, float elt) {
4196    if (arr == null) {
4197      return false;
4198    }
4199    for (int i = 0 ; i < arr.length ; i++) {
4200      if (gt(arr[i], elt)) {
4201        return false;
4202      }
4203    }
4204    return true;
4205  }
4206
4207  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
4208   *
4209   * Meaning (in pseudo-FOL):
4210   *
4211   * /\ seq1.length == se2.length
4212   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
4213   *
4214   */
4215
4216  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4217  @Pure
4218  public static boolean pairwiseEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4219    if (!sameLength(seq1, seq2)) {
4220      return false;
4221    }
4222    assert seq1 != null && seq2 != null; // because sameLength() = true
4223    for (int i = 0 ; i < seq1.length ; i++) {
4224      if (Double.isNaN(seq1[i]) && Double.isNaN(seq2[i])) {
4225        continue;
4226      }
4227      if (ne(seq1[i], seq2[i])) {
4228        return false;
4229      }
4230    }
4231    return true;
4232  }
4233
4234  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4235  @Pure
4236  public static boolean pairwiseEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4237    if (!sameLength(seq1, seq2)) {
4238      return false;
4239    }
4240    assert seq1 != null && seq2 != null; // because sameLength() = true
4241    for (int i = 0 ; i < seq1.length ; i++) {
4242      if (ne(seq1[i], seq2[i])) {
4243        return false;
4244      }
4245    }
4246    return true;
4247  }
4248
4249  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
4250   *
4251   * Meaning (in pseudo-FOL):
4252   *
4253   * /\ seq1.length == se2.length
4254   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
4255   *
4256   */
4257  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4258  @Pure
4259  public static boolean pairwiseNotEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4260    if (!sameLength(seq1, seq2)) {
4261      return false;
4262    }
4263    assert seq1 != null && seq2 != null; // because sameLength() = true
4264    for (int i = 0 ; i < seq1.length ; i++) {
4265      if (eq(seq1[i], seq2[i])) {
4266        return false;
4267      }
4268    }
4269    return true;
4270  }
4271
4272  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4273  @Pure
4274  public static boolean pairwiseNotEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4275    if (!sameLength(seq1, seq2)) {
4276      return false;
4277    }
4278    assert seq1 != null && seq2 != null; // because sameLength() = true
4279    for (int i = 0 ; i < seq1.length ; i++) {
4280      if (eq(seq1[i], seq2[i])) {
4281        return false;
4282      }
4283    }
4284    return true;
4285  }
4286
4287  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
4288   *
4289   * Meaning (in pseudo-FOL):
4290   *
4291   * /\ seq1.length == se2.length
4292   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
4293   *
4294   */
4295  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4296  @Pure
4297  public static boolean pairwiseLT(double @Nullable [] seq1, double @Nullable [] seq2) {
4298    if (!sameLength(seq1, seq2)) {
4299      return false;
4300    }
4301    assert seq1 != null && seq2 != null; // because sameLength() = true
4302    for (int i = 0 ; i < seq1.length ; i++) {
4303      if (gte(seq1[i], seq2[i])) {
4304        return false;
4305      }
4306    }
4307    return true;
4308  }
4309
4310  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4311  @Pure
4312  public static boolean pairwiseLT(double @Nullable [] seq1, float @Nullable [] seq2) {
4313    if (!sameLength(seq1, seq2)) {
4314      return false;
4315    }
4316    assert seq1 != null && seq2 != null; // because sameLength() = true
4317    for (int i = 0 ; i < seq1.length ; i++) {
4318      if (gte(seq1[i], seq2[i])) {
4319        return false;
4320      }
4321    }
4322    return true;
4323  }
4324
4325  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
4326   * Meaning (in pseudo-FOL):
4327   *
4328   * /\ seq1.length == se2.length
4329   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
4330   *
4331   */
4332  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4333  @Pure
4334  public static boolean pairwiseLTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4335    if (!sameLength(seq1, seq2)) {
4336      return false;
4337    }
4338    assert seq1 != null && seq2 != null; // because sameLength() = true
4339    for (int i = 0 ; i < seq1.length ; i++) {
4340      if (gt(seq1[i], seq2[i])) {
4341        return false;
4342      }
4343    }
4344    return true;
4345  }
4346
4347  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4348  @Pure
4349  public static boolean pairwiseLTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4350    if (!sameLength(seq1, seq2)) {
4351      return false;
4352    }
4353    assert seq1 != null && seq2 != null; // because sameLength() = true
4354    for (int i = 0 ; i < seq1.length ; i++) {
4355      if (gt(seq1[i], seq2[i])) {
4356        return false;
4357      }
4358    }
4359    return true;
4360  }
4361
4362  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
4363   * Meaning (in pseudo-FOL):
4364   *
4365   * /\ seq1.length == se2.length
4366   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
4367   *
4368   */
4369  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4370  @Pure
4371  public static boolean pairwiseGT(double @Nullable [] seq1, double @Nullable [] seq2) {
4372    if (!sameLength(seq1, seq2)) {
4373      return false;
4374    }
4375    assert seq1 != null && seq2 != null; // because sameLength() = true
4376    for (int i = 0 ; i < seq1.length ; i++) {
4377      if (lte(seq1[i], seq2[i])) {
4378        return false;
4379      }
4380    }
4381    return true;
4382  }
4383
4384  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4385  @Pure
4386  public static boolean pairwiseGT(double @Nullable [] seq1, float @Nullable [] seq2) {
4387    if (!sameLength(seq1, seq2)) {
4388      return false;
4389    }
4390    assert seq1 != null && seq2 != null; // because sameLength() = true
4391    for (int i = 0 ; i < seq1.length ; i++) {
4392      if (lte(seq1[i], seq2[i])) {
4393        return false;
4394      }
4395    }
4396    return true;
4397  }
4398
4399  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
4400   * Meaning (in pseudo-FOL):
4401   *
4402   * /\ seq1.length == se2.length
4403   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
4404   *
4405   */
4406  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4407  @Pure
4408  public static boolean pairwiseGTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4409    if (!sameLength(seq1, seq2)) {
4410      return false;
4411    }
4412    assert seq1 != null && seq2 != null; // because sameLength() = true
4413    for (int i = 0 ; i < seq1.length ; i++) {
4414      if (lt(seq1[i], seq2[i])) {
4415        return false;
4416      }
4417    }
4418    return true;
4419  }
4420
4421  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4422  @Pure
4423  public static boolean pairwiseGTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4424    if (!sameLength(seq1, seq2)) {
4425      return false;
4426    }
4427    assert seq1 != null && seq2 != null; // because sameLength() = true
4428    for (int i = 0 ; i < seq1.length ; i++) {
4429      if (lt(seq1[i], seq2[i])) {
4430        return false;
4431      }
4432    }
4433    return true;
4434  }
4435
4436  /**
4437   * Returns true iff seq1 is lexically equal to seq2.
4438   * For equality, "lexically" and "pairwise" are the same.
4439   */
4440  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4441  @Pure
4442  public static boolean lexEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4443    if (seq1 == null) {
4444      return false;
4445    }
4446    if (seq2 == null) {
4447      return false;
4448    }
4449    return pairwiseEqual(seq1, seq2);
4450  }
4451
4452  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4453  @Pure
4454  public static boolean lexEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4455    if (seq1 == null) {
4456      return false;
4457    }
4458    if (seq2 == null) {
4459      return false;
4460    }
4461    return pairwiseEqual(seq1, seq2);
4462  }
4463
4464  /** Returns true iff seq1 is lexically not equal to seq2. */
4465  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4466  @Pure
4467  public static boolean lexNotEqual(double @Nullable [] seq1, double @Nullable [] seq2) {
4468    if (seq1 == null) {
4469      return false;
4470    }
4471    if (seq2 == null) {
4472      return false;
4473    }
4474    return !lexEqual(seq1, seq2);
4475  }
4476
4477  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4478  @Pure
4479  public static boolean lexNotEqual(double @Nullable [] seq1, float @Nullable [] seq2) {
4480    if (seq1 == null) {
4481      return false;
4482    }
4483    if (seq2 == null) {
4484      return false;
4485    }
4486    return !lexEqual(seq1, seq2);
4487  }
4488
4489  /** Returns true iff seq1 is lexically &lt;  seq2. */
4490  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4491  @Pure
4492  public static boolean lexLT(double @Nullable [] seq1, double @Nullable [] seq2) {
4493    if (seq1 == null) {
4494      return false;
4495    }
4496    if (seq2 == null) {
4497      return false;
4498    }
4499    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4500    for (int i = 0 ; i < minlength ; i++) {
4501      if (gt(seq1[i], seq2[i])) {
4502        return false;
4503      } else if (lt(seq1[i], seq2[i])) {
4504        return true;
4505      }
4506    }
4507    if (seq1.length >= seq2.length) {
4508      return false;
4509    }
4510    return true;
4511  }
4512
4513  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4514  @Pure
4515  public static boolean lexLT(double @Nullable [] seq1, float @Nullable [] seq2) {
4516    if (seq1 == null) {
4517      return false;
4518    }
4519    if (seq2 == null) {
4520      return false;
4521    }
4522    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4523    for (int i = 0 ; i < minlength ; i++) {
4524      if (gt(seq1[i], seq2[i])) {
4525        return false;
4526        } else if (lt(seq1[i], seq2[i])) {
4527          return true;
4528        }
4529      }
4530      if (seq1.length >= seq2.length) {
4531        return false;
4532      }
4533      return true;
4534    }
4535
4536  /** Returns true iff seq1 is lexically &le; to seq2. */
4537  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4538  @Pure
4539  public static boolean lexLTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4540    if (seq1 == null) {
4541      return false;
4542    }
4543    if (seq2 == null) {
4544      return false;
4545    }
4546    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4547    for (int i = 0 ; i < minlength ; i++) {
4548      if (gt(seq1[i], seq2[i])) {
4549        return false;
4550      } else if (lt(seq1[i], seq2[i])) {
4551        return true;
4552      }
4553    }
4554    if (seq1.length > seq2.length) {
4555      return false;
4556    }
4557    return true;
4558  }
4559
4560  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4561  @Pure
4562  public static boolean lexLTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4563  if (seq1 == null) {
4564    return false;
4565  }
4566  if (seq2 == null) {
4567    return false;
4568  }
4569    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4570    for (int i = 0 ; i < minlength ; i++) {
4571      if (gt(seq1[i], seq2[i])) {
4572        return false;
4573      } else if (lt(seq1[i], seq2[i])) {
4574        return true;
4575      }
4576    }
4577    if (seq1.length > seq2.length) {
4578      return false;
4579    }
4580    return true;
4581  }
4582
4583  /** Returns true iff seq1 is lexically &gt; to seq2. */
4584  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4585  @Pure
4586  public static boolean lexGT(double @Nullable [] seq1, double @Nullable [] seq2) {
4587  if (seq1 == null) {
4588    return false;
4589  }
4590  if (seq2 == null) {
4591    return false;
4592  }
4593    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4594    for (int i = 0 ; i < minlength ; i++) {
4595      if (lt(seq1[i], seq2[i])) {
4596        return false;
4597      } else if (gt(seq1[i], seq2[i])) {
4598        return true;
4599      }
4600    }
4601    if (seq1.length <= seq2.length) {
4602      return false;
4603    }
4604    return true;
4605  }
4606
4607  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4608  @Pure
4609  public static boolean lexGT(double @Nullable [] seq1, float @Nullable [] seq2) {
4610  if (seq1 == null) {
4611    return false;
4612  }
4613  if (seq2 == null) {
4614    return false;
4615  }
4616    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4617    for (int i = 0 ; i < minlength ; i++) {
4618      if (lt(seq1[i], seq2[i])) {
4619        return false;
4620      } else if (gt(seq1[i], seq2[i])) {
4621        return true;
4622      }
4623    }
4624    if (seq1.length <= seq2.length) {
4625      return false;
4626    }
4627    return true;
4628  }
4629
4630  /** Returns true iff seq1 is lexically &ge; to seq2. */
4631  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4632  @Pure
4633  public static boolean lexGTE(double @Nullable [] seq1, double @Nullable [] seq2) {
4634  if (seq1 == null) {
4635    return false;
4636  }
4637  if (seq2 == null) {
4638    return false;
4639  }
4640    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4641    for (int i = 0 ; i < minlength ; i++) {
4642      if (lt(seq1[i], seq2[i])) {
4643        return false;
4644      } else if (gt(seq1[i], seq2[i])) {
4645        return true;
4646      }
4647    }
4648    if (seq1.length < seq2.length) {
4649      return false;
4650    }
4651    return true;
4652  }
4653
4654  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
4655  @Pure
4656  public static boolean lexGTE(double @Nullable [] seq1, float @Nullable [] seq2) {
4657  if (seq1 == null) {
4658    return false;
4659  }
4660  if (seq2 == null) {
4661    return false;
4662  }
4663    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
4664    for (int i = 0 ; i < minlength ; i++) {
4665      if (lt(seq1[i], seq2[i])) {
4666        return false;
4667      } else if (gt(seq1[i], seq2[i])) {
4668        return true;
4669      }
4670    }
4671    if (seq1.length < seq2.length) {
4672      return false;
4673    }
4674    return true;
4675  }
4676
4677  /** True iff for all applicable i, every seq[i] == seq[i+1].
4678   *
4679   * Meaning (in pseudo-FOL):
4680   *
4681   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
4682   *
4683   */
4684  @EnsuresNonNullIf(result=true, expression="#1")
4685  @Pure
4686  public static boolean eltwiseEqual(double @Nullable [] seq) {
4687  if (seq == null) {
4688    return false;
4689  }
4690    for (int i = 0 ; i < seq.length ; i++) {
4691      if (i < seq.length - 1) {
4692        if (ne(seq[i], seq[i + 1])) {
4693          return false;
4694        }
4695      }
4696    }
4697    return true;
4698  }
4699
4700  /** True iff for all applicable i, every seq[i] != seq[i+1].
4701   *
4702   * Meaning (in pseudo-FOL):
4703   *
4704   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
4705   *
4706   */
4707  @EnsuresNonNullIf(result=true, expression="#1")
4708  @Pure
4709  public static boolean eltwiseNotEqual(double @Nullable [] seq) {
4710  if (seq == null) {
4711    return false;
4712  }
4713    for (int i = 0 ; i < seq.length ; i++) {
4714      if (i < seq.length - 1) {
4715        if (eq(seq[i], seq[i + 1])) {
4716          return false;
4717        }
4718      }
4719    }
4720    return true;
4721  }
4722
4723  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
4724   *
4725   * Meaning (in pseudo-FOL):
4726   *
4727   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
4728   *
4729   */
4730  @EnsuresNonNullIf(result=true, expression="#1")
4731  @Pure
4732  public static boolean eltwiseLT(double @Nullable [] seq) {
4733  if (seq == null) {
4734    return false;
4735  }
4736    for (int i = 0 ; i < seq.length ; i++) {
4737      if (i < seq.length - 1) {
4738        if (gte(seq[i], seq[i + 1])) {
4739          return false;
4740        }
4741      }
4742    }
4743    return true;
4744  }
4745
4746  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
4747   *
4748   * Meaning (in pseudo-FOL):
4749   *
4750   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
4751   *
4752   */
4753  @EnsuresNonNullIf(result=true, expression="#1")
4754  @Pure
4755  public static boolean eltwiseLTE(double @Nullable [] seq) {
4756  if (seq == null) {
4757    return false;
4758  }
4759    for (int i = 0 ; i < seq.length ; i++) {
4760      if (i < seq.length - 1) {
4761        if (gt(seq[i], seq[i + 1])) {
4762          return false;
4763        }
4764      }
4765    }
4766    return true;
4767  }
4768
4769  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
4770   *
4771   * Meaning (in pseudo-FOL):
4772   *
4773   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
4774   *
4775   */
4776  @EnsuresNonNullIf(result=true, expression="#1")
4777  @Pure
4778  public static boolean eltwiseGT(double @Nullable [] seq) {
4779  if (seq == null) {
4780    return false;
4781  }
4782    for (int i = 0 ; i < seq.length ; i++) {
4783      if (i < seq.length - 1) {
4784        if (lte(seq[i], seq[i + 1])) {
4785          return false;
4786        }
4787      }
4788    }
4789    return true;
4790  }
4791
4792  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
4793   *
4794   * Meaning (in pseudo-FOL):
4795   *
4796   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
4797   *
4798   */
4799  @EnsuresNonNullIf(result=true, expression="#1")
4800  @Pure
4801  public static boolean eltwiseGTE(double @Nullable [] seq) {
4802  if (seq == null) {
4803    return false;
4804  }
4805    for (int i = 0 ; i < seq.length ; i++) {
4806      if (i < seq.length - 1) {
4807        if (lt(seq[i], seq[i + 1])) {
4808          return false;
4809        }
4810      }
4811    }
4812    return true;
4813  }
4814
4815  /** True iff for all applicable i, every seq[i] == i.
4816   *
4817   * Meaning (in pseudo-FOL):
4818   *
4819   * forall i in { 0..seq.length-1 } : seq[i] == i
4820   *
4821   */
4822  @EnsuresNonNullIf(result=true, expression="#1")
4823  @Pure
4824  public static boolean eltsEqualIndex(double @Nullable [] seq) {
4825  if (seq == null) {
4826    return false;
4827  }
4828    for (int i = 0 ; i < seq.length ; i++) {
4829      if (ne(seq[i], i)) {
4830        return false;
4831      }
4832    }
4833    return true;
4834  }
4835
4836  /** True iff for all applicable i, every seq[i] != i.
4837   *
4838   * Meaning (in pseudo-FOL):
4839   *
4840   * forall i in { 0..seq.length-1 } : seq[i] != i
4841   *
4842   */
4843  @EnsuresNonNullIf(result=true, expression="#1")
4844  @Pure
4845  public static boolean eltsNotEqualIndex(double @Nullable [] seq) {
4846  if (seq == null) {
4847    return false;
4848  }
4849    for (int i = 0 ; i < seq.length ; i++) {
4850      if (eq(seq[i], i)) {
4851        return false;
4852      }
4853    }
4854    return true;
4855  }
4856
4857  /** True iff for all applicable i, every seq[i] &lt; i.
4858   *
4859   * Meaning (in pseudo-FOL):
4860   *
4861   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
4862   *
4863   */
4864  @EnsuresNonNullIf(result=true, expression="#1")
4865  @Pure
4866  public static boolean eltsLtIndex(double @Nullable [] seq) {
4867  if (seq == null) {
4868    return false;
4869  }
4870    for (int i = 0 ; i < seq.length ; i++) {
4871      if (gte(seq[i], i)) {
4872        return false;
4873      }
4874    }
4875    return true;
4876  }
4877
4878  /** True iff for all applicable i, every seq[i] &le; i.
4879   *
4880   * Meaning (in pseudo-FOL):
4881   *
4882   * forall i in { 0..seq.length-1 } : seq[i] &le; i
4883   *
4884   */
4885  @EnsuresNonNullIf(result=true, expression="#1")
4886  @Pure
4887  public static boolean eltsLteIndex(double @Nullable [] seq) {
4888  if (seq == null) {
4889    return false;
4890  }
4891    for (int i = 0 ; i < seq.length ; i++) {
4892      if (gt(seq[i], i)) {
4893        return false;
4894      }
4895    }
4896    return true;
4897  }
4898
4899  /** True iff for all applicable i, every seq[i] &gt; i.
4900   *
4901   * Meaning (in pseudo-FOL):
4902   *
4903   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
4904   *
4905   */
4906  @EnsuresNonNullIf(result=true, expression="#1")
4907  @Pure
4908  public static boolean eltsGtIndex(double @Nullable [] seq) {
4909  if (seq == null) {
4910    return false;
4911  }
4912    for (int i = 0 ; i < seq.length ; i++) {
4913      if (lte(seq[i], i)) {
4914        return false;
4915      }
4916    }
4917    return true;
4918  }
4919
4920  /** True iff for all applicable i, every seq[i] &ge; i.
4921   *
4922   * Meaning (in pseudo-FOL):
4923   *
4924   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
4925   *
4926   */
4927  @EnsuresNonNullIf(result=true, expression="#1")
4928  @Pure
4929  public static boolean eltsGteIndex(double @Nullable [] seq) {
4930  if (seq == null) {
4931    return false;
4932  }
4933    for (int i = 0 ; i < seq.length ; i++) {
4934      if (lt(seq[i], i)) {
4935        return false;
4936      }
4937    }
4938    return true;
4939  }
4940
4941  // Deferencing (accessing) fields
4942
4943  /**
4944   * collectdouble accepts an object and a list of fields (one of which is of array type, and the
4945   * rest of which are not), and produces an array in which the original object has had the given
4946   * fields accessed.
4947   *
4948   * <p>Daikon creates invariants over "variables" such as the following.
4949   *
4950   * <dl>
4951   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
4952   *              for all y's in array x.arr.</dd>
4953   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
4954   *              for all x's in array arr.</dd>
4955   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
4956   * </dl>
4957   *
4958   * <p>The collectdouble() method does this collecting work.
4959   *
4960   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
4961   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
4962   * elements that result from following the fields, one of which is assumed to be an array.
4963   *
4964   * <p>
4965   * requires: fieldStr.length() &gt; 0 and object != null
4966   * <p>
4967   * requires: fieldStr contains only field names, no "[]" strings.
4968   * <p>
4969   * requires: the method only works for field sequences with exactly one field representing an
4970   * array. For example, the collection a[].b[].c will fail.
4971   *
4972   * @return if the resulting collection is of non-primitive type, then returns an array of type
4973   * Object[]. Returns null if any array or field access causes an exception.
4974   */
4975
4976  @SideEffectFree
4977  public static double @Nullable [] collectdouble(@Nullable Object object, @Nullable String fieldStr) {
4978
4979    if (object == null) {
4980      return null;
4981    }
4982    if (fieldStr == null) {
4983      return null;
4984    }
4985
4986    // assert fieldStr != null && !"".equals(fieldStr);
4987    String[] fieldNames = fieldStr.split("\\.");
4988    double[] retval = collectdouble(object, fieldNames, 0);
4989    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
4990    return retval;
4991  }
4992
4993  // @PolyNull does not work for return type, because null is returned on error.
4994  /** Helper method for collectdouble(Object, String).
4995   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
4996   * @see collectdouble(Object, String)
4997   */
4998
4999  @SideEffectFree
5000  private static double @Nullable [] collectdouble(@Nullable Object object,
5001                                                   String[] fields, int fieldsStartIdx) {
5002
5003    if (object == null) {
5004      return null;
5005    }
5006    assert (fields != null);
5007    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
5008
5009    Object fieldObj;
5010    try {
5011      Field field = (object instanceof java.lang.Class<?>)
5012        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
5013        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
5014      field.setAccessible(true);
5015      // Class cls = field.getType();
5016      fieldObj = field.get(object);
5017      // System.out.println("***fieldObj="+fieldObj);
5018
5019    } catch (Exception e) {
5020      return null;
5021
5022    }
5023
5024    if (fieldObj == null) {
5025      return null;
5026    }
5027
5028    // base case: just accessed the last field
5029    if (fields.length - 1 == fieldsStartIdx) {
5030
5031      if (fieldObj.getClass().isArray()) {
5032        // last field is an array
5033        return (double[])fieldObj;
5034      } else {
5035        // This hack should be removed in favor of, at "oneEltArray = ..."
5036        // below, calling a version of collectdouble_field that throws an
5037        // error.  Then, this case becomes a run-time error.  -MDE
5038
5039        // Just one element; return a one-element array.
5040        // assert cls.equals(Double.TYPE);
5041        return new double[] { ((Double)fieldObj).doubleValue() };
5042      }
5043    } else {
5044      // recursive case: more fields to access after this one
5045
5046      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
5047
5048        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
5049        double[] intermediate = new double[collection.size()];
5050        int index = 0;
5051        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
5052          Object obj = i.next();
5053          double[] oneEltArray = collectdouble(obj, fields, fieldsStartIdx + 1);
5054          if (oneEltArray == null) {
5055            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
5056          }
5057          // assert oneEltArray.length == 1;
5058          intermediate[index++] = oneEltArray[0];
5059        }
5060        return intermediate;
5061      } else if (fieldObj.getClass().isArray()) {
5062
5063        // collect elements across array
5064        double[] intermediate = new double[Array.getLength(fieldObj)];
5065        for (int i = 0 ; i < intermediate.length ; i++) {
5066          Object obj = Array.get(fieldObj, i);
5067          double[] oneEltArray = collectdouble(obj, fields, fieldsStartIdx + 1);
5068          if (oneEltArray == null) {
5069            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
5070          }
5071          // assert oneEltArray.length == 1;
5072          intermediate[i] = oneEltArray[0];
5073        }
5074        return intermediate;
5075      } else {
5076
5077        return collectdouble(fieldObj, fields, fieldsStartIdx + 1);
5078      }
5079    }
5080  }
5081
5082  /**
5083   * Returns the results of dereferencing the fields for 'object'. For example, the call
5084   *
5085   * <pre>collectdouble_field(x, "f.g.h")</pre>
5086   *
5087   * has the same value as
5088   *
5089   * <pre>x.f.g.h</pre>.
5090   * Returns a default value if any field access causes an exception.
5091   */
5092  @SideEffectFree
5093  public static double collectdouble_field(Object object, String fieldStr) {
5094
5095    if (object == null) {
5096      return Double.NaN; // return default value
5097    }
5098    if (fieldStr == null) {
5099      return Double.NaN; // return default value
5100    }
5101
5102    String[] fieldNames = fieldStr.split("\\.");
5103
5104    // Holds the intermediate (and final) result
5105    Object fieldObj = object;
5106
5107    for (int i = 0 ; i < fieldNames.length ; i++) {
5108
5109      String fieldName = fieldNames[i];
5110
5111      try {
5112        Field field =
5113          (fieldObj instanceof java.lang.Class<?>)
5114          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
5115          : fieldObj.getClass().getDeclaredField(fieldName);
5116        field.setAccessible(true);
5117        fieldObj = field.get(fieldObj);
5118
5119        if (fieldObj == null) {
5120          return Double.NaN; // return default value
5121        }
5122
5123      } catch (Exception e) {
5124        return Double.NaN; // return default value
5125
5126      }
5127
5128    }
5129
5130    return ((Double)fieldObj).doubleValue();
5131  }
5132
5133  // ///////////////////////////////////////////////////////////////////////////
5134  // Methods for "float" (from QuantBody.java.jpp)
5135  //
5136
5137  /**
5138   * Returns the ith element of the array or collection argument. If the argument is null or not an
5139   * array or collection, returns a default value (Float.NaN).
5140   */
5141
5142  @Pure
5143  public static float getElement_float(Object o, long i) {
5144    if (o == null) {
5145      return Float.NaN; // return default value
5146    }
5147    java.lang.Class<?> c = o.getClass();
5148    if (c.isArray()) {
5149      return java.lang.reflect.Array.getFloat(o, (int)i);
5150    } else if (o instanceof java.util.AbstractCollection<?>) {
5151      return java.lang.reflect.Array.getFloat(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
5152    } else {
5153      return Float.NaN; // return default value
5154    }
5155  }
5156
5157  @Pure
5158  public static float getElement_float(float[] arr, long i) {
5159    if (arr == null) {
5160      return Float.NaN; // return default value
5161    }
5162    return arr[(int)i];
5163  }
5164
5165  private static boolean eq(float x, float y) {
5166    return fuzzy.eq(x,y);
5167  }
5168
5169  private static boolean ne(float x, float y) {
5170    return fuzzy.ne(x,y);
5171  }
5172
5173  private static boolean lt(float x, float y) {
5174    return fuzzy.lt(x,y);
5175  }
5176
5177  private static boolean lte(float x, float y) {
5178    return fuzzy.lte(x,y);
5179  }
5180
5181  private static boolean gt(float x, float y) {
5182    return fuzzy.gt(x,y);
5183  }
5184
5185  private static boolean gte(float x, float y) {
5186    return fuzzy.gte(x,y);
5187  }
5188
5189  /** True iff both sequences are non-null and have the same length. */
5190  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
5191  @Pure
5192  public static boolean sameLength(float @Nullable [] seq1, float @Nullable [] seq2) {
5193    return ((seq1 != null)
5194            && (seq2 != null)
5195            && seq1.length == seq2.length);
5196  }
5197
5198  /** True iff both sequences are non-null and have the same length. */
5199  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
5200  @Pure
5201  public static boolean sameLength(float @Nullable [] seq1, double @Nullable [] seq2) {
5202    return ((seq1 != null)
5203            && (seq2 != null)
5204            && seq1.length == seq2.length);
5205  }
5206
5207  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
5208   *
5209   * Meaning (in pseudo-FOL):
5210   *
5211   * <pre>
5212   * /\ seq1.length == seq2.length
5213   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
5214   * </pre>
5215   *
5216   */
5217  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5218  @Pure
5219  public static boolean pairwiseDivides(float[] seq1, float[] seq2) {
5220    if (!sameLength(seq1, seq2)) {
5221      return false;
5222    }
5223    assert seq1 != null && seq2 != null; // because sameLength() = true
5224    for (int i = 0 ; i < seq1.length ; i++) {
5225      if (ne(seq1[i] % seq2[i], 0)) {
5226        return false;
5227      }
5228    }
5229    return true;
5230  }
5231  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5232  @Pure
5233  public static boolean pairwiseDivides(float[] seq1, double[] seq2) {
5234    if (!sameLength(seq1, seq2)) {
5235      return false;
5236    }
5237    assert seq1 != null && seq2 != null; // because sameLength() = true
5238    for (int i = 0 ; i < seq1.length ; i++) {
5239      if (ne(seq1[i] % seq2[i], 0)) {
5240        return false;
5241      }
5242    }
5243    return true;
5244  }
5245
5246  /**
5247   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
5248   *
5249   * Meaning (in pseudo-FOL):
5250   *
5251   * <pre>
5252   * /\ seq1.length == seq2.length
5253   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
5254   * </pre>
5255   *
5256   */
5257  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5258  @Pure
5259  public static boolean pairwiseSquare(float[] seq1, float[] seq2) {
5260    if (!sameLength(seq1, seq2)) {
5261      return false;
5262    }
5263    assert seq1 != null && seq2 != null; // because sameLength() = true
5264    for (int i = 0 ; i < seq1.length ; i++) {
5265      if (ne(seq1[i], seq2[i] * seq2[i])) {
5266        return false;
5267      }
5268    }
5269    return true;
5270  }
5271  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5272  @Pure
5273  public static boolean pairwiseSquare(float[] seq1, double[] seq2) {
5274    if (!sameLength(seq1, seq2)) {
5275      return false;
5276    }
5277    assert seq1 != null && seq2 != null; // because sameLength() = true
5278    for (int i = 0 ; i < seq1.length ; i++) {
5279
5280      if (ne(seq1[i], seq2[i] * seq2[i])) {
5281
5282        return false;
5283      }
5284    }
5285    return true;
5286  }
5287
5288  /**
5289   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
5290   *
5291   * <p>If either array is null, returns null. If either array is empty, returns only those
5292   * elements in the other array. If both arrays are empty, returns a new empty array.
5293   */
5294  @SideEffectFree
5295  public static float @PolyNull [] concat(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5296    if (seq1 == null) {
5297      return null;
5298    }
5299    if (seq2 == null) {
5300      return null;
5301    }
5302    return ArraysPlume.concat(seq1, seq2);
5303  }
5304
5305  @SideEffectFree
5306  public static double @PolyNull [] concat(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5307    if (seq1 == null) {
5308      return null;
5309    }
5310    if (seq2 == null) {
5311      return null;
5312    }
5313    // Cannot just use ArraysPlume.concat because the two arrays
5314    // have different types.  This essentially inlines that method.
5315    int newLength = seq1.length + seq2.length;
5316    double[] retval = new double[newLength];
5317
5318    for (int j = 0 ; j < seq1.length ; j++) {
5319      retval[j] = seq1[j];
5320    }
5321    System.arraycopy(seq2, 0, retval, seq1.length, seq2.length);
5322
5323    return retval;
5324  }
5325
5326  /**
5327   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
5328   * assurances about the order or repetition of elements: elements may be repeated, and their
5329   * order may be different from the order of elements in seq1 and seq2.
5330   */
5331  @SideEffectFree
5332  public static float @PolyNull [] union(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5333    if (seq1 == null) {
5334      return null;
5335    }
5336    if (seq2 == null) {
5337      return null;
5338    }
5339    return concat(seq1, seq2);
5340  }
5341
5342  @Pure
5343  public static double @PolyNull [] union(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5344    if (seq1 == null) {
5345      return null;
5346    }
5347    if (seq2 == null) {
5348      return null;
5349    }
5350    return concat(seq1, seq2);
5351  }
5352
5353  /**
5354   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
5355   * gives no assurances about the order or repetition of elements: elements may be repeated, and
5356   * their order may be different from the order of elements in seq1 and seq2.
5357   */
5358  @Pure
5359  public static float @PolyNull [] intersection(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5360    if (seq1 == null) {
5361      return null;
5362    }
5363    if (seq2 == null) {
5364      return null;
5365    }
5366    float[] intermediate = new float[Math.min(seq1.length, seq2.length)];
5367    int length = 0;
5368    for (int i = 0 ; i < seq1.length ; i++) {
5369      if (memberOf(seq1[i], seq2) ) {
5370        intermediate[length++] = seq1[i];
5371      }
5372    }
5373    return ArraysPlume.subarray(intermediate, 0, length);
5374  }
5375
5376  @Pure
5377  public static double @PolyNull [] intersection(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5378    if (seq1 == null) {
5379      return null;
5380    }
5381    if (seq2 == null) {
5382      return null;
5383    }
5384    double[] intermediate = new double[Math.min(seq1.length, seq2.length)];
5385    int length = 0;
5386    for (int i = 0 ; i < seq1.length ; i++) {
5387      if (memberOf(seq1[i], seq2) ) {
5388        intermediate[length++] = seq1[i];
5389      }
5390    }
5391    return ArraysPlume.subarray(intermediate, 0, length);
5392  }
5393
5394  /**
5395   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
5396   * no assurances about the order or repetition of elements: elements may be repeated, and their
5397   * order may be different from the order of elements in seq1 and seq2.
5398   */
5399  @Pure
5400  public static float @PolyNull [] setDiff(float @PolyNull [] seq1, float @PolyNull [] seq2) {
5401    if (seq1 == null) {
5402      return null;
5403    }
5404    if (seq2 == null) {
5405      return null;
5406    }
5407    float[] intermediate = new float[seq1.length];
5408    int length = 0;
5409    for (int i = 0 ; i < seq1.length ; i++) {
5410      if (!memberOf(seq1[i], seq2)) {
5411        intermediate[length++] = seq1[i];
5412      }
5413    }
5414    return ArraysPlume.subarray(intermediate, 0, length);
5415  }
5416
5417  @Pure
5418  public static double @PolyNull [] setDiff(float @PolyNull [] seq1, double @PolyNull [] seq2) {
5419    if (seq1 == null) {
5420      return null;
5421    }
5422    if (seq2 == null) {
5423      return null;
5424    }
5425    double[] intermediate = new double[seq1.length];
5426    int length = 0;
5427    for (int i = 0 ; i < seq1.length ; i++) {
5428      if (!memberOf(seq1[i], seq2)) {
5429        intermediate[length++] = seq1[i];
5430      }
5431    }
5432    return ArraysPlume.subarray(intermediate, 0, length);
5433  }
5434
5435  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
5436  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5437  @Pure
5438  public static boolean setEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
5439    if (seq1 == null) {
5440      return false;
5441    }
5442    if (seq2 == null) {
5443      return false;
5444    }
5445    for (int i = 0; i < seq1.length ; i++) {
5446      if (!memberOf(seq1[i], seq2) ) {
5447        return false;
5448      }
5449    }
5450    for (int i = 0; i < seq2.length ; i++) {
5451      if (!memberOf(seq2[i], seq1) ) {
5452        return false;
5453      }
5454    }
5455    return true;
5456  }
5457
5458  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5459  @Pure
5460  public static boolean setEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
5461    if (seq1 == null) {
5462      return false;
5463    }
5464    if (seq2 == null) {
5465      return false;
5466    }
5467    for (int i = 0; i < seq1.length ; i++) {
5468      if (!memberOf(seq1[i], seq2) ) {
5469        return false;
5470      }
5471    }
5472    for (int i = 0; i < seq2.length ; i++) {
5473      if (!memberOf(seq2[i], seq1) ) {
5474        return false;
5475      }
5476    }
5477    return true;
5478  }
5479
5480  /** True iff seq1 is the reverse of seq2.
5481   *
5482   * Meaning (in pseudo-FOL):
5483   *
5484   * <pre>
5485   * /\ seq1.length == seq2.length
5486   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
5487   * </pre>
5488   *
5489   */
5490  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5491  @Pure
5492  public static boolean isReverse(float[] seq1, float[] seq2) {
5493    if (!sameLength(seq1, seq2)) {
5494      return false;
5495    }
5496    assert seq1 != null && seq2 != null; // because sameLength() = true
5497    int length = seq1.length;
5498    for (int i = 0 ; i < length ; i++) {
5499      if (ne(seq1[i], seq2[length - i - 1])) {
5500        return false;
5501      }
5502    }
5503    return true;
5504  }
5505
5506  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5507  @Pure
5508  public static boolean isReverse(float @Nullable [] seq1, double @Nullable [] seq2) {
5509    if (!sameLength(seq1, seq2)) {
5510      return false;
5511    }
5512    assert seq1 != null && seq2 != null; // because sameLength() = true
5513    int length = seq1.length;
5514    for (int i = 0 ; i < length ; i++) {
5515      if (ne(seq1[i], seq2[length - i - 1])) {
5516        return false;
5517      }
5518    }
5519    return true;
5520  }
5521
5522  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
5523  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5524  @Pure
5525  public static boolean subsetOf(float @Nullable [] seq1, float @Nullable [] seq2) {
5526    if (seq1 == null) {
5527      return false;
5528    }
5529    if (seq2 == null) {
5530      return false;
5531    }
5532    for (int i = 0 ; i < seq1.length ; i++) {
5533      if (!memberOf(seq1[i], seq2)) {
5534        return false;
5535      }
5536    }
5537    return true;
5538  }
5539
5540  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5541  @Pure
5542  public static boolean subsetOf(float @Nullable [] seq1, double @Nullable [] seq2) {
5543    if (seq1 == null) {
5544      return false;
5545    }
5546    if (seq2 == null) {
5547      return false;
5548    }
5549    for (int i = 0 ; i < seq1.length ; i++) {
5550      if (!memberOf(seq1[i], seq2)) {
5551        return false;
5552      }
5553    }
5554    return true;
5555  }
5556
5557  /** Returns true iff seq contains no duplicate elements. */
5558  @EnsuresNonNullIf(result=true, expression="#1")
5559  @Pure
5560  public static boolean noDups(float @Nullable [] seq) {
5561    if (seq == null) {
5562      return false;
5563    }
5564    return ArraysPlume.hasNoDuplicates(seq);
5565  }
5566
5567 /** Returns true iff elt is in array arr. */
5568  @EnsuresNonNullIf(result=true, expression="#2")
5569  @Pure
5570  public static boolean memberOf(float elt, float @Nullable [] arr) {
5571    if (arr == null) {
5572      return false;
5573    }
5574    for (int i = 0 ; i < arr.length ; i++) {
5575      if (eq(arr[i], elt)) {
5576        return true;
5577      }
5578    }
5579    return false;
5580  }
5581
5582  @EnsuresNonNullIf(result=true, expression="#2")
5583  @Pure
5584  public static boolean memberOf(float elt, double @Nullable [] arr) {
5585    if (arr == null) {
5586      return false;
5587    }
5588    for (int i = 0 ; i < arr.length ; i++) {
5589      if (eq(arr[i], elt)) {
5590        return true;
5591      }
5592    }
5593    return false;
5594  }
5595
5596  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
5597  @Pure
5598  public static float @PolyNull [] slice(float @PolyNull [] seq, int start, int end) {
5599    if (seq == null) {
5600      return null;
5601    }
5602    int sliceStart = start;
5603    int sliceEnd = end;
5604    if (start < 0) {
5605      return new float[] { };
5606    }
5607    if (end > seq.length - 1) {
5608      return new float[] { };
5609    }
5610    if (sliceStart > sliceEnd) {
5611      return new float[] { };
5612    }
5613    int length = sliceEnd - sliceStart + 1;
5614    return ArraysPlume.subarray(seq, sliceStart, length);
5615  }
5616
5617  @Pure
5618  public static float @PolyNull [] slice(float @PolyNull [] seq, long start, int end) {
5619    return slice(seq, (int)start, end);
5620  }
5621  @Pure
5622  public static float @PolyNull [] slice(float @PolyNull [] seq, int start, long end) {
5623    return slice(seq, start, (int)end);
5624  }
5625  @Pure
5626  public static float @PolyNull [] slice(float @PolyNull [] seq, long start, long end) {
5627    return slice(seq, (int)start, (int)end);
5628  }
5629
5630  /** True iff all elements in arr equal elt.
5631   *
5632   * Meaning (in pseudo-FOL):
5633   *
5634   * forall i in { 0..arr.length-1 } : arr[i] == elt
5635   *
5636   */
5637  @EnsuresNonNullIf(result=true, expression="#1")
5638  @Pure
5639  public static boolean eltsEqual(float @Nullable [] arr, float elt) {
5640    if (arr == null) {
5641      return false;
5642    }
5643    for (int i = 0 ; i < arr.length ; i++) {
5644      if (ne(arr[i], elt)) {
5645        return false;
5646      }
5647    }
5648    return true;
5649  }
5650
5651  @EnsuresNonNullIf(result=true, expression="#1")
5652  @Pure
5653  public static boolean eltsEqual(float @Nullable [] arr, double elt) {
5654    if (arr == null) {
5655      return false;
5656    }
5657    for (int i = 0 ; i < arr.length ; i++) {
5658      if (ne(arr[i], elt)) {
5659        return false;
5660      }
5661    }
5662    return true;
5663  }
5664
5665  /** True iff every element in arr does not equal elt.
5666   *
5667   * Meaning (in pseudo-FOL):
5668   *
5669   * forall i in { 0..arr.length-1 } : arr[i] != elt
5670   *
5671   */
5672  @EnsuresNonNullIf(result=true, expression="#1")
5673  @Pure
5674  public static boolean eltsNotEqual(float @Nullable [] arr, float elt) {
5675    if (arr == null) {
5676      return false;
5677    }
5678    for (int i = 0 ; i < arr.length ; i++) {
5679      if (eq(arr[i], elt)) {
5680        return false;
5681      }
5682    }
5683    return true;
5684  }
5685
5686  @EnsuresNonNullIf(result=true, expression="#1")
5687  @Pure
5688  public static boolean eltsNotEqual(float @Nullable [] arr, double elt) {
5689    if (arr == null) {
5690      return false;
5691    }
5692    for (int i = 0 ; i < arr.length ; i++) {
5693      if (eq(arr[i], elt)) {
5694        return false;
5695      }
5696    }
5697    return true;
5698  }
5699
5700  /** True iff every element in arr is greater than elt.
5701   *
5702   * Meaning (in pseudo-FOL):
5703   *
5704   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
5705   *
5706   */
5707  @EnsuresNonNullIf(result=true, expression="#1")
5708  @Pure
5709  public static boolean eltsGT(float @Nullable [] arr, float elt) {
5710    if (arr == null) {
5711      return false;
5712    }
5713    for (int i = 0 ; i < arr.length ; i++) {
5714      if (lte(arr[i], elt)) {
5715        return false;
5716      }
5717    }
5718    return true;
5719  }
5720
5721  @EnsuresNonNullIf(result=true, expression="#1")
5722  @Pure
5723  public static boolean eltsGT(float @Nullable [] arr, double elt) {
5724    if (arr == null) {
5725      return false;
5726    }
5727    for (int i = 0 ; i < arr.length ; i++) {
5728      if (lte(arr[i], elt)) {
5729        return false;
5730      }
5731    }
5732    return true;
5733  }
5734
5735  /** True iff every element in arr is greater than or equal to elt.
5736   *
5737   * Meaning (in pseudo-FOL):
5738   *
5739   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
5740   *
5741   */
5742  @EnsuresNonNullIf(result=true, expression="#1")
5743  @Pure
5744  public static boolean eltsGTE(float @Nullable [] arr, float elt) {
5745    if (arr == null) {
5746      return false;
5747    }
5748    for (int i = 0 ; i < arr.length ; i++) {
5749      if (lt(arr[i], elt)) {
5750        return false;
5751      }
5752    }
5753    return true;
5754  }
5755
5756  @EnsuresNonNullIf(result=true, expression="#1")
5757  @Pure
5758  public static boolean eltsGTE(float @Nullable [] arr, double elt) {
5759    if (arr == null) {
5760      return false;
5761    }
5762    for (int i = 0 ; i < arr.length ; i++) {
5763      if (lt(arr[i], elt)) {
5764        return false;
5765      }
5766    }
5767    return true;
5768  }
5769
5770  /** True iff every element in arr is less than elt.
5771   *
5772   * Meaning (in pseudo-FOL):
5773   *
5774   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
5775   *
5776   */
5777  @EnsuresNonNullIf(result=true, expression="#1")
5778  @Pure
5779  public static boolean eltsLT(float @Nullable [] arr, float elt) {
5780    if (arr == null) {
5781      return false;
5782    }
5783    for (int i = 0 ; i < arr.length ; i++) {
5784      if (gte(arr[i], elt)) {
5785        return false;
5786      }
5787    }
5788    return true;
5789  }
5790
5791  @EnsuresNonNullIf(result=true, expression="#1")
5792  @Pure
5793  public static boolean eltsLT(float @Nullable [] arr, double elt) {
5794    if (arr == null) {
5795      return false;
5796    }
5797    for (int i = 0 ; i < arr.length ; i++) {
5798      if (gte(arr[i], elt)) {
5799        return false;
5800      }
5801    }
5802    return true;
5803  }
5804
5805  /** True iff every element in arr is less than or equal to elt.
5806   *
5807   * Meaning (in pseudo-FOL):
5808   *
5809   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
5810   *
5811   */
5812  @EnsuresNonNullIf(result=true, expression="#1")
5813  @Pure
5814  public static boolean eltsLTE(float @Nullable [] arr, float elt) {
5815    if (arr == null) {
5816      return false;
5817    }
5818    for (int i = 0 ; i < arr.length ; i++) {
5819      if (gt(arr[i], elt)) {
5820        return false;
5821      }
5822    }
5823    return true;
5824  }
5825
5826  @EnsuresNonNullIf(result=true, expression="#1")
5827  @Pure
5828  public static boolean eltsLTE(float @Nullable [] arr, double elt) {
5829    if (arr == null) {
5830      return false;
5831    }
5832    for (int i = 0 ; i < arr.length ; i++) {
5833      if (gt(arr[i], elt)) {
5834        return false;
5835      }
5836    }
5837    return true;
5838  }
5839
5840  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
5841   *
5842   * Meaning (in pseudo-FOL):
5843   *
5844   * /\ seq1.length == se2.length
5845   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
5846   *
5847   */
5848
5849  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5850  @Pure
5851  public static boolean pairwiseEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
5852    if (!sameLength(seq1, seq2)) {
5853      return false;
5854    }
5855    assert seq1 != null && seq2 != null; // because sameLength() = true
5856    for (int i = 0 ; i < seq1.length ; i++) {
5857      if (Float.isNaN(seq1[i]) && Float.isNaN(seq2[i])) {
5858        continue;
5859      }
5860      if (ne(seq1[i], seq2[i])) {
5861        return false;
5862      }
5863    }
5864    return true;
5865  }
5866
5867  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5868  @Pure
5869  public static boolean pairwiseEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
5870    if (!sameLength(seq1, seq2)) {
5871      return false;
5872    }
5873    assert seq1 != null && seq2 != null; // because sameLength() = true
5874    for (int i = 0 ; i < seq1.length ; i++) {
5875      if (ne(seq1[i], seq2[i])) {
5876        return false;
5877      }
5878    }
5879    return true;
5880  }
5881
5882  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
5883   *
5884   * Meaning (in pseudo-FOL):
5885   *
5886   * /\ seq1.length == se2.length
5887   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
5888   *
5889   */
5890  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5891  @Pure
5892  public static boolean pairwiseNotEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
5893    if (!sameLength(seq1, seq2)) {
5894      return false;
5895    }
5896    assert seq1 != null && seq2 != null; // because sameLength() = true
5897    for (int i = 0 ; i < seq1.length ; i++) {
5898      if (eq(seq1[i], seq2[i])) {
5899        return false;
5900      }
5901    }
5902    return true;
5903  }
5904
5905  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5906  @Pure
5907  public static boolean pairwiseNotEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
5908    if (!sameLength(seq1, seq2)) {
5909      return false;
5910    }
5911    assert seq1 != null && seq2 != null; // because sameLength() = true
5912    for (int i = 0 ; i < seq1.length ; i++) {
5913      if (eq(seq1[i], seq2[i])) {
5914        return false;
5915      }
5916    }
5917    return true;
5918  }
5919
5920  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
5921   *
5922   * Meaning (in pseudo-FOL):
5923   *
5924   * /\ seq1.length == se2.length
5925   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
5926   *
5927   */
5928  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5929  @Pure
5930  public static boolean pairwiseLT(float @Nullable [] seq1, float @Nullable [] seq2) {
5931    if (!sameLength(seq1, seq2)) {
5932      return false;
5933    }
5934    assert seq1 != null && seq2 != null; // because sameLength() = true
5935    for (int i = 0 ; i < seq1.length ; i++) {
5936      if (gte(seq1[i], seq2[i])) {
5937        return false;
5938      }
5939    }
5940    return true;
5941  }
5942
5943  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5944  @Pure
5945  public static boolean pairwiseLT(float @Nullable [] seq1, double @Nullable [] seq2) {
5946    if (!sameLength(seq1, seq2)) {
5947      return false;
5948    }
5949    assert seq1 != null && seq2 != null; // because sameLength() = true
5950    for (int i = 0 ; i < seq1.length ; i++) {
5951      if (gte(seq1[i], seq2[i])) {
5952        return false;
5953      }
5954    }
5955    return true;
5956  }
5957
5958  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
5959   * Meaning (in pseudo-FOL):
5960   *
5961   * /\ seq1.length == se2.length
5962   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
5963   *
5964   */
5965  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5966  @Pure
5967  public static boolean pairwiseLTE(float @Nullable [] seq1, float @Nullable [] seq2) {
5968    if (!sameLength(seq1, seq2)) {
5969      return false;
5970    }
5971    assert seq1 != null && seq2 != null; // because sameLength() = true
5972    for (int i = 0 ; i < seq1.length ; i++) {
5973      if (gt(seq1[i], seq2[i])) {
5974        return false;
5975      }
5976    }
5977    return true;
5978  }
5979
5980  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
5981  @Pure
5982  public static boolean pairwiseLTE(float @Nullable [] seq1, double @Nullable [] seq2) {
5983    if (!sameLength(seq1, seq2)) {
5984      return false;
5985    }
5986    assert seq1 != null && seq2 != null; // because sameLength() = true
5987    for (int i = 0 ; i < seq1.length ; i++) {
5988      if (gt(seq1[i], seq2[i])) {
5989        return false;
5990      }
5991    }
5992    return true;
5993  }
5994
5995  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
5996   * Meaning (in pseudo-FOL):
5997   *
5998   * /\ seq1.length == se2.length
5999   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
6000   *
6001   */
6002  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6003  @Pure
6004  public static boolean pairwiseGT(float @Nullable [] seq1, float @Nullable [] seq2) {
6005    if (!sameLength(seq1, seq2)) {
6006      return false;
6007    }
6008    assert seq1 != null && seq2 != null; // because sameLength() = true
6009    for (int i = 0 ; i < seq1.length ; i++) {
6010      if (lte(seq1[i], seq2[i])) {
6011        return false;
6012      }
6013    }
6014    return true;
6015  }
6016
6017  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6018  @Pure
6019  public static boolean pairwiseGT(float @Nullable [] seq1, double @Nullable [] seq2) {
6020    if (!sameLength(seq1, seq2)) {
6021      return false;
6022    }
6023    assert seq1 != null && seq2 != null; // because sameLength() = true
6024    for (int i = 0 ; i < seq1.length ; i++) {
6025      if (lte(seq1[i], seq2[i])) {
6026        return false;
6027      }
6028    }
6029    return true;
6030  }
6031
6032  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
6033   * Meaning (in pseudo-FOL):
6034   *
6035   * /\ seq1.length == se2.length
6036   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
6037   *
6038   */
6039  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6040  @Pure
6041  public static boolean pairwiseGTE(float @Nullable [] seq1, float @Nullable [] seq2) {
6042    if (!sameLength(seq1, seq2)) {
6043      return false;
6044    }
6045    assert seq1 != null && seq2 != null; // because sameLength() = true
6046    for (int i = 0 ; i < seq1.length ; i++) {
6047      if (lt(seq1[i], seq2[i])) {
6048        return false;
6049      }
6050    }
6051    return true;
6052  }
6053
6054  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6055  @Pure
6056  public static boolean pairwiseGTE(float @Nullable [] seq1, double @Nullable [] seq2) {
6057    if (!sameLength(seq1, seq2)) {
6058      return false;
6059    }
6060    assert seq1 != null && seq2 != null; // because sameLength() = true
6061    for (int i = 0 ; i < seq1.length ; i++) {
6062      if (lt(seq1[i], seq2[i])) {
6063        return false;
6064      }
6065    }
6066    return true;
6067  }
6068
6069  /**
6070   * Returns true iff seq1 is lexically equal to seq2.
6071   * For equality, "lexically" and "pairwise" are the same.
6072   */
6073  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6074  @Pure
6075  public static boolean lexEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
6076    if (seq1 == null) {
6077      return false;
6078    }
6079    if (seq2 == null) {
6080      return false;
6081    }
6082    return pairwiseEqual(seq1, seq2);
6083  }
6084
6085  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6086  @Pure
6087  public static boolean lexEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
6088    if (seq1 == null) {
6089      return false;
6090    }
6091    if (seq2 == null) {
6092      return false;
6093    }
6094    return pairwiseEqual(seq1, seq2);
6095  }
6096
6097  /** Returns true iff seq1 is lexically not equal to seq2. */
6098  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6099  @Pure
6100  public static boolean lexNotEqual(float @Nullable [] seq1, float @Nullable [] seq2) {
6101    if (seq1 == null) {
6102      return false;
6103    }
6104    if (seq2 == null) {
6105      return false;
6106    }
6107    return !lexEqual(seq1, seq2);
6108  }
6109
6110  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6111  @Pure
6112  public static boolean lexNotEqual(float @Nullable [] seq1, double @Nullable [] seq2) {
6113    if (seq1 == null) {
6114      return false;
6115    }
6116    if (seq2 == null) {
6117      return false;
6118    }
6119    return !lexEqual(seq1, seq2);
6120  }
6121
6122  /** Returns true iff seq1 is lexically &lt;  seq2. */
6123  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6124  @Pure
6125  public static boolean lexLT(float @Nullable [] seq1, float @Nullable [] seq2) {
6126    if (seq1 == null) {
6127      return false;
6128    }
6129    if (seq2 == null) {
6130      return false;
6131    }
6132    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6133    for (int i = 0 ; i < minlength ; i++) {
6134      if (gt(seq1[i], seq2[i])) {
6135        return false;
6136      } else if (lt(seq1[i], seq2[i])) {
6137        return true;
6138      }
6139    }
6140    if (seq1.length >= seq2.length) {
6141      return false;
6142    }
6143    return true;
6144  }
6145
6146  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6147  @Pure
6148  public static boolean lexLT(float @Nullable [] seq1, double @Nullable [] seq2) {
6149    if (seq1 == null) {
6150      return false;
6151    }
6152    if (seq2 == null) {
6153      return false;
6154    }
6155    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6156    for (int i = 0 ; i < minlength ; i++) {
6157      if (gt(seq1[i], seq2[i])) {
6158        return false;
6159        } else if (lt(seq1[i], seq2[i])) {
6160          return true;
6161        }
6162      }
6163      if (seq1.length >= seq2.length) {
6164        return false;
6165      }
6166      return true;
6167    }
6168
6169  /** Returns true iff seq1 is lexically &le; to seq2. */
6170  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6171  @Pure
6172  public static boolean lexLTE(float @Nullable [] seq1, float @Nullable [] seq2) {
6173    if (seq1 == null) {
6174      return false;
6175    }
6176    if (seq2 == null) {
6177      return false;
6178    }
6179    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6180    for (int i = 0 ; i < minlength ; i++) {
6181      if (gt(seq1[i], seq2[i])) {
6182        return false;
6183      } else if (lt(seq1[i], seq2[i])) {
6184        return true;
6185      }
6186    }
6187    if (seq1.length > seq2.length) {
6188      return false;
6189    }
6190    return true;
6191  }
6192
6193  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6194  @Pure
6195  public static boolean lexLTE(float @Nullable [] seq1, double @Nullable [] seq2) {
6196  if (seq1 == null) {
6197    return false;
6198  }
6199  if (seq2 == null) {
6200    return false;
6201  }
6202    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6203    for (int i = 0 ; i < minlength ; i++) {
6204      if (gt(seq1[i], seq2[i])) {
6205        return false;
6206      } else if (lt(seq1[i], seq2[i])) {
6207        return true;
6208      }
6209    }
6210    if (seq1.length > seq2.length) {
6211      return false;
6212    }
6213    return true;
6214  }
6215
6216  /** Returns true iff seq1 is lexically &gt; to seq2. */
6217  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6218  @Pure
6219  public static boolean lexGT(float @Nullable [] seq1, float @Nullable [] seq2) {
6220  if (seq1 == null) {
6221    return false;
6222  }
6223  if (seq2 == null) {
6224    return false;
6225  }
6226    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6227    for (int i = 0 ; i < minlength ; i++) {
6228      if (lt(seq1[i], seq2[i])) {
6229        return false;
6230      } else if (gt(seq1[i], seq2[i])) {
6231        return true;
6232      }
6233    }
6234    if (seq1.length <= seq2.length) {
6235      return false;
6236    }
6237    return true;
6238  }
6239
6240  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6241  @Pure
6242  public static boolean lexGT(float @Nullable [] seq1, double @Nullable [] seq2) {
6243  if (seq1 == null) {
6244    return false;
6245  }
6246  if (seq2 == null) {
6247    return false;
6248  }
6249    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6250    for (int i = 0 ; i < minlength ; i++) {
6251      if (lt(seq1[i], seq2[i])) {
6252        return false;
6253      } else if (gt(seq1[i], seq2[i])) {
6254        return true;
6255      }
6256    }
6257    if (seq1.length <= seq2.length) {
6258      return false;
6259    }
6260    return true;
6261  }
6262
6263  /** Returns true iff seq1 is lexically &ge; to seq2. */
6264  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6265  @Pure
6266  public static boolean lexGTE(float @Nullable [] seq1, float @Nullable [] seq2) {
6267  if (seq1 == null) {
6268    return false;
6269  }
6270  if (seq2 == null) {
6271    return false;
6272  }
6273    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6274    for (int i = 0 ; i < minlength ; i++) {
6275      if (lt(seq1[i], seq2[i])) {
6276        return false;
6277      } else if (gt(seq1[i], seq2[i])) {
6278        return true;
6279      }
6280    }
6281    if (seq1.length < seq2.length) {
6282      return false;
6283    }
6284    return true;
6285  }
6286
6287  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6288  @Pure
6289  public static boolean lexGTE(float @Nullable [] seq1, double @Nullable [] seq2) {
6290  if (seq1 == null) {
6291    return false;
6292  }
6293  if (seq2 == null) {
6294    return false;
6295  }
6296    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
6297    for (int i = 0 ; i < minlength ; i++) {
6298      if (lt(seq1[i], seq2[i])) {
6299        return false;
6300      } else if (gt(seq1[i], seq2[i])) {
6301        return true;
6302      }
6303    }
6304    if (seq1.length < seq2.length) {
6305      return false;
6306    }
6307    return true;
6308  }
6309
6310  /** True iff for all applicable i, every seq[i] == seq[i+1].
6311   *
6312   * Meaning (in pseudo-FOL):
6313   *
6314   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
6315   *
6316   */
6317  @EnsuresNonNullIf(result=true, expression="#1")
6318  @Pure
6319  public static boolean eltwiseEqual(float @Nullable [] seq) {
6320  if (seq == null) {
6321    return false;
6322  }
6323    for (int i = 0 ; i < seq.length ; i++) {
6324      if (i < seq.length - 1) {
6325        if (ne(seq[i], seq[i + 1])) {
6326          return false;
6327        }
6328      }
6329    }
6330    return true;
6331  }
6332
6333  /** True iff for all applicable i, every seq[i] != seq[i+1].
6334   *
6335   * Meaning (in pseudo-FOL):
6336   *
6337   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
6338   *
6339   */
6340  @EnsuresNonNullIf(result=true, expression="#1")
6341  @Pure
6342  public static boolean eltwiseNotEqual(float @Nullable [] seq) {
6343  if (seq == null) {
6344    return false;
6345  }
6346    for (int i = 0 ; i < seq.length ; i++) {
6347      if (i < seq.length - 1) {
6348        if (eq(seq[i], seq[i + 1])) {
6349          return false;
6350        }
6351      }
6352    }
6353    return true;
6354  }
6355
6356  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
6357   *
6358   * Meaning (in pseudo-FOL):
6359   *
6360   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
6361   *
6362   */
6363  @EnsuresNonNullIf(result=true, expression="#1")
6364  @Pure
6365  public static boolean eltwiseLT(float @Nullable [] seq) {
6366  if (seq == null) {
6367    return false;
6368  }
6369    for (int i = 0 ; i < seq.length ; i++) {
6370      if (i < seq.length - 1) {
6371        if (gte(seq[i], seq[i + 1])) {
6372          return false;
6373        }
6374      }
6375    }
6376    return true;
6377  }
6378
6379  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
6380   *
6381   * Meaning (in pseudo-FOL):
6382   *
6383   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
6384   *
6385   */
6386  @EnsuresNonNullIf(result=true, expression="#1")
6387  @Pure
6388  public static boolean eltwiseLTE(float @Nullable [] seq) {
6389  if (seq == null) {
6390    return false;
6391  }
6392    for (int i = 0 ; i < seq.length ; i++) {
6393      if (i < seq.length - 1) {
6394        if (gt(seq[i], seq[i + 1])) {
6395          return false;
6396        }
6397      }
6398    }
6399    return true;
6400  }
6401
6402  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
6403   *
6404   * Meaning (in pseudo-FOL):
6405   *
6406   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
6407   *
6408   */
6409  @EnsuresNonNullIf(result=true, expression="#1")
6410  @Pure
6411  public static boolean eltwiseGT(float @Nullable [] seq) {
6412  if (seq == null) {
6413    return false;
6414  }
6415    for (int i = 0 ; i < seq.length ; i++) {
6416      if (i < seq.length - 1) {
6417        if (lte(seq[i], seq[i + 1])) {
6418          return false;
6419        }
6420      }
6421    }
6422    return true;
6423  }
6424
6425  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
6426   *
6427   * Meaning (in pseudo-FOL):
6428   *
6429   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
6430   *
6431   */
6432  @EnsuresNonNullIf(result=true, expression="#1")
6433  @Pure
6434  public static boolean eltwiseGTE(float @Nullable [] seq) {
6435  if (seq == null) {
6436    return false;
6437  }
6438    for (int i = 0 ; i < seq.length ; i++) {
6439      if (i < seq.length - 1) {
6440        if (lt(seq[i], seq[i + 1])) {
6441          return false;
6442        }
6443      }
6444    }
6445    return true;
6446  }
6447
6448  /** True iff for all applicable i, every seq[i] == i.
6449   *
6450   * Meaning (in pseudo-FOL):
6451   *
6452   * forall i in { 0..seq.length-1 } : seq[i] == i
6453   *
6454   */
6455  @EnsuresNonNullIf(result=true, expression="#1")
6456  @Pure
6457  public static boolean eltsEqualIndex(float @Nullable [] seq) {
6458  if (seq == null) {
6459    return false;
6460  }
6461    for (int i = 0 ; i < seq.length ; i++) {
6462      if (ne(seq[i], i)) {
6463        return false;
6464      }
6465    }
6466    return true;
6467  }
6468
6469  /** True iff for all applicable i, every seq[i] != i.
6470   *
6471   * Meaning (in pseudo-FOL):
6472   *
6473   * forall i in { 0..seq.length-1 } : seq[i] != i
6474   *
6475   */
6476  @EnsuresNonNullIf(result=true, expression="#1")
6477  @Pure
6478  public static boolean eltsNotEqualIndex(float @Nullable [] seq) {
6479  if (seq == null) {
6480    return false;
6481  }
6482    for (int i = 0 ; i < seq.length ; i++) {
6483      if (eq(seq[i], i)) {
6484        return false;
6485      }
6486    }
6487    return true;
6488  }
6489
6490  /** True iff for all applicable i, every seq[i] &lt; i.
6491   *
6492   * Meaning (in pseudo-FOL):
6493   *
6494   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
6495   *
6496   */
6497  @EnsuresNonNullIf(result=true, expression="#1")
6498  @Pure
6499  public static boolean eltsLtIndex(float @Nullable [] seq) {
6500  if (seq == null) {
6501    return false;
6502  }
6503    for (int i = 0 ; i < seq.length ; i++) {
6504      if (gte(seq[i], i)) {
6505        return false;
6506      }
6507    }
6508    return true;
6509  }
6510
6511  /** True iff for all applicable i, every seq[i] &le; i.
6512   *
6513   * Meaning (in pseudo-FOL):
6514   *
6515   * forall i in { 0..seq.length-1 } : seq[i] &le; i
6516   *
6517   */
6518  @EnsuresNonNullIf(result=true, expression="#1")
6519  @Pure
6520  public static boolean eltsLteIndex(float @Nullable [] seq) {
6521  if (seq == null) {
6522    return false;
6523  }
6524    for (int i = 0 ; i < seq.length ; i++) {
6525      if (gt(seq[i], i)) {
6526        return false;
6527      }
6528    }
6529    return true;
6530  }
6531
6532  /** True iff for all applicable i, every seq[i] &gt; i.
6533   *
6534   * Meaning (in pseudo-FOL):
6535   *
6536   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
6537   *
6538   */
6539  @EnsuresNonNullIf(result=true, expression="#1")
6540  @Pure
6541  public static boolean eltsGtIndex(float @Nullable [] seq) {
6542  if (seq == null) {
6543    return false;
6544  }
6545    for (int i = 0 ; i < seq.length ; i++) {
6546      if (lte(seq[i], i)) {
6547        return false;
6548      }
6549    }
6550    return true;
6551  }
6552
6553  /** True iff for all applicable i, every seq[i] &ge; i.
6554   *
6555   * Meaning (in pseudo-FOL):
6556   *
6557   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
6558   *
6559   */
6560  @EnsuresNonNullIf(result=true, expression="#1")
6561  @Pure
6562  public static boolean eltsGteIndex(float @Nullable [] seq) {
6563  if (seq == null) {
6564    return false;
6565  }
6566    for (int i = 0 ; i < seq.length ; i++) {
6567      if (lt(seq[i], i)) {
6568        return false;
6569      }
6570    }
6571    return true;
6572  }
6573
6574  // Deferencing (accessing) fields
6575
6576  /**
6577   * collectfloat accepts an object and a list of fields (one of which is of array type, and the
6578   * rest of which are not), and produces an array in which the original object has had the given
6579   * fields accessed.
6580   *
6581   * <p>Daikon creates invariants over "variables" such as the following.
6582   *
6583   * <dl>
6584   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
6585   *              for all y's in array x.arr.</dd>
6586   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
6587   *              for all x's in array arr.</dd>
6588   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
6589   * </dl>
6590   *
6591   * <p>The collectfloat() method does this collecting work.
6592   *
6593   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
6594   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
6595   * elements that result from following the fields, one of which is assumed to be an array.
6596   *
6597   * <p>
6598   * requires: fieldStr.length() &gt; 0 and object != null
6599   * <p>
6600   * requires: fieldStr contains only field names, no "[]" strings.
6601   * <p>
6602   * requires: the method only works for field sequences with exactly one field representing an
6603   * array. For example, the collection a[].b[].c will fail.
6604   *
6605   * @return if the resulting collection is of non-primitive type, then returns an array of type
6606   * Object[]. Returns null if any array or field access causes an exception.
6607   */
6608
6609  @SideEffectFree
6610  public static float @Nullable [] collectfloat(@Nullable Object object, @Nullable String fieldStr) {
6611
6612    if (object == null) {
6613      return null;
6614    }
6615    if (fieldStr == null) {
6616      return null;
6617    }
6618
6619    // assert fieldStr != null && !"".equals(fieldStr);
6620    String[] fieldNames = fieldStr.split("\\.");
6621    float[] retval = collectfloat(object, fieldNames, 0);
6622    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
6623    return retval;
6624  }
6625
6626  // @PolyNull does not work for return type, because null is returned on error.
6627  /** Helper method for collectfloat(Object, String).
6628   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
6629   * @see collectfloat(Object, String)
6630   */
6631
6632  @SideEffectFree
6633  private static float @Nullable [] collectfloat(@Nullable Object object,
6634                                                   String[] fields, int fieldsStartIdx) {
6635
6636    if (object == null) {
6637      return null;
6638    }
6639    assert (fields != null);
6640    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
6641
6642    Object fieldObj;
6643    try {
6644      Field field = (object instanceof java.lang.Class<?>)
6645        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
6646        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
6647      field.setAccessible(true);
6648      // Class cls = field.getType();
6649      fieldObj = field.get(object);
6650      // System.out.println("***fieldObj="+fieldObj);
6651
6652    } catch (Exception e) {
6653      return null;
6654
6655    }
6656
6657    if (fieldObj == null) {
6658      return null;
6659    }
6660
6661    // base case: just accessed the last field
6662    if (fields.length - 1 == fieldsStartIdx) {
6663
6664      if (fieldObj.getClass().isArray()) {
6665        // last field is an array
6666        return (float[])fieldObj;
6667      } else {
6668        // This hack should be removed in favor of, at "oneEltArray = ..."
6669        // below, calling a version of collectfloat_field that throws an
6670        // error.  Then, this case becomes a run-time error.  -MDE
6671
6672        // Just one element; return a one-element array.
6673        // assert cls.equals(Float.TYPE);
6674        return new float[] { ((Float)fieldObj).floatValue() };
6675      }
6676    } else {
6677      // recursive case: more fields to access after this one
6678
6679      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
6680
6681        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
6682        float[] intermediate = new float[collection.size()];
6683        int index = 0;
6684        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
6685          Object obj = i.next();
6686          float[] oneEltArray = collectfloat(obj, fields, fieldsStartIdx + 1);
6687          if (oneEltArray == null) {
6688            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
6689          }
6690          // assert oneEltArray.length == 1;
6691          intermediate[index++] = oneEltArray[0];
6692        }
6693        return intermediate;
6694      } else if (fieldObj.getClass().isArray()) {
6695
6696        // collect elements across array
6697        float[] intermediate = new float[Array.getLength(fieldObj)];
6698        for (int i = 0 ; i < intermediate.length ; i++) {
6699          Object obj = Array.get(fieldObj, i);
6700          float[] oneEltArray = collectfloat(obj, fields, fieldsStartIdx + 1);
6701          if (oneEltArray == null) {
6702            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
6703          }
6704          // assert oneEltArray.length == 1;
6705          intermediate[i] = oneEltArray[0];
6706        }
6707        return intermediate;
6708      } else {
6709
6710        return collectfloat(fieldObj, fields, fieldsStartIdx + 1);
6711      }
6712    }
6713  }
6714
6715  /**
6716   * Returns the results of dereferencing the fields for 'object'. For example, the call
6717   *
6718   * <pre>collectfloat_field(x, "f.g.h")</pre>
6719   *
6720   * has the same value as
6721   *
6722   * <pre>x.f.g.h</pre>.
6723   * Returns a default value if any field access causes an exception.
6724   */
6725  @SideEffectFree
6726  public static float collectfloat_field(Object object, String fieldStr) {
6727
6728    if (object == null) {
6729      return Float.NaN; // return default value
6730    }
6731    if (fieldStr == null) {
6732      return Float.NaN; // return default value
6733    }
6734
6735    String[] fieldNames = fieldStr.split("\\.");
6736
6737    // Holds the intermediate (and final) result
6738    Object fieldObj = object;
6739
6740    for (int i = 0 ; i < fieldNames.length ; i++) {
6741
6742      String fieldName = fieldNames[i];
6743
6744      try {
6745        Field field =
6746          (fieldObj instanceof java.lang.Class<?>)
6747          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
6748          : fieldObj.getClass().getDeclaredField(fieldName);
6749        field.setAccessible(true);
6750        fieldObj = field.get(fieldObj);
6751
6752        if (fieldObj == null) {
6753          return Float.NaN; // return default value
6754        }
6755
6756      } catch (Exception e) {
6757        return Float.NaN; // return default value
6758
6759      }
6760
6761    }
6762
6763    return ((Float)fieldObj).floatValue();
6764  }
6765
6766  // ///////////////////////////////////////////////////////////////////////////
6767  // Methods for "int" (from QuantBody.java.jpp)
6768  //
6769
6770  /**
6771   * Returns the ith element of the array or collection argument. If the argument is null or not an
6772   * array or collection, returns a default value (Integer.MAX_VALUE).
6773   */
6774
6775  @Pure
6776  public static int getElement_int(Object o, long i) {
6777    if (o == null) {
6778      return Integer.MAX_VALUE; // return default value
6779    }
6780    java.lang.Class<?> c = o.getClass();
6781    if (c.isArray()) {
6782      return java.lang.reflect.Array.getInt(o, (int)i);
6783    } else if (o instanceof java.util.AbstractCollection<?>) {
6784      return java.lang.reflect.Array.getInt(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
6785    } else {
6786      return Integer.MAX_VALUE; // return default value
6787    }
6788  }
6789
6790  @Pure
6791  public static int getElement_int(int[] arr, long i) {
6792    if (arr == null) {
6793      return Integer.MAX_VALUE; // return default value
6794    }
6795    return arr[(int)i];
6796  }
6797
6798  private static boolean eq(int x, int y) {
6799    return x == y;
6800  }
6801
6802  private static boolean ne(int x, int y) {
6803    return x != y;
6804  }
6805
6806  private static boolean lt(int x, int y) {
6807    return x < y;
6808  }
6809
6810  private static boolean lte(int x, int y) {
6811    return x <= y;
6812  }
6813
6814  private static boolean gt(int x, int y) {
6815    return x > y;
6816  }
6817
6818  private static boolean gte(int x, int y) {
6819    return x >= y;
6820  }
6821
6822  /** True iff both sequences are non-null and have the same length. */
6823  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
6824  @Pure
6825  public static boolean sameLength(int @Nullable [] seq1, int @Nullable [] seq2) {
6826    return ((seq1 != null)
6827            && (seq2 != null)
6828            && seq1.length == seq2.length);
6829  }
6830
6831  /** True iff both sequences are non-null and have the same length. */
6832  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
6833  @Pure
6834  public static boolean sameLength(int @Nullable [] seq1, long @Nullable [] seq2) {
6835    return ((seq1 != null)
6836            && (seq2 != null)
6837            && seq1.length == seq2.length);
6838  }
6839
6840  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
6841   *
6842   * Meaning (in pseudo-FOL):
6843   *
6844   * <pre>
6845   * /\ seq1.length == seq2.length
6846   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
6847   * </pre>
6848   *
6849   */
6850  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6851  @Pure
6852  public static boolean pairwiseDivides(int[] seq1, int[] seq2) {
6853    if (!sameLength(seq1, seq2)) {
6854      return false;
6855    }
6856    assert seq1 != null && seq2 != null; // because sameLength() = true
6857    for (int i = 0 ; i < seq1.length ; i++) {
6858      if (ne(seq1[i] % seq2[i], 0)) {
6859        return false;
6860      }
6861    }
6862    return true;
6863  }
6864  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6865  @Pure
6866  public static boolean pairwiseDivides(int[] seq1, long[] seq2) {
6867    if (!sameLength(seq1, seq2)) {
6868      return false;
6869    }
6870    assert seq1 != null && seq2 != null; // because sameLength() = true
6871    for (int i = 0 ; i < seq1.length ; i++) {
6872      if (ne(seq1[i] % seq2[i], 0)) {
6873        return false;
6874      }
6875    }
6876    return true;
6877  }
6878
6879  /**
6880   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
6881   *
6882   * Meaning (in pseudo-FOL):
6883   *
6884   * <pre>
6885   * /\ seq1.length == seq2.length
6886   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
6887   * </pre>
6888   *
6889   */
6890  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6891  @Pure
6892  public static boolean pairwiseSquare(int[] seq1, int[] seq2) {
6893    if (!sameLength(seq1, seq2)) {
6894      return false;
6895    }
6896    assert seq1 != null && seq2 != null; // because sameLength() = true
6897    for (int i = 0 ; i < seq1.length ; i++) {
6898      if (ne(seq1[i], seq2[i] * seq2[i])) {
6899        return false;
6900      }
6901    }
6902    return true;
6903  }
6904  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6905  @Pure
6906  public static boolean pairwiseSquare(int[] seq1, long[] seq2) {
6907    if (!sameLength(seq1, seq2)) {
6908      return false;
6909    }
6910    assert seq1 != null && seq2 != null; // because sameLength() = true
6911    for (int i = 0 ; i < seq1.length ; i++) {
6912
6913      if (ne(seq1[i], seq2[i] * seq2[i])) {
6914
6915        return false;
6916      }
6917    }
6918    return true;
6919  }
6920
6921  /** True iff both sequences have the same length, and all seq1[i] == ~ seq2[i].
6922   *
6923   * Meaning (in pseudo-FOL):
6924   *
6925   * <pre>
6926   * /\ seq1.length == seq2.length
6927   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == ~ seq2[i]
6928   * </pre>
6929   *
6930   */
6931  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6932  @Pure
6933  public static boolean pairwiseBitwiseComplement(int[] seq1, int[] seq2) {
6934    if (!sameLength(seq1, seq2)) {
6935      return false;
6936    }
6937    assert seq1 != null && seq2 != null; // because sameLength() = true
6938    for (int i = 0 ; i < seq1.length ; i++) {
6939      if (seq1[i] != ~seq2[i]) {
6940        return false;
6941      }
6942    }
6943    return true;
6944  }
6945  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6946  @Pure
6947  public static boolean pairwiseBitwiseComplement(int[] seq1, long[] seq2) {
6948    if (!sameLength(seq1, seq2)) {
6949      return false;
6950    }
6951    assert seq1 != null && seq2 != null; // because sameLength() = true
6952    for (int i = 0 ; i < seq1.length ; i++) {
6953      if (seq1[i] != ~seq2[i]) {
6954        return false;
6955      }
6956    }
6957    return true;
6958  }
6959
6960  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6961  @Pure
6962  public static boolean pairwiseBitwiseComplement(Object[] seq1, Object[] seq2) {
6963    if (!sameLength(seq1, seq2)) {
6964      return false;
6965    }
6966    assert seq1 != null && seq2 != null; // because sameLength() = true
6967    if (!eltsNonNull(seq1)) {
6968      return false;
6969    }
6970    if (!eltsNonNull(seq2)) {
6971      return false;
6972    }
6973    int[] hashArr1 = new int[seq1.length];
6974    for (int i = 0 ; i < seq1.length ; i++) {
6975      hashArr1[i] = seq1[i].hashCode();
6976    }
6977    int[] hashArr2 = new int[seq2.length];
6978    for (int i = 0 ; i < seq2.length ; i++) {
6979      hashArr2[i] = seq2[i].hashCode();
6980    }
6981    return pairwiseBitwiseComplement(hashArr1, hashArr2);
6982  }
6983
6984  /** True iff both sequences have the same length, and all seq1[i] == (seq2[i] | seq1[i]).
6985   *
6986   * Meaning (in pseudo-FOL):
6987   *
6988   * <pre>
6989   * /\ seq1.length == seq2.length
6990   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == (seq2[i] | seq1[i])
6991   * </pre>
6992   *
6993   */
6994  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
6995  @Pure
6996  public static boolean pairwiseBitwiseSubset(int[] seq1, int[] seq2) {
6997    if (seq1 == null) {
6998      return false;
6999    }
7000    if (seq2 == null) {
7001      return false;
7002    }
7003    if (seq1.length != seq2.length) {
7004      return false;
7005    }
7006    for (int i = 0 ; i < seq1.length ; i++) {
7007      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
7008        return false;
7009      }
7010    }
7011    return true;
7012  }
7013  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7014  @Pure
7015  public static boolean pairwiseBitwiseSubset(int[] seq1, long[] seq2) {
7016    if (!sameLength(seq1, seq2)) {
7017      return false;
7018    }
7019    assert seq1 != null && seq2 != null; // because sameLength() = true
7020    for (int i = 0 ; i < seq1.length ; i++) {
7021      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
7022        return false;
7023      }
7024    }
7025    return true;
7026  }
7027
7028  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7029  @Pure
7030  public static boolean pairwiseBitwiseSubset(Object[] seq1, Object[] seq2) {
7031    if (!sameLength(seq1, seq2)) {
7032      return false;
7033    }
7034    assert seq1 != null && seq2 != null; // because sameLength() = true
7035    if (!eltsNonNull(seq1)) {
7036      return false;
7037    }
7038    if (!eltsNonNull(seq2)) {
7039      return false;
7040    }
7041    int[] hashArr1 = new int[seq1.length];
7042    for (int i = 0 ; i < seq1.length ; i++) {
7043      hashArr1[i] = seq1[i].hashCode();
7044    }
7045    int[] hashArr2 = new int[seq2.length];
7046    for (int i = 0 ; i < seq2.length ; i++) {
7047      hashArr2[i] = seq2[i].hashCode();
7048    }
7049    return pairwiseBitwiseSubset(hashArr1, hashArr2);
7050  }
7051
7052  /**
7053   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
7054   *
7055   * <p>If either array is null, returns null. If either array is empty, returns only those
7056   * elements in the other array. If both arrays are empty, returns a new empty array.
7057   */
7058  @SideEffectFree
7059  public static int @PolyNull [] concat(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7060    if (seq1 == null) {
7061      return null;
7062    }
7063    if (seq2 == null) {
7064      return null;
7065    }
7066    return ArraysPlume.concat(seq1, seq2);
7067  }
7068
7069  @SideEffectFree
7070  public static long @PolyNull [] concat(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7071    if (seq1 == null) {
7072      return null;
7073    }
7074    if (seq2 == null) {
7075      return null;
7076    }
7077    // Cannot just use ArraysPlume.concat because the two arrays
7078    // have different types.  This essentially inlines that method.
7079    int newLength = seq1.length + seq2.length;
7080    long[] retval = new long[newLength];
7081
7082    for (int j = 0 ; j < seq1.length ; j++) {
7083      retval[j] = seq1[j];
7084    }
7085    System.arraycopy(seq2, 0, retval, seq1.length, seq2.length);
7086
7087    return retval;
7088  }
7089
7090  /**
7091   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
7092   * assurances about the order or repetition of elements: elements may be repeated, and their
7093   * order may be different from the order of elements in seq1 and seq2.
7094   */
7095  @SideEffectFree
7096  public static int @PolyNull [] union(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7097    if (seq1 == null) {
7098      return null;
7099    }
7100    if (seq2 == null) {
7101      return null;
7102    }
7103    return concat(seq1, seq2);
7104  }
7105
7106  @Pure
7107  public static long @PolyNull [] union(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7108    if (seq1 == null) {
7109      return null;
7110    }
7111    if (seq2 == null) {
7112      return null;
7113    }
7114    return concat(seq1, seq2);
7115  }
7116
7117  /**
7118   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
7119   * gives no assurances about the order or repetition of elements: elements may be repeated, and
7120   * their order may be different from the order of elements in seq1 and seq2.
7121   */
7122  @Pure
7123  public static int @PolyNull [] intersection(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7124    if (seq1 == null) {
7125      return null;
7126    }
7127    if (seq2 == null) {
7128      return null;
7129    }
7130    int[] intermediate = new int[Math.min(seq1.length, seq2.length)];
7131    int length = 0;
7132    for (int i = 0 ; i < seq1.length ; i++) {
7133      if (memberOf(seq1[i], seq2) ) {
7134        intermediate[length++] = seq1[i];
7135      }
7136    }
7137    return ArraysPlume.subarray(intermediate, 0, length);
7138  }
7139
7140  @Pure
7141  public static long @PolyNull [] intersection(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7142    if (seq1 == null) {
7143      return null;
7144    }
7145    if (seq2 == null) {
7146      return null;
7147    }
7148    long[] intermediate = new long[Math.min(seq1.length, seq2.length)];
7149    int length = 0;
7150    for (int i = 0 ; i < seq1.length ; i++) {
7151      if (memberOf(seq1[i], seq2) ) {
7152        intermediate[length++] = seq1[i];
7153      }
7154    }
7155    return ArraysPlume.subarray(intermediate, 0, length);
7156  }
7157
7158  /**
7159   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
7160   * no assurances about the order or repetition of elements: elements may be repeated, and their
7161   * order may be different from the order of elements in seq1 and seq2.
7162   */
7163  @Pure
7164  public static int @PolyNull [] setDiff(int @PolyNull [] seq1, int @PolyNull [] seq2) {
7165    if (seq1 == null) {
7166      return null;
7167    }
7168    if (seq2 == null) {
7169      return null;
7170    }
7171    int[] intermediate = new int[seq1.length];
7172    int length = 0;
7173    for (int i = 0 ; i < seq1.length ; i++) {
7174      if (!memberOf(seq1[i], seq2)) {
7175        intermediate[length++] = seq1[i];
7176      }
7177    }
7178    return ArraysPlume.subarray(intermediate, 0, length);
7179  }
7180
7181  @Pure
7182  public static long @PolyNull [] setDiff(int @PolyNull [] seq1, long @PolyNull [] seq2) {
7183    if (seq1 == null) {
7184      return null;
7185    }
7186    if (seq2 == null) {
7187      return null;
7188    }
7189    long[] intermediate = new long[seq1.length];
7190    int length = 0;
7191    for (int i = 0 ; i < seq1.length ; i++) {
7192      if (!memberOf(seq1[i], seq2)) {
7193        intermediate[length++] = seq1[i];
7194      }
7195    }
7196    return ArraysPlume.subarray(intermediate, 0, length);
7197  }
7198
7199  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
7200  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7201  @Pure
7202  public static boolean setEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7203    if (seq1 == null) {
7204      return false;
7205    }
7206    if (seq2 == null) {
7207      return false;
7208    }
7209    for (int i = 0; i < seq1.length ; i++) {
7210      if (!memberOf(seq1[i], seq2) ) {
7211        return false;
7212      }
7213    }
7214    for (int i = 0; i < seq2.length ; i++) {
7215      if (!memberOf(seq2[i], seq1) ) {
7216        return false;
7217      }
7218    }
7219    return true;
7220  }
7221
7222  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7223  @Pure
7224  public static boolean setEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7225    if (seq1 == null) {
7226      return false;
7227    }
7228    if (seq2 == null) {
7229      return false;
7230    }
7231    for (int i = 0; i < seq1.length ; i++) {
7232      if (!memberOf(seq1[i], seq2) ) {
7233        return false;
7234      }
7235    }
7236    for (int i = 0; i < seq2.length ; i++) {
7237      if (!memberOf(seq2[i], seq1) ) {
7238        return false;
7239      }
7240    }
7241    return true;
7242  }
7243
7244  /** True iff seq1 is the reverse of seq2.
7245   *
7246   * Meaning (in pseudo-FOL):
7247   *
7248   * <pre>
7249   * /\ seq1.length == seq2.length
7250   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
7251   * </pre>
7252   *
7253   */
7254  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7255  @Pure
7256  public static boolean isReverse(int[] seq1, int[] seq2) {
7257    if (!sameLength(seq1, seq2)) {
7258      return false;
7259    }
7260    assert seq1 != null && seq2 != null; // because sameLength() = true
7261    int length = seq1.length;
7262    for (int i = 0 ; i < length ; i++) {
7263      if (ne(seq1[i], seq2[length - i - 1])) {
7264        return false;
7265      }
7266    }
7267    return true;
7268  }
7269
7270  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7271  @Pure
7272  public static boolean isReverse(int @Nullable [] seq1, long @Nullable [] seq2) {
7273    if (!sameLength(seq1, seq2)) {
7274      return false;
7275    }
7276    assert seq1 != null && seq2 != null; // because sameLength() = true
7277    int length = seq1.length;
7278    for (int i = 0 ; i < length ; i++) {
7279      if (ne(seq1[i], seq2[length - i - 1])) {
7280        return false;
7281      }
7282    }
7283    return true;
7284  }
7285
7286  /** True iff all elements in elts occur once or more in arr;
7287   * that is, elts is a subset of arr.
7288   *
7289   * Meaning (in pseudo-FOL):
7290   *
7291   * forall i in { 0..elt.length-1 } : elt[i] element_of arr
7292   *
7293   */
7294  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7295  @Pure
7296  public static boolean subsetOf(@Nullable Object elts, @Nullable Object arr) {
7297    if (elts == null) {
7298      return false;
7299    }
7300    if (arr == null) {
7301      return false;
7302    }
7303    if (!(elts.getClass().isArray() && arr.getClass().isArray())) {
7304      // throw new IllegalArgumentException("both arguments must be arrays.");
7305      return false;
7306    }
7307    // We know that the two arguments are arrays of different types; if
7308    // they had been of the same type, then one of the more specific
7309    // overriding versions of this method would have been called.
7310
7311    // This implementation simply calls either subsetOf(long[], long[]) or
7312    // subsetOf(double[], double[]).
7313
7314    Class<?> eltsType = elts.getClass().getComponentType();
7315    Class<?> arrType = arr.getClass().getComponentType();
7316    if (isIntegralType(eltsType) && isIntegralType(arrType)) {
7317      // Both arrays are int/long.
7318      // Cast both arrays to long and call subsetOf(long[],long[]).
7319      long[] elts_long;
7320      if (eltsType == Long.class) {
7321        elts_long = (long[]) elts;
7322      } else {
7323        elts_long = new long[Array.getLength(elts)];
7324        for (int i = 0 ; i < elts_long.length ; i++) {
7325          elts_long[i] = Array.getLong(elts, i);
7326        }
7327      }
7328      long[] arr_long;
7329      if (arrType == Long.class) {
7330        arr_long = (long[]) arr;
7331      } else {
7332        arr_long = new long[Array.getLength(arr)];
7333        for (int i = 0 ; i < arr_long.length ; i++) {
7334          arr_long[i] = Array.getLong(arr, i);
7335        }
7336      }
7337      return subsetOf(elts_long, arr_long);
7338    } else if (isNumericType(eltsType) && isNumericType(arrType)) {
7339      // At least one array is float/double.
7340      // Cast both arrays to double and call subsetOf(double[],double[])
7341      double[] elts_double = new double[Array.getLength(elts)];
7342      for (int i = 0 ; i < elts_double.length ; i++) {
7343        elts_double[i] = Array.getDouble(elts, i);
7344      }
7345      double[] arr_double = new double[Array.getLength(arr)];
7346      for (int i = 0 ; i < arr_double.length ; i++) {
7347        arr_double[i] = Array.getDouble(arr, i);
7348      }
7349      return subsetOf(elts_double, arr_double);
7350    } else {
7351      // throw new IllegalArgumentException("both arguments must be arrays of numeric types.");
7352      return false;
7353    }
7354
7355  }
7356
7357  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
7358  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7359  @Pure
7360  public static boolean subsetOf(int @Nullable [] seq1, int @Nullable [] seq2) {
7361    if (seq1 == null) {
7362      return false;
7363    }
7364    if (seq2 == null) {
7365      return false;
7366    }
7367    for (int i = 0 ; i < seq1.length ; i++) {
7368      if (!memberOf(seq1[i], seq2)) {
7369        return false;
7370      }
7371    }
7372    return true;
7373  }
7374
7375  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7376  @Pure
7377  public static boolean subsetOf(int @Nullable [] seq1, long @Nullable [] seq2) {
7378    if (seq1 == null) {
7379      return false;
7380    }
7381    if (seq2 == null) {
7382      return false;
7383    }
7384    for (int i = 0 ; i < seq1.length ; i++) {
7385      if (!memberOf(seq1[i], seq2)) {
7386        return false;
7387      }
7388    }
7389    return true;
7390  }
7391
7392  /** Returns true iff seq contains no duplicate elements. */
7393  @EnsuresNonNullIf(result=true, expression="#1")
7394  @Pure
7395  public static boolean noDups(int @Nullable [] seq) {
7396    if (seq == null) {
7397      return false;
7398    }
7399    return ArraysPlume.hasNoDuplicates(seq);
7400  }
7401
7402 /** Returns true iff elt is in array arr. */
7403  @EnsuresNonNullIf(result=true, expression="#2")
7404  @Pure
7405  public static boolean memberOf(int elt, int @Nullable [] arr) {
7406    if (arr == null) {
7407      return false;
7408    }
7409    for (int i = 0 ; i < arr.length ; i++) {
7410      if (eq(arr[i], elt)) {
7411        return true;
7412      }
7413    }
7414    return false;
7415  }
7416
7417  @EnsuresNonNullIf(result=true, expression="#2")
7418  @Pure
7419  public static boolean memberOf(int elt, long @Nullable [] arr) {
7420    if (arr == null) {
7421      return false;
7422    }
7423    for (int i = 0 ; i < arr.length ; i++) {
7424      if (eq(arr[i], elt)) {
7425        return true;
7426      }
7427    }
7428    return false;
7429  }
7430
7431  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
7432  @Pure
7433  public static int @PolyNull [] slice(int @PolyNull [] seq, int start, int end) {
7434    if (seq == null) {
7435      return null;
7436    }
7437    int sliceStart = start;
7438    int sliceEnd = end;
7439    if (start < 0) {
7440      return new int[] { };
7441    }
7442    if (end > seq.length - 1) {
7443      return new int[] { };
7444    }
7445    if (sliceStart > sliceEnd) {
7446      return new int[] { };
7447    }
7448    int length = sliceEnd - sliceStart + 1;
7449    return ArraysPlume.subarray(seq, sliceStart, length);
7450  }
7451
7452  @Pure
7453  public static int @PolyNull [] slice(int @PolyNull [] seq, long start, int end) {
7454    return slice(seq, (int)start, end);
7455  }
7456  @Pure
7457  public static int @PolyNull [] slice(int @PolyNull [] seq, int start, long end) {
7458    return slice(seq, start, (int)end);
7459  }
7460  @Pure
7461  public static int @PolyNull [] slice(int @PolyNull [] seq, long start, long end) {
7462    return slice(seq, (int)start, (int)end);
7463  }
7464
7465  /** True iff all elements in arr equal elt.
7466   *
7467   * Meaning (in pseudo-FOL):
7468   *
7469   * forall i in { 0..arr.length-1 } : arr[i] == elt
7470   *
7471   */
7472  @EnsuresNonNullIf(result=true, expression="#1")
7473  @Pure
7474  public static boolean eltsEqual(int @Nullable [] arr, int elt) {
7475    if (arr == null) {
7476      return false;
7477    }
7478    for (int i = 0 ; i < arr.length ; i++) {
7479      if (ne(arr[i], elt)) {
7480        return false;
7481      }
7482    }
7483    return true;
7484  }
7485
7486  @EnsuresNonNullIf(result=true, expression="#1")
7487  @Pure
7488  public static boolean eltsEqual(int @Nullable [] arr, long elt) {
7489    if (arr == null) {
7490      return false;
7491    }
7492    for (int i = 0 ; i < arr.length ; i++) {
7493      if (ne(arr[i], elt)) {
7494        return false;
7495      }
7496    }
7497    return true;
7498  }
7499
7500  /** True iff every element in arr does not equal elt.
7501   *
7502   * Meaning (in pseudo-FOL):
7503   *
7504   * forall i in { 0..arr.length-1 } : arr[i] != elt
7505   *
7506   */
7507  @EnsuresNonNullIf(result=true, expression="#1")
7508  @Pure
7509  public static boolean eltsNotEqual(int @Nullable [] arr, int elt) {
7510    if (arr == null) {
7511      return false;
7512    }
7513    for (int i = 0 ; i < arr.length ; i++) {
7514      if (eq(arr[i], elt)) {
7515        return false;
7516      }
7517    }
7518    return true;
7519  }
7520
7521  @EnsuresNonNullIf(result=true, expression="#1")
7522  @Pure
7523  public static boolean eltsNotEqual(int @Nullable [] arr, long elt) {
7524    if (arr == null) {
7525      return false;
7526    }
7527    for (int i = 0 ; i < arr.length ; i++) {
7528      if (eq(arr[i], elt)) {
7529        return false;
7530      }
7531    }
7532    return true;
7533  }
7534
7535  /** True iff every element in arr is greater than elt.
7536   *
7537   * Meaning (in pseudo-FOL):
7538   *
7539   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
7540   *
7541   */
7542  @EnsuresNonNullIf(result=true, expression="#1")
7543  @Pure
7544  public static boolean eltsGT(int @Nullable [] arr, int elt) {
7545    if (arr == null) {
7546      return false;
7547    }
7548    for (int i = 0 ; i < arr.length ; i++) {
7549      if (lte(arr[i], elt)) {
7550        return false;
7551      }
7552    }
7553    return true;
7554  }
7555
7556  @EnsuresNonNullIf(result=true, expression="#1")
7557  @Pure
7558  public static boolean eltsGT(int @Nullable [] arr, long elt) {
7559    if (arr == null) {
7560      return false;
7561    }
7562    for (int i = 0 ; i < arr.length ; i++) {
7563      if (lte(arr[i], elt)) {
7564        return false;
7565      }
7566    }
7567    return true;
7568  }
7569
7570  /** True iff every element in arr is greater than or equal to elt.
7571   *
7572   * Meaning (in pseudo-FOL):
7573   *
7574   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
7575   *
7576   */
7577  @EnsuresNonNullIf(result=true, expression="#1")
7578  @Pure
7579  public static boolean eltsGTE(int @Nullable [] arr, int elt) {
7580    if (arr == null) {
7581      return false;
7582    }
7583    for (int i = 0 ; i < arr.length ; i++) {
7584      if (lt(arr[i], elt)) {
7585        return false;
7586      }
7587    }
7588    return true;
7589  }
7590
7591  @EnsuresNonNullIf(result=true, expression="#1")
7592  @Pure
7593  public static boolean eltsGTE(int @Nullable [] arr, long elt) {
7594    if (arr == null) {
7595      return false;
7596    }
7597    for (int i = 0 ; i < arr.length ; i++) {
7598      if (lt(arr[i], elt)) {
7599        return false;
7600      }
7601    }
7602    return true;
7603  }
7604
7605  /** True iff every element in arr is less than elt.
7606   *
7607   * Meaning (in pseudo-FOL):
7608   *
7609   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
7610   *
7611   */
7612  @EnsuresNonNullIf(result=true, expression="#1")
7613  @Pure
7614  public static boolean eltsLT(int @Nullable [] arr, int elt) {
7615    if (arr == null) {
7616      return false;
7617    }
7618    for (int i = 0 ; i < arr.length ; i++) {
7619      if (gte(arr[i], elt)) {
7620        return false;
7621      }
7622    }
7623    return true;
7624  }
7625
7626  @EnsuresNonNullIf(result=true, expression="#1")
7627  @Pure
7628  public static boolean eltsLT(int @Nullable [] arr, long elt) {
7629    if (arr == null) {
7630      return false;
7631    }
7632    for (int i = 0 ; i < arr.length ; i++) {
7633      if (gte(arr[i], elt)) {
7634        return false;
7635      }
7636    }
7637    return true;
7638  }
7639
7640  /** True iff every element in arr is less than or equal to elt.
7641   *
7642   * Meaning (in pseudo-FOL):
7643   *
7644   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
7645   *
7646   */
7647  @EnsuresNonNullIf(result=true, expression="#1")
7648  @Pure
7649  public static boolean eltsLTE(int @Nullable [] arr, int elt) {
7650    if (arr == null) {
7651      return false;
7652    }
7653    for (int i = 0 ; i < arr.length ; i++) {
7654      if (gt(arr[i], elt)) {
7655        return false;
7656      }
7657    }
7658    return true;
7659  }
7660
7661  @EnsuresNonNullIf(result=true, expression="#1")
7662  @Pure
7663  public static boolean eltsLTE(int @Nullable [] arr, long elt) {
7664    if (arr == null) {
7665      return false;
7666    }
7667    for (int i = 0 ; i < arr.length ; i++) {
7668      if (gt(arr[i], elt)) {
7669        return false;
7670      }
7671    }
7672    return true;
7673  }
7674
7675  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
7676   *
7677   * Meaning (in pseudo-FOL):
7678   *
7679   * /\ seq1.length == se2.length
7680   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
7681   *
7682   */
7683
7684  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7685  @Pure
7686  public static boolean pairwiseEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7687    if (!sameLength(seq1, seq2)) {
7688      return false;
7689    }
7690    assert seq1 != null && seq2 != null; // because sameLength() = true
7691    for (int i = 0 ; i < seq1.length ; i++) {
7692      if (ne(seq1[i], seq2[i])) {
7693        return false;
7694      }
7695    }
7696    return true;
7697  }
7698
7699  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7700  @Pure
7701  public static boolean pairwiseEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7702    if (!sameLength(seq1, seq2)) {
7703      return false;
7704    }
7705    assert seq1 != null && seq2 != null; // because sameLength() = true
7706    for (int i = 0 ; i < seq1.length ; i++) {
7707      if (ne(seq1[i], seq2[i])) {
7708        return false;
7709      }
7710    }
7711    return true;
7712  }
7713
7714  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
7715   *
7716   * Meaning (in pseudo-FOL):
7717   *
7718   * /\ seq1.length == se2.length
7719   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
7720   *
7721   */
7722  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7723  @Pure
7724  public static boolean pairwiseNotEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7725    if (!sameLength(seq1, seq2)) {
7726      return false;
7727    }
7728    assert seq1 != null && seq2 != null; // because sameLength() = true
7729    for (int i = 0 ; i < seq1.length ; i++) {
7730      if (eq(seq1[i], seq2[i])) {
7731        return false;
7732      }
7733    }
7734    return true;
7735  }
7736
7737  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7738  @Pure
7739  public static boolean pairwiseNotEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7740    if (!sameLength(seq1, seq2)) {
7741      return false;
7742    }
7743    assert seq1 != null && seq2 != null; // because sameLength() = true
7744    for (int i = 0 ; i < seq1.length ; i++) {
7745      if (eq(seq1[i], seq2[i])) {
7746        return false;
7747      }
7748    }
7749    return true;
7750  }
7751
7752  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
7753   *
7754   * Meaning (in pseudo-FOL):
7755   *
7756   * /\ seq1.length == se2.length
7757   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
7758   *
7759   */
7760  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7761  @Pure
7762  public static boolean pairwiseLT(int @Nullable [] seq1, int @Nullable [] seq2) {
7763    if (!sameLength(seq1, seq2)) {
7764      return false;
7765    }
7766    assert seq1 != null && seq2 != null; // because sameLength() = true
7767    for (int i = 0 ; i < seq1.length ; i++) {
7768      if (gte(seq1[i], seq2[i])) {
7769        return false;
7770      }
7771    }
7772    return true;
7773  }
7774
7775  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7776  @Pure
7777  public static boolean pairwiseLT(int @Nullable [] seq1, long @Nullable [] seq2) {
7778    if (!sameLength(seq1, seq2)) {
7779      return false;
7780    }
7781    assert seq1 != null && seq2 != null; // because sameLength() = true
7782    for (int i = 0 ; i < seq1.length ; i++) {
7783      if (gte(seq1[i], seq2[i])) {
7784        return false;
7785      }
7786    }
7787    return true;
7788  }
7789
7790  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
7791   * Meaning (in pseudo-FOL):
7792   *
7793   * /\ seq1.length == se2.length
7794   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
7795   *
7796   */
7797  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7798  @Pure
7799  public static boolean pairwiseLTE(int @Nullable [] seq1, int @Nullable [] seq2) {
7800    if (!sameLength(seq1, seq2)) {
7801      return false;
7802    }
7803    assert seq1 != null && seq2 != null; // because sameLength() = true
7804    for (int i = 0 ; i < seq1.length ; i++) {
7805      if (gt(seq1[i], seq2[i])) {
7806        return false;
7807      }
7808    }
7809    return true;
7810  }
7811
7812  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7813  @Pure
7814  public static boolean pairwiseLTE(int @Nullable [] seq1, long @Nullable [] seq2) {
7815    if (!sameLength(seq1, seq2)) {
7816      return false;
7817    }
7818    assert seq1 != null && seq2 != null; // because sameLength() = true
7819    for (int i = 0 ; i < seq1.length ; i++) {
7820      if (gt(seq1[i], seq2[i])) {
7821        return false;
7822      }
7823    }
7824    return true;
7825  }
7826
7827  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
7828   * Meaning (in pseudo-FOL):
7829   *
7830   * /\ seq1.length == se2.length
7831   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
7832   *
7833   */
7834  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7835  @Pure
7836  public static boolean pairwiseGT(int @Nullable [] seq1, int @Nullable [] seq2) {
7837    if (!sameLength(seq1, seq2)) {
7838      return false;
7839    }
7840    assert seq1 != null && seq2 != null; // because sameLength() = true
7841    for (int i = 0 ; i < seq1.length ; i++) {
7842      if (lte(seq1[i], seq2[i])) {
7843        return false;
7844      }
7845    }
7846    return true;
7847  }
7848
7849  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7850  @Pure
7851  public static boolean pairwiseGT(int @Nullable [] seq1, long @Nullable [] seq2) {
7852    if (!sameLength(seq1, seq2)) {
7853      return false;
7854    }
7855    assert seq1 != null && seq2 != null; // because sameLength() = true
7856    for (int i = 0 ; i < seq1.length ; i++) {
7857      if (lte(seq1[i], seq2[i])) {
7858        return false;
7859      }
7860    }
7861    return true;
7862  }
7863
7864  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
7865   * Meaning (in pseudo-FOL):
7866   *
7867   * /\ seq1.length == se2.length
7868   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
7869   *
7870   */
7871  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7872  @Pure
7873  public static boolean pairwiseGTE(int @Nullable [] seq1, int @Nullable [] seq2) {
7874    if (!sameLength(seq1, seq2)) {
7875      return false;
7876    }
7877    assert seq1 != null && seq2 != null; // because sameLength() = true
7878    for (int i = 0 ; i < seq1.length ; i++) {
7879      if (lt(seq1[i], seq2[i])) {
7880        return false;
7881      }
7882    }
7883    return true;
7884  }
7885
7886  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7887  @Pure
7888  public static boolean pairwiseGTE(int @Nullable [] seq1, long @Nullable [] seq2) {
7889    if (!sameLength(seq1, seq2)) {
7890      return false;
7891    }
7892    assert seq1 != null && seq2 != null; // because sameLength() = true
7893    for (int i = 0 ; i < seq1.length ; i++) {
7894      if (lt(seq1[i], seq2[i])) {
7895        return false;
7896      }
7897    }
7898    return true;
7899  }
7900
7901  /**
7902   * Returns true iff seq1 is lexically equal to seq2.
7903   * For equality, "lexically" and "pairwise" are the same.
7904   */
7905  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7906  @Pure
7907  public static boolean lexEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7908    if (seq1 == null) {
7909      return false;
7910    }
7911    if (seq2 == null) {
7912      return false;
7913    }
7914    return pairwiseEqual(seq1, seq2);
7915  }
7916
7917  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7918  @Pure
7919  public static boolean lexEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7920    if (seq1 == null) {
7921      return false;
7922    }
7923    if (seq2 == null) {
7924      return false;
7925    }
7926    return pairwiseEqual(seq1, seq2);
7927  }
7928
7929  /** Returns true iff seq1 is lexically not equal to seq2. */
7930  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7931  @Pure
7932  public static boolean lexNotEqual(int @Nullable [] seq1, int @Nullable [] seq2) {
7933    if (seq1 == null) {
7934      return false;
7935    }
7936    if (seq2 == null) {
7937      return false;
7938    }
7939    return !lexEqual(seq1, seq2);
7940  }
7941
7942  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7943  @Pure
7944  public static boolean lexNotEqual(int @Nullable [] seq1, long @Nullable [] seq2) {
7945    if (seq1 == null) {
7946      return false;
7947    }
7948    if (seq2 == null) {
7949      return false;
7950    }
7951    return !lexEqual(seq1, seq2);
7952  }
7953
7954  /** Returns true iff seq1 is lexically &lt;  seq2. */
7955  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7956  @Pure
7957  public static boolean lexLT(int @Nullable [] seq1, int @Nullable [] seq2) {
7958    if (seq1 == null) {
7959      return false;
7960    }
7961    if (seq2 == null) {
7962      return false;
7963    }
7964    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
7965    for (int i = 0 ; i < minlength ; i++) {
7966      if (gt(seq1[i], seq2[i])) {
7967        return false;
7968      } else if (lt(seq1[i], seq2[i])) {
7969        return true;
7970      }
7971    }
7972    if (seq1.length >= seq2.length) {
7973      return false;
7974    }
7975    return true;
7976  }
7977
7978  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
7979  @Pure
7980  public static boolean lexLT(int @Nullable [] seq1, long @Nullable [] seq2) {
7981    if (seq1 == null) {
7982      return false;
7983    }
7984    if (seq2 == null) {
7985      return false;
7986    }
7987    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
7988    for (int i = 0 ; i < minlength ; i++) {
7989      if (gt(seq1[i], seq2[i])) {
7990        return false;
7991        } else if (lt(seq1[i], seq2[i])) {
7992          return true;
7993        }
7994      }
7995      if (seq1.length >= seq2.length) {
7996        return false;
7997      }
7998      return true;
7999    }
8000
8001  /** Returns true iff seq1 is lexically &le; to seq2. */
8002  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8003  @Pure
8004  public static boolean lexLTE(int @Nullable [] seq1, int @Nullable [] seq2) {
8005    if (seq1 == null) {
8006      return false;
8007    }
8008    if (seq2 == null) {
8009      return false;
8010    }
8011    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8012    for (int i = 0 ; i < minlength ; i++) {
8013      if (gt(seq1[i], seq2[i])) {
8014        return false;
8015      } else if (lt(seq1[i], seq2[i])) {
8016        return true;
8017      }
8018    }
8019    if (seq1.length > seq2.length) {
8020      return false;
8021    }
8022    return true;
8023  }
8024
8025  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8026  @Pure
8027  public static boolean lexLTE(int @Nullable [] seq1, long @Nullable [] seq2) {
8028  if (seq1 == null) {
8029    return false;
8030  }
8031  if (seq2 == null) {
8032    return false;
8033  }
8034    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8035    for (int i = 0 ; i < minlength ; i++) {
8036      if (gt(seq1[i], seq2[i])) {
8037        return false;
8038      } else if (lt(seq1[i], seq2[i])) {
8039        return true;
8040      }
8041    }
8042    if (seq1.length > seq2.length) {
8043      return false;
8044    }
8045    return true;
8046  }
8047
8048  /** Returns true iff seq1 is lexically &gt; to seq2. */
8049  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8050  @Pure
8051  public static boolean lexGT(int @Nullable [] seq1, int @Nullable [] seq2) {
8052  if (seq1 == null) {
8053    return false;
8054  }
8055  if (seq2 == null) {
8056    return false;
8057  }
8058    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8059    for (int i = 0 ; i < minlength ; i++) {
8060      if (lt(seq1[i], seq2[i])) {
8061        return false;
8062      } else if (gt(seq1[i], seq2[i])) {
8063        return true;
8064      }
8065    }
8066    if (seq1.length <= seq2.length) {
8067      return false;
8068    }
8069    return true;
8070  }
8071
8072  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8073  @Pure
8074  public static boolean lexGT(int @Nullable [] seq1, long @Nullable [] seq2) {
8075  if (seq1 == null) {
8076    return false;
8077  }
8078  if (seq2 == null) {
8079    return false;
8080  }
8081    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8082    for (int i = 0 ; i < minlength ; i++) {
8083      if (lt(seq1[i], seq2[i])) {
8084        return false;
8085      } else if (gt(seq1[i], seq2[i])) {
8086        return true;
8087      }
8088    }
8089    if (seq1.length <= seq2.length) {
8090      return false;
8091    }
8092    return true;
8093  }
8094
8095  /** Returns true iff seq1 is lexically &ge; to seq2. */
8096  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8097  @Pure
8098  public static boolean lexGTE(int @Nullable [] seq1, int @Nullable [] seq2) {
8099  if (seq1 == null) {
8100    return false;
8101  }
8102  if (seq2 == null) {
8103    return false;
8104  }
8105    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8106    for (int i = 0 ; i < minlength ; i++) {
8107      if (lt(seq1[i], seq2[i])) {
8108        return false;
8109      } else if (gt(seq1[i], seq2[i])) {
8110        return true;
8111      }
8112    }
8113    if (seq1.length < seq2.length) {
8114      return false;
8115    }
8116    return true;
8117  }
8118
8119  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8120  @Pure
8121  public static boolean lexGTE(int @Nullable [] seq1, long @Nullable [] seq2) {
8122  if (seq1 == null) {
8123    return false;
8124  }
8125  if (seq2 == null) {
8126    return false;
8127  }
8128    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
8129    for (int i = 0 ; i < minlength ; i++) {
8130      if (lt(seq1[i], seq2[i])) {
8131        return false;
8132      } else if (gt(seq1[i], seq2[i])) {
8133        return true;
8134      }
8135    }
8136    if (seq1.length < seq2.length) {
8137      return false;
8138    }
8139    return true;
8140  }
8141
8142  /** True iff for all applicable i, every seq[i] == seq[i+1].
8143   *
8144   * Meaning (in pseudo-FOL):
8145   *
8146   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
8147   *
8148   */
8149  @EnsuresNonNullIf(result=true, expression="#1")
8150  @Pure
8151  public static boolean eltwiseEqual(int @Nullable [] seq) {
8152  if (seq == null) {
8153    return false;
8154  }
8155    for (int i = 0 ; i < seq.length ; i++) {
8156      if (i < seq.length - 1) {
8157        if (ne(seq[i], seq[i + 1])) {
8158          return false;
8159        }
8160      }
8161    }
8162    return true;
8163  }
8164
8165  /** True iff for all applicable i, every seq[i] != seq[i+1].
8166   *
8167   * Meaning (in pseudo-FOL):
8168   *
8169   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
8170   *
8171   */
8172  @EnsuresNonNullIf(result=true, expression="#1")
8173  @Pure
8174  public static boolean eltwiseNotEqual(int @Nullable [] seq) {
8175  if (seq == null) {
8176    return false;
8177  }
8178    for (int i = 0 ; i < seq.length ; i++) {
8179      if (i < seq.length - 1) {
8180        if (eq(seq[i], seq[i + 1])) {
8181          return false;
8182        }
8183      }
8184    }
8185    return true;
8186  }
8187
8188  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
8189   *
8190   * Meaning (in pseudo-FOL):
8191   *
8192   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
8193   *
8194   */
8195  @EnsuresNonNullIf(result=true, expression="#1")
8196  @Pure
8197  public static boolean eltwiseLT(int @Nullable [] seq) {
8198  if (seq == null) {
8199    return false;
8200  }
8201    for (int i = 0 ; i < seq.length ; i++) {
8202      if (i < seq.length - 1) {
8203        if (gte(seq[i], seq[i + 1])) {
8204          return false;
8205        }
8206      }
8207    }
8208    return true;
8209  }
8210
8211  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
8212   *
8213   * Meaning (in pseudo-FOL):
8214   *
8215   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
8216   *
8217   */
8218  @EnsuresNonNullIf(result=true, expression="#1")
8219  @Pure
8220  public static boolean eltwiseLTE(int @Nullable [] seq) {
8221  if (seq == null) {
8222    return false;
8223  }
8224    for (int i = 0 ; i < seq.length ; i++) {
8225      if (i < seq.length - 1) {
8226        if (gt(seq[i], seq[i + 1])) {
8227          return false;
8228        }
8229      }
8230    }
8231    return true;
8232  }
8233
8234  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
8235   *
8236   * Meaning (in pseudo-FOL):
8237   *
8238   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
8239   *
8240   */
8241  @EnsuresNonNullIf(result=true, expression="#1")
8242  @Pure
8243  public static boolean eltwiseGT(int @Nullable [] seq) {
8244  if (seq == null) {
8245    return false;
8246  }
8247    for (int i = 0 ; i < seq.length ; i++) {
8248      if (i < seq.length - 1) {
8249        if (lte(seq[i], seq[i + 1])) {
8250          return false;
8251        }
8252      }
8253    }
8254    return true;
8255  }
8256
8257  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
8258   *
8259   * Meaning (in pseudo-FOL):
8260   *
8261   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
8262   *
8263   */
8264  @EnsuresNonNullIf(result=true, expression="#1")
8265  @Pure
8266  public static boolean eltwiseGTE(int @Nullable [] seq) {
8267  if (seq == null) {
8268    return false;
8269  }
8270    for (int i = 0 ; i < seq.length ; i++) {
8271      if (i < seq.length - 1) {
8272        if (lt(seq[i], seq[i + 1])) {
8273          return false;
8274        }
8275      }
8276    }
8277    return true;
8278  }
8279
8280  /** True iff for all applicable i, every seq[i] == i.
8281   *
8282   * Meaning (in pseudo-FOL):
8283   *
8284   * forall i in { 0..seq.length-1 } : seq[i] == i
8285   *
8286   */
8287  @EnsuresNonNullIf(result=true, expression="#1")
8288  @Pure
8289  public static boolean eltsEqualIndex(int @Nullable [] seq) {
8290  if (seq == null) {
8291    return false;
8292  }
8293    for (int i = 0 ; i < seq.length ; i++) {
8294      if (ne(seq[i], i)) {
8295        return false;
8296      }
8297    }
8298    return true;
8299  }
8300
8301  /** True iff for all applicable i, every seq[i] != i.
8302   *
8303   * Meaning (in pseudo-FOL):
8304   *
8305   * forall i in { 0..seq.length-1 } : seq[i] != i
8306   *
8307   */
8308  @EnsuresNonNullIf(result=true, expression="#1")
8309  @Pure
8310  public static boolean eltsNotEqualIndex(int @Nullable [] seq) {
8311  if (seq == null) {
8312    return false;
8313  }
8314    for (int i = 0 ; i < seq.length ; i++) {
8315      if (eq(seq[i], i)) {
8316        return false;
8317      }
8318    }
8319    return true;
8320  }
8321
8322  /** True iff for all applicable i, every seq[i] &lt; i.
8323   *
8324   * Meaning (in pseudo-FOL):
8325   *
8326   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
8327   *
8328   */
8329  @EnsuresNonNullIf(result=true, expression="#1")
8330  @Pure
8331  public static boolean eltsLtIndex(int @Nullable [] seq) {
8332  if (seq == null) {
8333    return false;
8334  }
8335    for (int i = 0 ; i < seq.length ; i++) {
8336      if (gte(seq[i], i)) {
8337        return false;
8338      }
8339    }
8340    return true;
8341  }
8342
8343  /** True iff for all applicable i, every seq[i] &le; i.
8344   *
8345   * Meaning (in pseudo-FOL):
8346   *
8347   * forall i in { 0..seq.length-1 } : seq[i] &le; i
8348   *
8349   */
8350  @EnsuresNonNullIf(result=true, expression="#1")
8351  @Pure
8352  public static boolean eltsLteIndex(int @Nullable [] seq) {
8353  if (seq == null) {
8354    return false;
8355  }
8356    for (int i = 0 ; i < seq.length ; i++) {
8357      if (gt(seq[i], i)) {
8358        return false;
8359      }
8360    }
8361    return true;
8362  }
8363
8364  /** True iff for all applicable i, every seq[i] &gt; i.
8365   *
8366   * Meaning (in pseudo-FOL):
8367   *
8368   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
8369   *
8370   */
8371  @EnsuresNonNullIf(result=true, expression="#1")
8372  @Pure
8373  public static boolean eltsGtIndex(int @Nullable [] seq) {
8374  if (seq == null) {
8375    return false;
8376  }
8377    for (int i = 0 ; i < seq.length ; i++) {
8378      if (lte(seq[i], i)) {
8379        return false;
8380      }
8381    }
8382    return true;
8383  }
8384
8385  /** True iff for all applicable i, every seq[i] &ge; i.
8386   *
8387   * Meaning (in pseudo-FOL):
8388   *
8389   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
8390   *
8391   */
8392  @EnsuresNonNullIf(result=true, expression="#1")
8393  @Pure
8394  public static boolean eltsGteIndex(int @Nullable [] seq) {
8395  if (seq == null) {
8396    return false;
8397  }
8398    for (int i = 0 ; i < seq.length ; i++) {
8399      if (lt(seq[i], i)) {
8400        return false;
8401      }
8402    }
8403    return true;
8404  }
8405
8406  // Deferencing (accessing) fields
8407
8408  /**
8409   * collectint accepts an object and a list of fields (one of which is of array type, and the
8410   * rest of which are not), and produces an array in which the original object has had the given
8411   * fields accessed.
8412   *
8413   * <p>Daikon creates invariants over "variables" such as the following.
8414   *
8415   * <dl>
8416   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
8417   *              for all y's in array x.arr.</dd>
8418   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
8419   *              for all x's in array arr.</dd>
8420   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
8421   * </dl>
8422   *
8423   * <p>The collectint() method does this collecting work.
8424   *
8425   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
8426   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
8427   * elements that result from following the fields, one of which is assumed to be an array.
8428   *
8429   * <p>
8430   * requires: fieldStr.length() &gt; 0 and object != null
8431   * <p>
8432   * requires: fieldStr contains only field names, no "[]" strings.
8433   * <p>
8434   * requires: the method only works for field sequences with exactly one field representing an
8435   * array. For example, the collection a[].b[].c will fail.
8436   *
8437   * @return if the resulting collection is of non-primitive type, then returns an array of type
8438   * Object[]. Returns null if any array or field access causes an exception.
8439   */
8440
8441  @SideEffectFree
8442  public static int @Nullable [] collectint(@Nullable Object object, @Nullable String fieldStr) {
8443
8444    if (object == null) {
8445      return null;
8446    }
8447    if (fieldStr == null) {
8448      return null;
8449    }
8450
8451    // assert fieldStr != null && !"".equals(fieldStr);
8452    String[] fieldNames = fieldStr.split("\\.");
8453    int[] retval = collectint(object, fieldNames, 0);
8454    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
8455    return retval;
8456  }
8457
8458  // @PolyNull does not work for return type, because null is returned on error.
8459  /** Helper method for collectint(Object, String).
8460   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
8461   * @see collectint(Object, String)
8462   */
8463
8464  @SideEffectFree
8465  private static int @Nullable [] collectint(@Nullable Object object,
8466                                                   String[] fields, int fieldsStartIdx) {
8467
8468    if (object == null) {
8469      return null;
8470    }
8471    assert (fields != null);
8472    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
8473
8474    Object fieldObj;
8475    try {
8476      Field field = (object instanceof java.lang.Class<?>)
8477        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
8478        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
8479      field.setAccessible(true);
8480      // Class cls = field.getType();
8481      fieldObj = field.get(object);
8482      // System.out.println("***fieldObj="+fieldObj);
8483
8484    } catch (Exception e) {
8485      return null;
8486
8487    }
8488
8489    if (fieldObj == null) {
8490      return null;
8491    }
8492
8493    // base case: just accessed the last field
8494    if (fields.length - 1 == fieldsStartIdx) {
8495
8496      if (fieldObj.getClass().isArray()) {
8497        // last field is an array
8498        return (int[])fieldObj;
8499      } else {
8500        // This hack should be removed in favor of, at "oneEltArray = ..."
8501        // below, calling a version of collectint_field that throws an
8502        // error.  Then, this case becomes a run-time error.  -MDE
8503
8504        // Just one element; return a one-element array.
8505        // assert cls.equals(Integer.TYPE);
8506        return new int[] { ((Integer)fieldObj).intValue() };
8507      }
8508    } else {
8509      // recursive case: more fields to access after this one
8510
8511      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
8512
8513        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
8514        int[] intermediate = new int[collection.size()];
8515        int index = 0;
8516        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
8517          Object obj = i.next();
8518          int[] oneEltArray = collectint(obj, fields, fieldsStartIdx + 1);
8519          if (oneEltArray == null) {
8520            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
8521          }
8522          // assert oneEltArray.length == 1;
8523          intermediate[index++] = oneEltArray[0];
8524        }
8525        return intermediate;
8526      } else if (fieldObj.getClass().isArray()) {
8527
8528        // collect elements across array
8529        int[] intermediate = new int[Array.getLength(fieldObj)];
8530        for (int i = 0 ; i < intermediate.length ; i++) {
8531          Object obj = Array.get(fieldObj, i);
8532          int[] oneEltArray = collectint(obj, fields, fieldsStartIdx + 1);
8533          if (oneEltArray == null) {
8534            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
8535          }
8536          // assert oneEltArray.length == 1;
8537          intermediate[i] = oneEltArray[0];
8538        }
8539        return intermediate;
8540      } else {
8541
8542        return collectint(fieldObj, fields, fieldsStartIdx + 1);
8543      }
8544    }
8545  }
8546
8547  /**
8548   * Returns the results of dereferencing the fields for 'object'. For example, the call
8549   *
8550   * <pre>collectint_field(x, "f.g.h")</pre>
8551   *
8552   * has the same value as
8553   *
8554   * <pre>x.f.g.h</pre>.
8555   * Returns a default value if any field access causes an exception.
8556   */
8557  @SideEffectFree
8558  public static int collectint_field(Object object, String fieldStr) {
8559
8560    if (object == null) {
8561      return Integer.MAX_VALUE; // return default value
8562    }
8563    if (fieldStr == null) {
8564      return Integer.MAX_VALUE; // return default value
8565    }
8566
8567    String[] fieldNames = fieldStr.split("\\.");
8568
8569    // Holds the intermediate (and final) result
8570    Object fieldObj = object;
8571
8572    for (int i = 0 ; i < fieldNames.length ; i++) {
8573
8574      String fieldName = fieldNames[i];
8575
8576      try {
8577        Field field =
8578          (fieldObj instanceof java.lang.Class<?>)
8579          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
8580          : fieldObj.getClass().getDeclaredField(fieldName);
8581        field.setAccessible(true);
8582        fieldObj = field.get(fieldObj);
8583
8584        if (fieldObj == null) {
8585          return Integer.MAX_VALUE; // return default value
8586        }
8587
8588      } catch (Exception e) {
8589        return Integer.MAX_VALUE; // return default value
8590
8591      }
8592
8593    }
8594
8595    return ((Integer)fieldObj).intValue();
8596  }
8597
8598  // ///////////////////////////////////////////////////////////////////////////
8599  // Methods for "long" (from QuantBody.java.jpp)
8600  //
8601
8602  /**
8603   * Returns the ith element of the array or collection argument. If the argument is null or not an
8604   * array or collection, returns a default value (Long.MAX_VALUE).
8605   */
8606
8607  @Pure
8608  public static long getElement_long(Object o, long i) {
8609    if (o == null) {
8610      return Long.MAX_VALUE; // return default value
8611    }
8612    java.lang.Class<?> c = o.getClass();
8613    if (c.isArray()) {
8614      return java.lang.reflect.Array.getLong(o, (int)i);
8615    } else if (o instanceof java.util.AbstractCollection<?>) {
8616      return java.lang.reflect.Array.getLong(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
8617    } else {
8618      return Long.MAX_VALUE; // return default value
8619    }
8620  }
8621
8622  @Pure
8623  public static long getElement_long(long[] arr, long i) {
8624    if (arr == null) {
8625      return Long.MAX_VALUE; // return default value
8626    }
8627    return arr[(int)i];
8628  }
8629
8630  private static boolean eq(long x, long y) {
8631    return x == y;
8632  }
8633
8634  private static boolean ne(long x, long y) {
8635    return x != y;
8636  }
8637
8638  private static boolean lt(long x, long y) {
8639    return x < y;
8640  }
8641
8642  private static boolean lte(long x, long y) {
8643    return x <= y;
8644  }
8645
8646  private static boolean gt(long x, long y) {
8647    return x > y;
8648  }
8649
8650  private static boolean gte(long x, long y) {
8651    return x >= y;
8652  }
8653
8654  /** True iff both sequences are non-null and have the same length. */
8655  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
8656  @Pure
8657  public static boolean sameLength(long @Nullable [] seq1, long @Nullable [] seq2) {
8658    return ((seq1 != null)
8659            && (seq2 != null)
8660            && seq1.length == seq2.length);
8661  }
8662
8663  /** True iff both sequences are non-null and have the same length. */
8664  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
8665  @Pure
8666  public static boolean sameLength(long @Nullable [] seq1, int @Nullable [] seq2) {
8667    return ((seq1 != null)
8668            && (seq2 != null)
8669            && seq1.length == seq2.length);
8670  }
8671
8672  /** True iff both sequences have the same length, and all seq2[i] divide seq1[i].
8673   *
8674   * Meaning (in pseudo-FOL):
8675   *
8676   * <pre>
8677   * /\ seq1.length == seq2.length
8678   * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i]
8679   * </pre>
8680   *
8681   */
8682  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8683  @Pure
8684  public static boolean pairwiseDivides(long[] seq1, long[] seq2) {
8685    if (!sameLength(seq1, seq2)) {
8686      return false;
8687    }
8688    assert seq1 != null && seq2 != null; // because sameLength() = true
8689    for (int i = 0 ; i < seq1.length ; i++) {
8690      if (ne(seq1[i] % seq2[i], 0)) {
8691        return false;
8692      }
8693    }
8694    return true;
8695  }
8696  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8697  @Pure
8698  public static boolean pairwiseDivides(long[] seq1, int[] seq2) {
8699    if (!sameLength(seq1, seq2)) {
8700      return false;
8701    }
8702    assert seq1 != null && seq2 != null; // because sameLength() = true
8703    for (int i = 0 ; i < seq1.length ; i++) {
8704      if (ne(seq1[i] % seq2[i], 0)) {
8705        return false;
8706      }
8707    }
8708    return true;
8709  }
8710
8711  /**
8712   * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i].
8713   *
8714   * Meaning (in pseudo-FOL):
8715   *
8716   * <pre>
8717   * /\ seq1.length == seq2.length
8718   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i]
8719   * </pre>
8720   *
8721   */
8722  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8723  @Pure
8724  public static boolean pairwiseSquare(long[] seq1, long[] seq2) {
8725    if (!sameLength(seq1, seq2)) {
8726      return false;
8727    }
8728    assert seq1 != null && seq2 != null; // because sameLength() = true
8729    for (int i = 0 ; i < seq1.length ; i++) {
8730      if (ne(seq1[i], seq2[i] * seq2[i])) {
8731        return false;
8732      }
8733    }
8734    return true;
8735  }
8736  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8737  @Pure
8738  public static boolean pairwiseSquare(long[] seq1, int[] seq2) {
8739    if (!sameLength(seq1, seq2)) {
8740      return false;
8741    }
8742    assert seq1 != null && seq2 != null; // because sameLength() = true
8743    for (int i = 0 ; i < seq1.length ; i++) {
8744
8745      if (ne(seq1[i], ((long) seq2[i]) * ((long) seq2[i]))) {
8746
8747        return false;
8748      }
8749    }
8750    return true;
8751  }
8752
8753  /** True iff both sequences have the same length, and all seq1[i] == ~ seq2[i].
8754   *
8755   * Meaning (in pseudo-FOL):
8756   *
8757   * <pre>
8758   * /\ seq1.length == seq2.length
8759   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == ~ seq2[i]
8760   * </pre>
8761   *
8762   */
8763  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8764  @Pure
8765  public static boolean pairwiseBitwiseComplement(long[] seq1, long[] seq2) {
8766    if (!sameLength(seq1, seq2)) {
8767      return false;
8768    }
8769    assert seq1 != null && seq2 != null; // because sameLength() = true
8770    for (int i = 0 ; i < seq1.length ; i++) {
8771      if (seq1[i] != ~seq2[i]) {
8772        return false;
8773      }
8774    }
8775    return true;
8776  }
8777  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8778  @Pure
8779  public static boolean pairwiseBitwiseComplement(long[] seq1, int[] seq2) {
8780    if (!sameLength(seq1, seq2)) {
8781      return false;
8782    }
8783    assert seq1 != null && seq2 != null; // because sameLength() = true
8784    for (int i = 0 ; i < seq1.length ; i++) {
8785      if (seq1[i] != ~seq2[i]) {
8786        return false;
8787      }
8788    }
8789    return true;
8790  }
8791
8792  /** True iff both sequences have the same length, and all seq1[i] == (seq2[i] | seq1[i]).
8793   *
8794   * Meaning (in pseudo-FOL):
8795   *
8796   * <pre>
8797   * /\ seq1.length == seq2.length
8798   * /\ forall i in { 0..seq2.length-1 } : seq1[i] == (seq2[i] | seq1[i])
8799   * </pre>
8800   *
8801   */
8802  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8803  @Pure
8804  public static boolean pairwiseBitwiseSubset(long[] seq1, long[] seq2) {
8805    if (seq1 == null) {
8806      return false;
8807    }
8808    if (seq2 == null) {
8809      return false;
8810    }
8811    if (seq1.length != seq2.length) {
8812      return false;
8813    }
8814    for (int i = 0 ; i < seq1.length ; i++) {
8815      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
8816        return false;
8817      }
8818    }
8819    return true;
8820  }
8821  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8822  @Pure
8823  public static boolean pairwiseBitwiseSubset(long[] seq1, int[] seq2) {
8824    if (!sameLength(seq1, seq2)) {
8825      return false;
8826    }
8827    assert seq1 != null && seq2 != null; // because sameLength() = true
8828    for (int i = 0 ; i < seq1.length ; i++) {
8829      if (ne(seq1[i], (seq2[i] | seq1[i]))) {
8830        return false;
8831      }
8832    }
8833    return true;
8834  }
8835
8836  /**
8837   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
8838   *
8839   * <p>If either array is null, returns null. If either array is empty, returns only those
8840   * elements in the other array. If both arrays are empty, returns a new empty array.
8841   */
8842  @SideEffectFree
8843  public static long @PolyNull [] concat(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8844    if (seq1 == null) {
8845      return null;
8846    }
8847    if (seq2 == null) {
8848      return null;
8849    }
8850    return ArraysPlume.concat(seq1, seq2);
8851  }
8852
8853  @SideEffectFree
8854  public static long @PolyNull [] concat(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8855    if (seq1 == null) {
8856      return null;
8857    }
8858    if (seq2 == null) {
8859      return null;
8860    }
8861    // Cannot just use ArraysPlume.concat because the two arrays
8862    // have different types.  This essentially inlines that method.
8863    int newLength = seq1.length + seq2.length;
8864    long[] retval = new long[newLength];
8865
8866    System.arraycopy(seq1, 0, retval, 0, seq1.length);
8867    for (int j = 0 ; j < seq2.length ; j++) {
8868      retval[seq1.length + j] = seq2[j];
8869    }
8870
8871    return retval;
8872  }
8873
8874  /**
8875   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
8876   * assurances about the order or repetition of elements: elements may be repeated, and their
8877   * order may be different from the order of elements in seq1 and seq2.
8878   */
8879  @SideEffectFree
8880  public static long @PolyNull [] union(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8881    if (seq1 == null) {
8882      return null;
8883    }
8884    if (seq2 == null) {
8885      return null;
8886    }
8887    return concat(seq1, seq2);
8888  }
8889
8890  @Pure
8891  public static long @PolyNull [] union(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8892    if (seq1 == null) {
8893      return null;
8894    }
8895    if (seq2 == null) {
8896      return null;
8897    }
8898    return concat(seq1, seq2);
8899  }
8900
8901  /**
8902   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
8903   * gives no assurances about the order or repetition of elements: elements may be repeated, and
8904   * their order may be different from the order of elements in seq1 and seq2.
8905   */
8906  @Pure
8907  public static long @PolyNull [] intersection(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8908    if (seq1 == null) {
8909      return null;
8910    }
8911    if (seq2 == null) {
8912      return null;
8913    }
8914    long[] intermediate = new long[Math.min(seq1.length, seq2.length)];
8915    int length = 0;
8916    for (int i = 0 ; i < seq1.length ; i++) {
8917      if (memberOf(seq1[i], seq2) ) {
8918        intermediate[length++] = seq1[i];
8919      }
8920    }
8921    return ArraysPlume.subarray(intermediate, 0, length);
8922  }
8923
8924  @Pure
8925  public static long @PolyNull [] intersection(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8926    if (seq1 == null) {
8927      return null;
8928    }
8929    if (seq2 == null) {
8930      return null;
8931    }
8932    long[] intermediate = new long[Math.min(seq1.length, seq2.length)];
8933    int length = 0;
8934    for (int i = 0 ; i < seq1.length ; i++) {
8935      if (memberOf(seq1[i], seq2) ) {
8936        intermediate[length++] = seq1[i];
8937      }
8938    }
8939    return ArraysPlume.subarray(intermediate, 0, length);
8940  }
8941
8942  /**
8943   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
8944   * no assurances about the order or repetition of elements: elements may be repeated, and their
8945   * order may be different from the order of elements in seq1 and seq2.
8946   */
8947  @Pure
8948  public static long @PolyNull [] setDiff(long @PolyNull [] seq1, long @PolyNull [] seq2) {
8949    if (seq1 == null) {
8950      return null;
8951    }
8952    if (seq2 == null) {
8953      return null;
8954    }
8955    long[] intermediate = new long[seq1.length];
8956    int length = 0;
8957    for (int i = 0 ; i < seq1.length ; i++) {
8958      if (!memberOf(seq1[i], seq2)) {
8959        intermediate[length++] = seq1[i];
8960      }
8961    }
8962    return ArraysPlume.subarray(intermediate, 0, length);
8963  }
8964
8965  @Pure
8966  public static long @PolyNull [] setDiff(long @PolyNull [] seq1, int @PolyNull [] seq2) {
8967    if (seq1 == null) {
8968      return null;
8969    }
8970    if (seq2 == null) {
8971      return null;
8972    }
8973    long[] intermediate = new long[seq1.length];
8974    int length = 0;
8975    for (int i = 0 ; i < seq1.length ; i++) {
8976      if (!memberOf(seq1[i], seq2)) {
8977        intermediate[length++] = seq1[i];
8978      }
8979    }
8980    return ArraysPlume.subarray(intermediate, 0, length);
8981  }
8982
8983  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
8984  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
8985  @Pure
8986  public static boolean setEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
8987    if (seq1 == null) {
8988      return false;
8989    }
8990    if (seq2 == null) {
8991      return false;
8992    }
8993    for (int i = 0; i < seq1.length ; i++) {
8994      if (!memberOf(seq1[i], seq2) ) {
8995        return false;
8996      }
8997    }
8998    for (int i = 0; i < seq2.length ; i++) {
8999      if (!memberOf(seq2[i], seq1) ) {
9000        return false;
9001      }
9002    }
9003    return true;
9004  }
9005
9006  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9007  @Pure
9008  public static boolean setEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9009    if (seq1 == null) {
9010      return false;
9011    }
9012    if (seq2 == null) {
9013      return false;
9014    }
9015    for (int i = 0; i < seq1.length ; i++) {
9016      if (!memberOf(seq1[i], seq2) ) {
9017        return false;
9018      }
9019    }
9020    for (int i = 0; i < seq2.length ; i++) {
9021      if (!memberOf(seq2[i], seq1) ) {
9022        return false;
9023      }
9024    }
9025    return true;
9026  }
9027
9028  /** True iff seq1 is the reverse of seq2.
9029   *
9030   * Meaning (in pseudo-FOL):
9031   *
9032   * <pre>
9033   * /\ seq1.length == seq2.length
9034   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
9035   * </pre>
9036   *
9037   */
9038  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9039  @Pure
9040  public static boolean isReverse(long[] seq1, long[] seq2) {
9041    if (!sameLength(seq1, seq2)) {
9042      return false;
9043    }
9044    assert seq1 != null && seq2 != null; // because sameLength() = true
9045    int length = seq1.length;
9046    for (int i = 0 ; i < length ; i++) {
9047      if (ne(seq1[i], seq2[length - i - 1])) {
9048        return false;
9049      }
9050    }
9051    return true;
9052  }
9053
9054  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9055  @Pure
9056  public static boolean isReverse(long @Nullable [] seq1, int @Nullable [] seq2) {
9057    if (!sameLength(seq1, seq2)) {
9058      return false;
9059    }
9060    assert seq1 != null && seq2 != null; // because sameLength() = true
9061    int length = seq1.length;
9062    for (int i = 0 ; i < length ; i++) {
9063      if (ne(seq1[i], seq2[length - i - 1])) {
9064        return false;
9065      }
9066    }
9067    return true;
9068  }
9069
9070  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
9071  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9072  @Pure
9073  public static boolean subsetOf(long @Nullable [] seq1, long @Nullable [] seq2) {
9074    if (seq1 == null) {
9075      return false;
9076    }
9077    if (seq2 == null) {
9078      return false;
9079    }
9080    for (int i = 0 ; i < seq1.length ; i++) {
9081      if (!memberOf(seq1[i], seq2)) {
9082        return false;
9083      }
9084    }
9085    return true;
9086  }
9087
9088  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9089  @Pure
9090  public static boolean subsetOf(long @Nullable [] seq1, int @Nullable [] seq2) {
9091    if (seq1 == null) {
9092      return false;
9093    }
9094    if (seq2 == null) {
9095      return false;
9096    }
9097    for (int i = 0 ; i < seq1.length ; i++) {
9098      if (!memberOf(seq1[i], seq2)) {
9099        return false;
9100      }
9101    }
9102    return true;
9103  }
9104
9105  /** Returns true iff seq contains no duplicate elements. */
9106  @EnsuresNonNullIf(result=true, expression="#1")
9107  @Pure
9108  public static boolean noDups(long @Nullable [] seq) {
9109    if (seq == null) {
9110      return false;
9111    }
9112    return ArraysPlume.hasNoDuplicates(seq);
9113  }
9114
9115 /** Returns true iff elt is in array arr. */
9116  @EnsuresNonNullIf(result=true, expression="#2")
9117  @Pure
9118  public static boolean memberOf(long elt, long @Nullable [] arr) {
9119    if (arr == null) {
9120      return false;
9121    }
9122    for (int i = 0 ; i < arr.length ; i++) {
9123      if (eq(arr[i], elt)) {
9124        return true;
9125      }
9126    }
9127    return false;
9128  }
9129
9130  @EnsuresNonNullIf(result=true, expression="#2")
9131  @Pure
9132  public static boolean memberOf(long elt, int @Nullable [] arr) {
9133    if (arr == null) {
9134      return false;
9135    }
9136    for (int i = 0 ; i < arr.length ; i++) {
9137      if (eq(arr[i], elt)) {
9138        return true;
9139      }
9140    }
9141    return false;
9142  }
9143
9144  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
9145  @Pure
9146  public static long @PolyNull [] slice(long @PolyNull [] seq, int start, int end) {
9147    if (seq == null) {
9148      return null;
9149    }
9150    int sliceStart = start;
9151    int sliceEnd = end;
9152    if (start < 0) {
9153      return new long[] { };
9154    }
9155    if (end > seq.length - 1) {
9156      return new long[] { };
9157    }
9158    if (sliceStart > sliceEnd) {
9159      return new long[] { };
9160    }
9161    int length = sliceEnd - sliceStart + 1;
9162    return ArraysPlume.subarray(seq, sliceStart, length);
9163  }
9164
9165  @Pure
9166  public static long @PolyNull [] slice(long @PolyNull [] seq, long start, int end) {
9167    return slice(seq, (int)start, end);
9168  }
9169  @Pure
9170  public static long @PolyNull [] slice(long @PolyNull [] seq, int start, long end) {
9171    return slice(seq, start, (int)end);
9172  }
9173  @Pure
9174  public static long @PolyNull [] slice(long @PolyNull [] seq, long start, long end) {
9175    return slice(seq, (int)start, (int)end);
9176  }
9177
9178  /** True iff all elements in arr equal elt.
9179   *
9180   * Meaning (in pseudo-FOL):
9181   *
9182   * forall i in { 0..arr.length-1 } : arr[i] == elt
9183   *
9184   */
9185  @EnsuresNonNullIf(result=true, expression="#1")
9186  @Pure
9187  public static boolean eltsEqual(long @Nullable [] arr, long elt) {
9188    if (arr == null) {
9189      return false;
9190    }
9191    for (int i = 0 ; i < arr.length ; i++) {
9192      if (ne(arr[i], elt)) {
9193        return false;
9194      }
9195    }
9196    return true;
9197  }
9198
9199  @EnsuresNonNullIf(result=true, expression="#1")
9200  @Pure
9201  public static boolean eltsEqual(long @Nullable [] arr, int elt) {
9202    if (arr == null) {
9203      return false;
9204    }
9205    for (int i = 0 ; i < arr.length ; i++) {
9206      if (ne(arr[i], elt)) {
9207        return false;
9208      }
9209    }
9210    return true;
9211  }
9212
9213  /** True iff every element in arr does not equal elt.
9214   *
9215   * Meaning (in pseudo-FOL):
9216   *
9217   * forall i in { 0..arr.length-1 } : arr[i] != elt
9218   *
9219   */
9220  @EnsuresNonNullIf(result=true, expression="#1")
9221  @Pure
9222  public static boolean eltsNotEqual(long @Nullable [] arr, long elt) {
9223    if (arr == null) {
9224      return false;
9225    }
9226    for (int i = 0 ; i < arr.length ; i++) {
9227      if (eq(arr[i], elt)) {
9228        return false;
9229      }
9230    }
9231    return true;
9232  }
9233
9234  @EnsuresNonNullIf(result=true, expression="#1")
9235  @Pure
9236  public static boolean eltsNotEqual(long @Nullable [] arr, int elt) {
9237    if (arr == null) {
9238      return false;
9239    }
9240    for (int i = 0 ; i < arr.length ; i++) {
9241      if (eq(arr[i], elt)) {
9242        return false;
9243      }
9244    }
9245    return true;
9246  }
9247
9248  /** True iff every element in arr is greater than elt.
9249   *
9250   * Meaning (in pseudo-FOL):
9251   *
9252   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
9253   *
9254   */
9255  @EnsuresNonNullIf(result=true, expression="#1")
9256  @Pure
9257  public static boolean eltsGT(long @Nullable [] arr, long elt) {
9258    if (arr == null) {
9259      return false;
9260    }
9261    for (int i = 0 ; i < arr.length ; i++) {
9262      if (lte(arr[i], elt)) {
9263        return false;
9264      }
9265    }
9266    return true;
9267  }
9268
9269  @EnsuresNonNullIf(result=true, expression="#1")
9270  @Pure
9271  public static boolean eltsGT(long @Nullable [] arr, int elt) {
9272    if (arr == null) {
9273      return false;
9274    }
9275    for (int i = 0 ; i < arr.length ; i++) {
9276      if (lte(arr[i], elt)) {
9277        return false;
9278      }
9279    }
9280    return true;
9281  }
9282
9283  /** True iff every element in arr is greater than or equal to elt.
9284   *
9285   * Meaning (in pseudo-FOL):
9286   *
9287   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
9288   *
9289   */
9290  @EnsuresNonNullIf(result=true, expression="#1")
9291  @Pure
9292  public static boolean eltsGTE(long @Nullable [] arr, long elt) {
9293    if (arr == null) {
9294      return false;
9295    }
9296    for (int i = 0 ; i < arr.length ; i++) {
9297      if (lt(arr[i], elt)) {
9298        return false;
9299      }
9300    }
9301    return true;
9302  }
9303
9304  @EnsuresNonNullIf(result=true, expression="#1")
9305  @Pure
9306  public static boolean eltsGTE(long @Nullable [] arr, int elt) {
9307    if (arr == null) {
9308      return false;
9309    }
9310    for (int i = 0 ; i < arr.length ; i++) {
9311      if (lt(arr[i], elt)) {
9312        return false;
9313      }
9314    }
9315    return true;
9316  }
9317
9318  /** True iff every element in arr is less than elt.
9319   *
9320   * Meaning (in pseudo-FOL):
9321   *
9322   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
9323   *
9324   */
9325  @EnsuresNonNullIf(result=true, expression="#1")
9326  @Pure
9327  public static boolean eltsLT(long @Nullable [] arr, long elt) {
9328    if (arr == null) {
9329      return false;
9330    }
9331    for (int i = 0 ; i < arr.length ; i++) {
9332      if (gte(arr[i], elt)) {
9333        return false;
9334      }
9335    }
9336    return true;
9337  }
9338
9339  @EnsuresNonNullIf(result=true, expression="#1")
9340  @Pure
9341  public static boolean eltsLT(long @Nullable [] arr, int elt) {
9342    if (arr == null) {
9343      return false;
9344    }
9345    for (int i = 0 ; i < arr.length ; i++) {
9346      if (gte(arr[i], elt)) {
9347        return false;
9348      }
9349    }
9350    return true;
9351  }
9352
9353  /** True iff every element in arr is less than or equal to elt.
9354   *
9355   * Meaning (in pseudo-FOL):
9356   *
9357   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
9358   *
9359   */
9360  @EnsuresNonNullIf(result=true, expression="#1")
9361  @Pure
9362  public static boolean eltsLTE(long @Nullable [] arr, long elt) {
9363    if (arr == null) {
9364      return false;
9365    }
9366    for (int i = 0 ; i < arr.length ; i++) {
9367      if (gt(arr[i], elt)) {
9368        return false;
9369      }
9370    }
9371    return true;
9372  }
9373
9374  @EnsuresNonNullIf(result=true, expression="#1")
9375  @Pure
9376  public static boolean eltsLTE(long @Nullable [] arr, int elt) {
9377    if (arr == null) {
9378      return false;
9379    }
9380    for (int i = 0 ; i < arr.length ; i++) {
9381      if (gt(arr[i], elt)) {
9382        return false;
9383      }
9384    }
9385    return true;
9386  }
9387
9388  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
9389   *
9390   * Meaning (in pseudo-FOL):
9391   *
9392   * /\ seq1.length == se2.length
9393   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
9394   *
9395   */
9396
9397  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9398  @Pure
9399  public static boolean pairwiseEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9400    if (!sameLength(seq1, seq2)) {
9401      return false;
9402    }
9403    assert seq1 != null && seq2 != null; // because sameLength() = true
9404    for (int i = 0 ; i < seq1.length ; i++) {
9405      if (ne(seq1[i], seq2[i])) {
9406        return false;
9407      }
9408    }
9409    return true;
9410  }
9411
9412  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9413  @Pure
9414  public static boolean pairwiseEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9415    if (!sameLength(seq1, seq2)) {
9416      return false;
9417    }
9418    assert seq1 != null && seq2 != null; // because sameLength() = true
9419    for (int i = 0 ; i < seq1.length ; i++) {
9420      if (ne(seq1[i], seq2[i])) {
9421        return false;
9422      }
9423    }
9424    return true;
9425  }
9426
9427  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
9428   *
9429   * Meaning (in pseudo-FOL):
9430   *
9431   * /\ seq1.length == se2.length
9432   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
9433   *
9434   */
9435  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9436  @Pure
9437  public static boolean pairwiseNotEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9438    if (!sameLength(seq1, seq2)) {
9439      return false;
9440    }
9441    assert seq1 != null && seq2 != null; // because sameLength() = true
9442    for (int i = 0 ; i < seq1.length ; i++) {
9443      if (eq(seq1[i], seq2[i])) {
9444        return false;
9445      }
9446    }
9447    return true;
9448  }
9449
9450  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9451  @Pure
9452  public static boolean pairwiseNotEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9453    if (!sameLength(seq1, seq2)) {
9454      return false;
9455    }
9456    assert seq1 != null && seq2 != null; // because sameLength() = true
9457    for (int i = 0 ; i < seq1.length ; i++) {
9458      if (eq(seq1[i], seq2[i])) {
9459        return false;
9460      }
9461    }
9462    return true;
9463  }
9464
9465  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
9466   *
9467   * Meaning (in pseudo-FOL):
9468   *
9469   * /\ seq1.length == se2.length
9470   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
9471   *
9472   */
9473  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9474  @Pure
9475  public static boolean pairwiseLT(long @Nullable [] seq1, long @Nullable [] seq2) {
9476    if (!sameLength(seq1, seq2)) {
9477      return false;
9478    }
9479    assert seq1 != null && seq2 != null; // because sameLength() = true
9480    for (int i = 0 ; i < seq1.length ; i++) {
9481      if (gte(seq1[i], seq2[i])) {
9482        return false;
9483      }
9484    }
9485    return true;
9486  }
9487
9488  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9489  @Pure
9490  public static boolean pairwiseLT(long @Nullable [] seq1, int @Nullable [] seq2) {
9491    if (!sameLength(seq1, seq2)) {
9492      return false;
9493    }
9494    assert seq1 != null && seq2 != null; // because sameLength() = true
9495    for (int i = 0 ; i < seq1.length ; i++) {
9496      if (gte(seq1[i], seq2[i])) {
9497        return false;
9498      }
9499    }
9500    return true;
9501  }
9502
9503  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
9504   * Meaning (in pseudo-FOL):
9505   *
9506   * /\ seq1.length == se2.length
9507   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
9508   *
9509   */
9510  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9511  @Pure
9512  public static boolean pairwiseLTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9513    if (!sameLength(seq1, seq2)) {
9514      return false;
9515    }
9516    assert seq1 != null && seq2 != null; // because sameLength() = true
9517    for (int i = 0 ; i < seq1.length ; i++) {
9518      if (gt(seq1[i], seq2[i])) {
9519        return false;
9520      }
9521    }
9522    return true;
9523  }
9524
9525  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9526  @Pure
9527  public static boolean pairwiseLTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9528    if (!sameLength(seq1, seq2)) {
9529      return false;
9530    }
9531    assert seq1 != null && seq2 != null; // because sameLength() = true
9532    for (int i = 0 ; i < seq1.length ; i++) {
9533      if (gt(seq1[i], seq2[i])) {
9534        return false;
9535      }
9536    }
9537    return true;
9538  }
9539
9540  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
9541   * Meaning (in pseudo-FOL):
9542   *
9543   * /\ seq1.length == se2.length
9544   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
9545   *
9546   */
9547  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9548  @Pure
9549  public static boolean pairwiseGT(long @Nullable [] seq1, long @Nullable [] seq2) {
9550    if (!sameLength(seq1, seq2)) {
9551      return false;
9552    }
9553    assert seq1 != null && seq2 != null; // because sameLength() = true
9554    for (int i = 0 ; i < seq1.length ; i++) {
9555      if (lte(seq1[i], seq2[i])) {
9556        return false;
9557      }
9558    }
9559    return true;
9560  }
9561
9562  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9563  @Pure
9564  public static boolean pairwiseGT(long @Nullable [] seq1, int @Nullable [] seq2) {
9565    if (!sameLength(seq1, seq2)) {
9566      return false;
9567    }
9568    assert seq1 != null && seq2 != null; // because sameLength() = true
9569    for (int i = 0 ; i < seq1.length ; i++) {
9570      if (lte(seq1[i], seq2[i])) {
9571        return false;
9572      }
9573    }
9574    return true;
9575  }
9576
9577  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
9578   * Meaning (in pseudo-FOL):
9579   *
9580   * /\ seq1.length == se2.length
9581   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
9582   *
9583   */
9584  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9585  @Pure
9586  public static boolean pairwiseGTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9587    if (!sameLength(seq1, seq2)) {
9588      return false;
9589    }
9590    assert seq1 != null && seq2 != null; // because sameLength() = true
9591    for (int i = 0 ; i < seq1.length ; i++) {
9592      if (lt(seq1[i], seq2[i])) {
9593        return false;
9594      }
9595    }
9596    return true;
9597  }
9598
9599  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9600  @Pure
9601  public static boolean pairwiseGTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9602    if (!sameLength(seq1, seq2)) {
9603      return false;
9604    }
9605    assert seq1 != null && seq2 != null; // because sameLength() = true
9606    for (int i = 0 ; i < seq1.length ; i++) {
9607      if (lt(seq1[i], seq2[i])) {
9608        return false;
9609      }
9610    }
9611    return true;
9612  }
9613
9614  /**
9615   * Returns true iff seq1 is lexically equal to seq2.
9616   * For equality, "lexically" and "pairwise" are the same.
9617   */
9618  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9619  @Pure
9620  public static boolean lexEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9621    if (seq1 == null) {
9622      return false;
9623    }
9624    if (seq2 == null) {
9625      return false;
9626    }
9627    return pairwiseEqual(seq1, seq2);
9628  }
9629
9630  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9631  @Pure
9632  public static boolean lexEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9633    if (seq1 == null) {
9634      return false;
9635    }
9636    if (seq2 == null) {
9637      return false;
9638    }
9639    return pairwiseEqual(seq1, seq2);
9640  }
9641
9642  /** Returns true iff seq1 is lexically not equal to seq2. */
9643  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9644  @Pure
9645  public static boolean lexNotEqual(long @Nullable [] seq1, long @Nullable [] seq2) {
9646    if (seq1 == null) {
9647      return false;
9648    }
9649    if (seq2 == null) {
9650      return false;
9651    }
9652    return !lexEqual(seq1, seq2);
9653  }
9654
9655  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9656  @Pure
9657  public static boolean lexNotEqual(long @Nullable [] seq1, int @Nullable [] seq2) {
9658    if (seq1 == null) {
9659      return false;
9660    }
9661    if (seq2 == null) {
9662      return false;
9663    }
9664    return !lexEqual(seq1, seq2);
9665  }
9666
9667  /** Returns true iff seq1 is lexically &lt;  seq2. */
9668  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9669  @Pure
9670  public static boolean lexLT(long @Nullable [] seq1, long @Nullable [] seq2) {
9671    if (seq1 == null) {
9672      return false;
9673    }
9674    if (seq2 == null) {
9675      return false;
9676    }
9677    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9678    for (int i = 0 ; i < minlength ; i++) {
9679      if (gt(seq1[i], seq2[i])) {
9680        return false;
9681      } else if (lt(seq1[i], seq2[i])) {
9682        return true;
9683      }
9684    }
9685    if (seq1.length >= seq2.length) {
9686      return false;
9687    }
9688    return true;
9689  }
9690
9691  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9692  @Pure
9693  public static boolean lexLT(long @Nullable [] seq1, int @Nullable [] seq2) {
9694    if (seq1 == null) {
9695      return false;
9696    }
9697    if (seq2 == null) {
9698      return false;
9699    }
9700    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9701    for (int i = 0 ; i < minlength ; i++) {
9702      if (gt(seq1[i], seq2[i])) {
9703        return false;
9704        } else if (lt(seq1[i], seq2[i])) {
9705          return true;
9706        }
9707      }
9708      if (seq1.length >= seq2.length) {
9709        return false;
9710      }
9711      return true;
9712    }
9713
9714  /** Returns true iff seq1 is lexically &le; to seq2. */
9715  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9716  @Pure
9717  public static boolean lexLTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9718    if (seq1 == null) {
9719      return false;
9720    }
9721    if (seq2 == null) {
9722      return false;
9723    }
9724    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9725    for (int i = 0 ; i < minlength ; i++) {
9726      if (gt(seq1[i], seq2[i])) {
9727        return false;
9728      } else if (lt(seq1[i], seq2[i])) {
9729        return true;
9730      }
9731    }
9732    if (seq1.length > seq2.length) {
9733      return false;
9734    }
9735    return true;
9736  }
9737
9738  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9739  @Pure
9740  public static boolean lexLTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9741  if (seq1 == null) {
9742    return false;
9743  }
9744  if (seq2 == null) {
9745    return false;
9746  }
9747    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9748    for (int i = 0 ; i < minlength ; i++) {
9749      if (gt(seq1[i], seq2[i])) {
9750        return false;
9751      } else if (lt(seq1[i], seq2[i])) {
9752        return true;
9753      }
9754    }
9755    if (seq1.length > seq2.length) {
9756      return false;
9757    }
9758    return true;
9759  }
9760
9761  /** Returns true iff seq1 is lexically &gt; to seq2. */
9762  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9763  @Pure
9764  public static boolean lexGT(long @Nullable [] seq1, long @Nullable [] seq2) {
9765  if (seq1 == null) {
9766    return false;
9767  }
9768  if (seq2 == null) {
9769    return false;
9770  }
9771    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9772    for (int i = 0 ; i < minlength ; i++) {
9773      if (lt(seq1[i], seq2[i])) {
9774        return false;
9775      } else if (gt(seq1[i], seq2[i])) {
9776        return true;
9777      }
9778    }
9779    if (seq1.length <= seq2.length) {
9780      return false;
9781    }
9782    return true;
9783  }
9784
9785  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9786  @Pure
9787  public static boolean lexGT(long @Nullable [] seq1, int @Nullable [] seq2) {
9788  if (seq1 == null) {
9789    return false;
9790  }
9791  if (seq2 == null) {
9792    return false;
9793  }
9794    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9795    for (int i = 0 ; i < minlength ; i++) {
9796      if (lt(seq1[i], seq2[i])) {
9797        return false;
9798      } else if (gt(seq1[i], seq2[i])) {
9799        return true;
9800      }
9801    }
9802    if (seq1.length <= seq2.length) {
9803      return false;
9804    }
9805    return true;
9806  }
9807
9808  /** Returns true iff seq1 is lexically &ge; to seq2. */
9809  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9810  @Pure
9811  public static boolean lexGTE(long @Nullable [] seq1, long @Nullable [] seq2) {
9812  if (seq1 == null) {
9813    return false;
9814  }
9815  if (seq2 == null) {
9816    return false;
9817  }
9818    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9819    for (int i = 0 ; i < minlength ; i++) {
9820      if (lt(seq1[i], seq2[i])) {
9821        return false;
9822      } else if (gt(seq1[i], seq2[i])) {
9823        return true;
9824      }
9825    }
9826    if (seq1.length < seq2.length) {
9827      return false;
9828    }
9829    return true;
9830  }
9831
9832  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
9833  @Pure
9834  public static boolean lexGTE(long @Nullable [] seq1, int @Nullable [] seq2) {
9835  if (seq1 == null) {
9836    return false;
9837  }
9838  if (seq2 == null) {
9839    return false;
9840  }
9841    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
9842    for (int i = 0 ; i < minlength ; i++) {
9843      if (lt(seq1[i], seq2[i])) {
9844        return false;
9845      } else if (gt(seq1[i], seq2[i])) {
9846        return true;
9847      }
9848    }
9849    if (seq1.length < seq2.length) {
9850      return false;
9851    }
9852    return true;
9853  }
9854
9855  /** True iff for all applicable i, every seq[i] == seq[i+1].
9856   *
9857   * Meaning (in pseudo-FOL):
9858   *
9859   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
9860   *
9861   */
9862  @EnsuresNonNullIf(result=true, expression="#1")
9863  @Pure
9864  public static boolean eltwiseEqual(long @Nullable [] seq) {
9865  if (seq == null) {
9866    return false;
9867  }
9868    for (int i = 0 ; i < seq.length ; i++) {
9869      if (i < seq.length - 1) {
9870        if (ne(seq[i], seq[i + 1])) {
9871          return false;
9872        }
9873      }
9874    }
9875    return true;
9876  }
9877
9878  /** True iff for all applicable i, every seq[i] != seq[i+1].
9879   *
9880   * Meaning (in pseudo-FOL):
9881   *
9882   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
9883   *
9884   */
9885  @EnsuresNonNullIf(result=true, expression="#1")
9886  @Pure
9887  public static boolean eltwiseNotEqual(long @Nullable [] seq) {
9888  if (seq == null) {
9889    return false;
9890  }
9891    for (int i = 0 ; i < seq.length ; i++) {
9892      if (i < seq.length - 1) {
9893        if (eq(seq[i], seq[i + 1])) {
9894          return false;
9895        }
9896      }
9897    }
9898    return true;
9899  }
9900
9901  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
9902   *
9903   * Meaning (in pseudo-FOL):
9904   *
9905   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
9906   *
9907   */
9908  @EnsuresNonNullIf(result=true, expression="#1")
9909  @Pure
9910  public static boolean eltwiseLT(long @Nullable [] seq) {
9911  if (seq == null) {
9912    return false;
9913  }
9914    for (int i = 0 ; i < seq.length ; i++) {
9915      if (i < seq.length - 1) {
9916        if (gte(seq[i], seq[i + 1])) {
9917          return false;
9918        }
9919      }
9920    }
9921    return true;
9922  }
9923
9924  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
9925   *
9926   * Meaning (in pseudo-FOL):
9927   *
9928   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
9929   *
9930   */
9931  @EnsuresNonNullIf(result=true, expression="#1")
9932  @Pure
9933  public static boolean eltwiseLTE(long @Nullable [] seq) {
9934  if (seq == null) {
9935    return false;
9936  }
9937    for (int i = 0 ; i < seq.length ; i++) {
9938      if (i < seq.length - 1) {
9939        if (gt(seq[i], seq[i + 1])) {
9940          return false;
9941        }
9942      }
9943    }
9944    return true;
9945  }
9946
9947  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
9948   *
9949   * Meaning (in pseudo-FOL):
9950   *
9951   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
9952   *
9953   */
9954  @EnsuresNonNullIf(result=true, expression="#1")
9955  @Pure
9956  public static boolean eltwiseGT(long @Nullable [] seq) {
9957  if (seq == null) {
9958    return false;
9959  }
9960    for (int i = 0 ; i < seq.length ; i++) {
9961      if (i < seq.length - 1) {
9962        if (lte(seq[i], seq[i + 1])) {
9963          return false;
9964        }
9965      }
9966    }
9967    return true;
9968  }
9969
9970  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
9971   *
9972   * Meaning (in pseudo-FOL):
9973   *
9974   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
9975   *
9976   */
9977  @EnsuresNonNullIf(result=true, expression="#1")
9978  @Pure
9979  public static boolean eltwiseGTE(long @Nullable [] seq) {
9980  if (seq == null) {
9981    return false;
9982  }
9983    for (int i = 0 ; i < seq.length ; i++) {
9984      if (i < seq.length - 1) {
9985        if (lt(seq[i], seq[i + 1])) {
9986          return false;
9987        }
9988      }
9989    }
9990    return true;
9991  }
9992
9993  /** True iff for all applicable i, every seq[i] == i.
9994   *
9995   * Meaning (in pseudo-FOL):
9996   *
9997   * forall i in { 0..seq.length-1 } : seq[i] == i
9998   *
9999   */
10000  @EnsuresNonNullIf(result=true, expression="#1")
10001  @Pure
10002  public static boolean eltsEqualIndex(long @Nullable [] seq) {
10003  if (seq == null) {
10004    return false;
10005  }
10006    for (int i = 0 ; i < seq.length ; i++) {
10007      if (ne(seq[i], i)) {
10008        return false;
10009      }
10010    }
10011    return true;
10012  }
10013
10014  /** True iff for all applicable i, every seq[i] != i.
10015   *
10016   * Meaning (in pseudo-FOL):
10017   *
10018   * forall i in { 0..seq.length-1 } : seq[i] != i
10019   *
10020   */
10021  @EnsuresNonNullIf(result=true, expression="#1")
10022  @Pure
10023  public static boolean eltsNotEqualIndex(long @Nullable [] seq) {
10024  if (seq == null) {
10025    return false;
10026  }
10027    for (int i = 0 ; i < seq.length ; i++) {
10028      if (eq(seq[i], i)) {
10029        return false;
10030      }
10031    }
10032    return true;
10033  }
10034
10035  /** True iff for all applicable i, every seq[i] &lt; i.
10036   *
10037   * Meaning (in pseudo-FOL):
10038   *
10039   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
10040   *
10041   */
10042  @EnsuresNonNullIf(result=true, expression="#1")
10043  @Pure
10044  public static boolean eltsLtIndex(long @Nullable [] seq) {
10045  if (seq == null) {
10046    return false;
10047  }
10048    for (int i = 0 ; i < seq.length ; i++) {
10049      if (gte(seq[i], i)) {
10050        return false;
10051      }
10052    }
10053    return true;
10054  }
10055
10056  /** True iff for all applicable i, every seq[i] &le; i.
10057   *
10058   * Meaning (in pseudo-FOL):
10059   *
10060   * forall i in { 0..seq.length-1 } : seq[i] &le; i
10061   *
10062   */
10063  @EnsuresNonNullIf(result=true, expression="#1")
10064  @Pure
10065  public static boolean eltsLteIndex(long @Nullable [] seq) {
10066  if (seq == null) {
10067    return false;
10068  }
10069    for (int i = 0 ; i < seq.length ; i++) {
10070      if (gt(seq[i], i)) {
10071        return false;
10072      }
10073    }
10074    return true;
10075  }
10076
10077  /** True iff for all applicable i, every seq[i] &gt; i.
10078   *
10079   * Meaning (in pseudo-FOL):
10080   *
10081   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
10082   *
10083   */
10084  @EnsuresNonNullIf(result=true, expression="#1")
10085  @Pure
10086  public static boolean eltsGtIndex(long @Nullable [] seq) {
10087  if (seq == null) {
10088    return false;
10089  }
10090    for (int i = 0 ; i < seq.length ; i++) {
10091      if (lte(seq[i], i)) {
10092        return false;
10093      }
10094    }
10095    return true;
10096  }
10097
10098  /** True iff for all applicable i, every seq[i] &ge; i.
10099   *
10100   * Meaning (in pseudo-FOL):
10101   *
10102   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
10103   *
10104   */
10105  @EnsuresNonNullIf(result=true, expression="#1")
10106  @Pure
10107  public static boolean eltsGteIndex(long @Nullable [] seq) {
10108  if (seq == null) {
10109    return false;
10110  }
10111    for (int i = 0 ; i < seq.length ; i++) {
10112      if (lt(seq[i], i)) {
10113        return false;
10114      }
10115    }
10116    return true;
10117  }
10118
10119  // Deferencing (accessing) fields
10120
10121  /**
10122   * collectlong accepts an object and a list of fields (one of which is of array type, and the
10123   * rest of which are not), and produces an array in which the original object has had the given
10124   * fields accessed.
10125   *
10126   * <p>Daikon creates invariants over "variables" such as the following.
10127   *
10128   * <dl>
10129   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
10130   *              for all y's in array x.arr.</dd>
10131   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
10132   *              for all x's in array arr.</dd>
10133   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
10134   * </dl>
10135   *
10136   * <p>The collectlong() method does this collecting work.
10137   *
10138   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
10139   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
10140   * elements that result from following the fields, one of which is assumed to be an array.
10141   *
10142   * <p>
10143   * requires: fieldStr.length() &gt; 0 and object != null
10144   * <p>
10145   * requires: fieldStr contains only field names, no "[]" strings.
10146   * <p>
10147   * requires: the method only works for field sequences with exactly one field representing an
10148   * array. For example, the collection a[].b[].c will fail.
10149   *
10150   * @return if the resulting collection is of non-primitive type, then returns an array of type
10151   * Object[]. Returns null if any array or field access causes an exception.
10152   */
10153
10154  @SideEffectFree
10155  public static long @Nullable [] collectlong(@Nullable Object object, @Nullable String fieldStr) {
10156
10157    if (object == null) {
10158      return null;
10159    }
10160    if (fieldStr == null) {
10161      return null;
10162    }
10163
10164    // assert fieldStr != null && !"".equals(fieldStr);
10165    String[] fieldNames = fieldStr.split("\\.");
10166    long[] retval = collectlong(object, fieldNames, 0);
10167    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
10168    return retval;
10169  }
10170
10171  // @PolyNull does not work for return type, because null is returned on error.
10172  /** Helper method for collectlong(Object, String).
10173   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
10174   * @see collectlong(Object, String)
10175   */
10176
10177  @SideEffectFree
10178  private static long @Nullable [] collectlong(@Nullable Object object,
10179                                                   String[] fields, int fieldsStartIdx) {
10180
10181    if (object == null) {
10182      return null;
10183    }
10184    assert (fields != null);
10185    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
10186
10187    Object fieldObj;
10188    try {
10189      Field field = (object instanceof java.lang.Class<?>)
10190        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
10191        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
10192      field.setAccessible(true);
10193      // Class cls = field.getType();
10194      fieldObj = field.get(object);
10195      // System.out.println("***fieldObj="+fieldObj);
10196
10197    } catch (Exception e) {
10198      return null;
10199
10200    }
10201
10202    if (fieldObj == null) {
10203      return null;
10204    }
10205
10206    // base case: just accessed the last field
10207    if (fields.length - 1 == fieldsStartIdx) {
10208
10209      if (fieldObj.getClass().isArray()) {
10210        // last field is an array
10211        return (long[])fieldObj;
10212      } else {
10213        // This hack should be removed in favor of, at "oneEltArray = ..."
10214        // below, calling a version of collectlong_field that throws an
10215        // error.  Then, this case becomes a run-time error.  -MDE
10216
10217        // Just one element; return a one-element array.
10218        // assert cls.equals(Long.TYPE);
10219        return new long[] { ((Long)fieldObj).longValue() };
10220      }
10221    } else {
10222      // recursive case: more fields to access after this one
10223
10224      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
10225
10226        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
10227        long[] intermediate = new long[collection.size()];
10228        int index = 0;
10229        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
10230          Object obj = i.next();
10231          long[] oneEltArray = collectlong(obj, fields, fieldsStartIdx + 1);
10232          if (oneEltArray == null) {
10233            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
10234          }
10235          // assert oneEltArray.length == 1;
10236          intermediate[index++] = oneEltArray[0];
10237        }
10238        return intermediate;
10239      } else if (fieldObj.getClass().isArray()) {
10240
10241        // collect elements across array
10242        long[] intermediate = new long[Array.getLength(fieldObj)];
10243        for (int i = 0 ; i < intermediate.length ; i++) {
10244          Object obj = Array.get(fieldObj, i);
10245          long[] oneEltArray = collectlong(obj, fields, fieldsStartIdx + 1);
10246          if (oneEltArray == null) {
10247            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
10248          }
10249          // assert oneEltArray.length == 1;
10250          intermediate[i] = oneEltArray[0];
10251        }
10252        return intermediate;
10253      } else {
10254
10255        return collectlong(fieldObj, fields, fieldsStartIdx + 1);
10256      }
10257    }
10258  }
10259
10260  /**
10261   * Returns the results of dereferencing the fields for 'object'. For example, the call
10262   *
10263   * <pre>collectlong_field(x, "f.g.h")</pre>
10264   *
10265   * has the same value as
10266   *
10267   * <pre>x.f.g.h</pre>.
10268   * Returns a default value if any field access causes an exception.
10269   */
10270  @SideEffectFree
10271  public static long collectlong_field(Object object, String fieldStr) {
10272
10273    if (object == null) {
10274      return Long.MAX_VALUE; // return default value
10275    }
10276    if (fieldStr == null) {
10277      return Long.MAX_VALUE; // return default value
10278    }
10279
10280    String[] fieldNames = fieldStr.split("\\.");
10281
10282    // Holds the intermediate (and final) result
10283    Object fieldObj = object;
10284
10285    for (int i = 0 ; i < fieldNames.length ; i++) {
10286
10287      String fieldName = fieldNames[i];
10288
10289      try {
10290        Field field =
10291          (fieldObj instanceof java.lang.Class<?>)
10292          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
10293          : fieldObj.getClass().getDeclaredField(fieldName);
10294        field.setAccessible(true);
10295        fieldObj = field.get(fieldObj);
10296
10297        if (fieldObj == null) {
10298          return Long.MAX_VALUE; // return default value
10299        }
10300
10301      } catch (Exception e) {
10302        return Long.MAX_VALUE; // return default value
10303
10304      }
10305
10306    }
10307
10308    return ((Long)fieldObj).longValue();
10309  }
10310
10311  // ///////////////////////////////////////////////////////////////////////////
10312  // Methods for "short" (from QuantBody.java.jpp)
10313  //
10314
10315  /**
10316   * Returns the ith element of the array or collection argument. If the argument is null or not an
10317   * array or collection, returns a default value (Short.MAX_VALUE).
10318   */
10319
10320  @Pure
10321  public static short getElement_short(Object o, long i) {
10322    if (o == null) {
10323      return Short.MAX_VALUE; // return default value
10324    }
10325    java.lang.Class<?> c = o.getClass();
10326    if (c.isArray()) {
10327      return java.lang.reflect.Array.getShort(o, (int)i);
10328    } else if (o instanceof java.util.AbstractCollection<?>) {
10329      return java.lang.reflect.Array.getShort(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
10330    } else {
10331      return Short.MAX_VALUE; // return default value
10332    }
10333  }
10334
10335  @Pure
10336  public static short getElement_short(short[] arr, long i) {
10337    if (arr == null) {
10338      return Short.MAX_VALUE; // return default value
10339    }
10340    return arr[(int)i];
10341  }
10342
10343  private static boolean eq(short x, short y) {
10344    return x == y;
10345  }
10346
10347  private static boolean ne(short x, short y) {
10348    return x != y;
10349  }
10350
10351  private static boolean lt(short x, short y) {
10352    return x < y;
10353  }
10354
10355  private static boolean lte(short x, short y) {
10356    return x <= y;
10357  }
10358
10359  private static boolean gt(short x, short y) {
10360    return x > y;
10361  }
10362
10363  private static boolean gte(short x, short y) {
10364    return x >= y;
10365  }
10366
10367  /** True iff both sequences are non-null and have the same length. */
10368  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
10369  @Pure
10370  public static boolean sameLength(short @Nullable [] seq1, short @Nullable [] seq2) {
10371    return ((seq1 != null)
10372            && (seq2 != null)
10373            && seq1.length == seq2.length);
10374  }
10375
10376  /**
10377   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
10378   *
10379   * <p>If either array is null, returns null. If either array is empty, returns only those
10380   * elements in the other array. If both arrays are empty, returns a new empty array.
10381   */
10382  @SideEffectFree
10383  public static short @PolyNull [] concat(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10384    if (seq1 == null) {
10385      return null;
10386    }
10387    if (seq2 == null) {
10388      return null;
10389    }
10390    return ArraysPlume.concat(seq1, seq2);
10391  }
10392
10393  /**
10394   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
10395   * assurances about the order or repetition of elements: elements may be repeated, and their
10396   * order may be different from the order of elements in seq1 and seq2.
10397   */
10398  @SideEffectFree
10399  public static short @PolyNull [] union(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10400    if (seq1 == null) {
10401      return null;
10402    }
10403    if (seq2 == null) {
10404      return null;
10405    }
10406    return concat(seq1, seq2);
10407  }
10408
10409  /**
10410   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
10411   * gives no assurances about the order or repetition of elements: elements may be repeated, and
10412   * their order may be different from the order of elements in seq1 and seq2.
10413   */
10414  @Pure
10415  public static short @PolyNull [] intersection(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10416    if (seq1 == null) {
10417      return null;
10418    }
10419    if (seq2 == null) {
10420      return null;
10421    }
10422    short[] intermediate = new short[Math.min(seq1.length, seq2.length)];
10423    int length = 0;
10424    for (int i = 0 ; i < seq1.length ; i++) {
10425      if (memberOf(seq1[i], seq2) ) {
10426        intermediate[length++] = seq1[i];
10427      }
10428    }
10429    return ArraysPlume.subarray(intermediate, 0, length);
10430  }
10431
10432  /**
10433   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
10434   * no assurances about the order or repetition of elements: elements may be repeated, and their
10435   * order may be different from the order of elements in seq1 and seq2.
10436   */
10437  @Pure
10438  public static short @PolyNull [] setDiff(short @PolyNull [] seq1, short @PolyNull [] seq2) {
10439    if (seq1 == null) {
10440      return null;
10441    }
10442    if (seq2 == null) {
10443      return null;
10444    }
10445    short[] intermediate = new short[seq1.length];
10446    int length = 0;
10447    for (int i = 0 ; i < seq1.length ; i++) {
10448      if (!memberOf(seq1[i], seq2)) {
10449        intermediate[length++] = seq1[i];
10450      }
10451    }
10452    return ArraysPlume.subarray(intermediate, 0, length);
10453  }
10454
10455  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
10456  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10457  @Pure
10458  public static boolean setEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10459    if (seq1 == null) {
10460      return false;
10461    }
10462    if (seq2 == null) {
10463      return false;
10464    }
10465    for (int i = 0; i < seq1.length ; i++) {
10466      if (!memberOf(seq1[i], seq2) ) {
10467        return false;
10468      }
10469    }
10470    for (int i = 0; i < seq2.length ; i++) {
10471      if (!memberOf(seq2[i], seq1) ) {
10472        return false;
10473      }
10474    }
10475    return true;
10476  }
10477
10478  /** True iff seq1 is the reverse of seq2.
10479   *
10480   * Meaning (in pseudo-FOL):
10481   *
10482   * <pre>
10483   * /\ seq1.length == seq2.length
10484   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
10485   * </pre>
10486   *
10487   */
10488  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10489  @Pure
10490  public static boolean isReverse(short[] seq1, short[] seq2) {
10491    if (!sameLength(seq1, seq2)) {
10492      return false;
10493    }
10494    assert seq1 != null && seq2 != null; // because sameLength() = true
10495    int length = seq1.length;
10496    for (int i = 0 ; i < length ; i++) {
10497      if (ne(seq1[i], seq2[length - i - 1])) {
10498        return false;
10499      }
10500    }
10501    return true;
10502  }
10503
10504  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
10505  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10506  @Pure
10507  public static boolean subsetOf(short @Nullable [] seq1, short @Nullable [] seq2) {
10508    if (seq1 == null) {
10509      return false;
10510    }
10511    if (seq2 == null) {
10512      return false;
10513    }
10514    for (int i = 0 ; i < seq1.length ; i++) {
10515      if (!memberOf(seq1[i], seq2)) {
10516        return false;
10517      }
10518    }
10519    return true;
10520  }
10521
10522  /** Returns true iff seq contains no duplicate elements. */
10523  @EnsuresNonNullIf(result=true, expression="#1")
10524  @Pure
10525  public static boolean noDups(short @Nullable [] seq) {
10526    if (seq == null) {
10527      return false;
10528    }
10529    return ArraysPlume.hasNoDuplicates(seq);
10530  }
10531
10532 /** Returns true iff elt is in array arr. */
10533  @EnsuresNonNullIf(result=true, expression="#2")
10534  @Pure
10535  public static boolean memberOf(short elt, short @Nullable [] arr) {
10536    if (arr == null) {
10537      return false;
10538    }
10539    for (int i = 0 ; i < arr.length ; i++) {
10540      if (eq(arr[i], elt)) {
10541        return true;
10542      }
10543    }
10544    return false;
10545  }
10546
10547  @EnsuresNonNullIf(result=true, expression="#2")
10548  @Pure
10549  public static boolean memberOf(long elt, short @Nullable [] arr) {
10550    if (arr == null) {
10551      return false;
10552    }
10553    for (int i = 0 ; i < arr.length ; i++) {
10554      if (eq(arr[i], elt)) {
10555        return true;
10556      }
10557    }
10558    return false;
10559  }
10560
10561  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
10562  @Pure
10563  public static short @PolyNull [] slice(short @PolyNull [] seq, int start, int end) {
10564    if (seq == null) {
10565      return null;
10566    }
10567    int sliceStart = start;
10568    int sliceEnd = end;
10569    if (start < 0) {
10570      return new short[] { };
10571    }
10572    if (end > seq.length - 1) {
10573      return new short[] { };
10574    }
10575    if (sliceStart > sliceEnd) {
10576      return new short[] { };
10577    }
10578    int length = sliceEnd - sliceStart + 1;
10579    return ArraysPlume.subarray(seq, sliceStart, length);
10580  }
10581
10582  @Pure
10583  public static short @PolyNull [] slice(short @PolyNull [] seq, long start, int end) {
10584    return slice(seq, (int)start, end);
10585  }
10586  @Pure
10587  public static short @PolyNull [] slice(short @PolyNull [] seq, int start, long end) {
10588    return slice(seq, start, (int)end);
10589  }
10590  @Pure
10591  public static short @PolyNull [] slice(short @PolyNull [] seq, long start, long end) {
10592    return slice(seq, (int)start, (int)end);
10593  }
10594
10595  /** True iff all elements in arr equal elt.
10596   *
10597   * Meaning (in pseudo-FOL):
10598   *
10599   * forall i in { 0..arr.length-1 } : arr[i] == elt
10600   *
10601   */
10602  @EnsuresNonNullIf(result=true, expression="#1")
10603  @Pure
10604  public static boolean eltsEqual(short @Nullable [] arr, short elt) {
10605    if (arr == null) {
10606      return false;
10607    }
10608    for (int i = 0 ; i < arr.length ; i++) {
10609      if (ne(arr[i], elt)) {
10610        return false;
10611      }
10612    }
10613    return true;
10614  }
10615
10616  /** True iff every element in arr does not equal elt.
10617   *
10618   * Meaning (in pseudo-FOL):
10619   *
10620   * forall i in { 0..arr.length-1 } : arr[i] != elt
10621   *
10622   */
10623  @EnsuresNonNullIf(result=true, expression="#1")
10624  @Pure
10625  public static boolean eltsNotEqual(short @Nullable [] arr, short elt) {
10626    if (arr == null) {
10627      return false;
10628    }
10629    for (int i = 0 ; i < arr.length ; i++) {
10630      if (eq(arr[i], elt)) {
10631        return false;
10632      }
10633    }
10634    return true;
10635  }
10636
10637  /** True iff every element in arr is greater than elt.
10638   *
10639   * Meaning (in pseudo-FOL):
10640   *
10641   * forall i in { 0..arr.length-1 } : arr[i] &gt; elt
10642   *
10643   */
10644  @EnsuresNonNullIf(result=true, expression="#1")
10645  @Pure
10646  public static boolean eltsGT(short @Nullable [] arr, short elt) {
10647    if (arr == null) {
10648      return false;
10649    }
10650    for (int i = 0 ; i < arr.length ; i++) {
10651      if (lte(arr[i], elt)) {
10652        return false;
10653      }
10654    }
10655    return true;
10656  }
10657
10658  /** True iff every element in arr is greater than or equal to elt.
10659   *
10660   * Meaning (in pseudo-FOL):
10661   *
10662   * forall i in { 0..arr.length-1 } : arr[i] &ge; elt
10663   *
10664   */
10665  @EnsuresNonNullIf(result=true, expression="#1")
10666  @Pure
10667  public static boolean eltsGTE(short @Nullable [] arr, short elt) {
10668    if (arr == null) {
10669      return false;
10670    }
10671    for (int i = 0 ; i < arr.length ; i++) {
10672      if (lt(arr[i], elt)) {
10673        return false;
10674      }
10675    }
10676    return true;
10677  }
10678
10679  /** True iff every element in arr is less than elt.
10680   *
10681   * Meaning (in pseudo-FOL):
10682   *
10683   * forall i in { 0..arr.length-1 } : arr[i] &lt; elt
10684   *
10685   */
10686  @EnsuresNonNullIf(result=true, expression="#1")
10687  @Pure
10688  public static boolean eltsLT(short @Nullable [] arr, short elt) {
10689    if (arr == null) {
10690      return false;
10691    }
10692    for (int i = 0 ; i < arr.length ; i++) {
10693      if (gte(arr[i], elt)) {
10694        return false;
10695      }
10696    }
10697    return true;
10698  }
10699
10700  /** True iff every element in arr is less than or equal to elt.
10701   *
10702   * Meaning (in pseudo-FOL):
10703   *
10704   * forall i in { 0..arr.length-1 } : arr[i] &le; elt
10705   *
10706   */
10707  @EnsuresNonNullIf(result=true, expression="#1")
10708  @Pure
10709  public static boolean eltsLTE(short @Nullable [] arr, short elt) {
10710    if (arr == null) {
10711      return false;
10712    }
10713    for (int i = 0 ; i < arr.length ; i++) {
10714      if (gt(arr[i], elt)) {
10715        return false;
10716      }
10717    }
10718    return true;
10719  }
10720
10721  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
10722   *
10723   * Meaning (in pseudo-FOL):
10724   *
10725   * /\ seq1.length == se2.length
10726   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
10727   *
10728   */
10729
10730  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10731  @Pure
10732  public static boolean pairwiseEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10733    if (!sameLength(seq1, seq2)) {
10734      return false;
10735    }
10736    assert seq1 != null && seq2 != null; // because sameLength() = true
10737    for (int i = 0 ; i < seq1.length ; i++) {
10738      if (ne(seq1[i], seq2[i])) {
10739        return false;
10740      }
10741    }
10742    return true;
10743  }
10744
10745  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
10746   *
10747   * Meaning (in pseudo-FOL):
10748   *
10749   * /\ seq1.length == se2.length
10750   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
10751   *
10752   */
10753  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10754  @Pure
10755  public static boolean pairwiseNotEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10756    if (!sameLength(seq1, seq2)) {
10757      return false;
10758    }
10759    assert seq1 != null && seq2 != null; // because sameLength() = true
10760    for (int i = 0 ; i < seq1.length ; i++) {
10761      if (eq(seq1[i], seq2[i])) {
10762        return false;
10763      }
10764    }
10765    return true;
10766  }
10767
10768  /** True iff seq1 and seq2 have the same length, and every seq1[i] &lt; seq2[i].
10769   *
10770   * Meaning (in pseudo-FOL):
10771   *
10772   * /\ seq1.length == se2.length
10773   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &lt; seq2[i]
10774   *
10775   */
10776  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10777  @Pure
10778  public static boolean pairwiseLT(short @Nullable [] seq1, short @Nullable [] seq2) {
10779    if (!sameLength(seq1, seq2)) {
10780      return false;
10781    }
10782    assert seq1 != null && seq2 != null; // because sameLength() = true
10783    for (int i = 0 ; i < seq1.length ; i++) {
10784      if (gte(seq1[i], seq2[i])) {
10785        return false;
10786      }
10787    }
10788    return true;
10789  }
10790
10791  /** True iff seq1 and seq2 have the same length, and every seq1[i] &le; seq2[i].
10792   * Meaning (in pseudo-FOL):
10793   *
10794   * /\ seq1.length == se2.length
10795   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &le; seq2[i]
10796   *
10797   */
10798  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10799  @Pure
10800  public static boolean pairwiseLTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10801    if (!sameLength(seq1, seq2)) {
10802      return false;
10803    }
10804    assert seq1 != null && seq2 != null; // because sameLength() = true
10805    for (int i = 0 ; i < seq1.length ; i++) {
10806      if (gt(seq1[i], seq2[i])) {
10807        return false;
10808      }
10809    }
10810    return true;
10811  }
10812
10813  /** True iff seq1 and seq2 have the same length, and every seq1[i] &gt; seq2[i].
10814   * Meaning (in pseudo-FOL):
10815   *
10816   * /\ seq1.length == se2.length
10817   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &gt; seq2[i]
10818   *
10819   */
10820  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10821  @Pure
10822  public static boolean pairwiseGT(short @Nullable [] seq1, short @Nullable [] seq2) {
10823    if (!sameLength(seq1, seq2)) {
10824      return false;
10825    }
10826    assert seq1 != null && seq2 != null; // because sameLength() = true
10827    for (int i = 0 ; i < seq1.length ; i++) {
10828      if (lte(seq1[i], seq2[i])) {
10829        return false;
10830      }
10831    }
10832    return true;
10833  }
10834
10835  /** True iff seq1 and seq2 have the same length, and every seq1[i] &ge; seq2[i].
10836   * Meaning (in pseudo-FOL):
10837   *
10838   * /\ seq1.length == se2.length
10839   * /\ forall i in { 0..seq1.length-1 } : seq1[i] &ge; seq2[i]
10840   *
10841   */
10842  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10843  @Pure
10844  public static boolean pairwiseGTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10845    if (!sameLength(seq1, seq2)) {
10846      return false;
10847    }
10848    assert seq1 != null && seq2 != null; // because sameLength() = true
10849    for (int i = 0 ; i < seq1.length ; i++) {
10850      if (lt(seq1[i], seq2[i])) {
10851        return false;
10852      }
10853    }
10854    return true;
10855  }
10856
10857  /**
10858   * Returns true iff seq1 is lexically equal to seq2.
10859   * For equality, "lexically" and "pairwise" are the same.
10860   */
10861  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10862  @Pure
10863  public static boolean lexEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10864    if (seq1 == null) {
10865      return false;
10866    }
10867    if (seq2 == null) {
10868      return false;
10869    }
10870    return pairwiseEqual(seq1, seq2);
10871  }
10872
10873  /** Returns true iff seq1 is lexically not equal to seq2. */
10874  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10875  @Pure
10876  public static boolean lexNotEqual(short @Nullable [] seq1, short @Nullable [] seq2) {
10877    if (seq1 == null) {
10878      return false;
10879    }
10880    if (seq2 == null) {
10881      return false;
10882    }
10883    return !lexEqual(seq1, seq2);
10884  }
10885
10886  /** Returns true iff seq1 is lexically &lt;  seq2. */
10887  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10888  @Pure
10889  public static boolean lexLT(short @Nullable [] seq1, short @Nullable [] seq2) {
10890    if (seq1 == null) {
10891      return false;
10892    }
10893    if (seq2 == null) {
10894      return false;
10895    }
10896    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10897    for (int i = 0 ; i < minlength ; i++) {
10898      if (gt(seq1[i], seq2[i])) {
10899        return false;
10900      } else if (lt(seq1[i], seq2[i])) {
10901        return true;
10902      }
10903    }
10904    if (seq1.length >= seq2.length) {
10905      return false;
10906    }
10907    return true;
10908  }
10909
10910  /** Returns true iff seq1 is lexically &le; to seq2. */
10911  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10912  @Pure
10913  public static boolean lexLTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10914    if (seq1 == null) {
10915      return false;
10916    }
10917    if (seq2 == null) {
10918      return false;
10919    }
10920    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10921    for (int i = 0 ; i < minlength ; i++) {
10922      if (gt(seq1[i], seq2[i])) {
10923        return false;
10924      } else if (lt(seq1[i], seq2[i])) {
10925        return true;
10926      }
10927    }
10928    if (seq1.length > seq2.length) {
10929      return false;
10930    }
10931    return true;
10932  }
10933
10934  /** Returns true iff seq1 is lexically &gt; to seq2. */
10935  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10936  @Pure
10937  public static boolean lexGT(short @Nullable [] seq1, short @Nullable [] seq2) {
10938  if (seq1 == null) {
10939    return false;
10940  }
10941  if (seq2 == null) {
10942    return false;
10943  }
10944    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10945    for (int i = 0 ; i < minlength ; i++) {
10946      if (lt(seq1[i], seq2[i])) {
10947        return false;
10948      } else if (gt(seq1[i], seq2[i])) {
10949        return true;
10950      }
10951    }
10952    if (seq1.length <= seq2.length) {
10953      return false;
10954    }
10955    return true;
10956  }
10957
10958  /** Returns true iff seq1 is lexically &ge; to seq2. */
10959  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
10960  @Pure
10961  public static boolean lexGTE(short @Nullable [] seq1, short @Nullable [] seq2) {
10962  if (seq1 == null) {
10963    return false;
10964  }
10965  if (seq2 == null) {
10966    return false;
10967  }
10968    int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length;
10969    for (int i = 0 ; i < minlength ; i++) {
10970      if (lt(seq1[i], seq2[i])) {
10971        return false;
10972      } else if (gt(seq1[i], seq2[i])) {
10973        return true;
10974      }
10975    }
10976    if (seq1.length < seq2.length) {
10977      return false;
10978    }
10979    return true;
10980  }
10981
10982  /** True iff for all applicable i, every seq[i] == seq[i+1].
10983   *
10984   * Meaning (in pseudo-FOL):
10985   *
10986   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
10987   *
10988   */
10989  @EnsuresNonNullIf(result=true, expression="#1")
10990  @Pure
10991  public static boolean eltwiseEqual(short @Nullable [] seq) {
10992  if (seq == null) {
10993    return false;
10994  }
10995    for (int i = 0 ; i < seq.length ; i++) {
10996      if (i < seq.length - 1) {
10997        if (ne(seq[i], seq[i + 1])) {
10998          return false;
10999        }
11000      }
11001    }
11002    return true;
11003  }
11004
11005  /** True iff for all applicable i, every seq[i] != seq[i+1].
11006   *
11007   * Meaning (in pseudo-FOL):
11008   *
11009   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
11010   *
11011   */
11012  @EnsuresNonNullIf(result=true, expression="#1")
11013  @Pure
11014  public static boolean eltwiseNotEqual(short @Nullable [] seq) {
11015  if (seq == null) {
11016    return false;
11017  }
11018    for (int i = 0 ; i < seq.length ; i++) {
11019      if (i < seq.length - 1) {
11020        if (eq(seq[i], seq[i + 1])) {
11021          return false;
11022        }
11023      }
11024    }
11025    return true;
11026  }
11027
11028  /** True iff for all applicable i, every seq[i] &lt; seq[i+1].
11029   *
11030   * Meaning (in pseudo-FOL):
11031   *
11032   * forall i in { 0..seq.length-2 } : seq[i] &lt; seq[i+1]
11033   *
11034   */
11035  @EnsuresNonNullIf(result=true, expression="#1")
11036  @Pure
11037  public static boolean eltwiseLT(short @Nullable [] seq) {
11038  if (seq == null) {
11039    return false;
11040  }
11041    for (int i = 0 ; i < seq.length ; i++) {
11042      if (i < seq.length - 1) {
11043        if (gte(seq[i], seq[i + 1])) {
11044          return false;
11045        }
11046      }
11047    }
11048    return true;
11049  }
11050
11051  /** True iff for all applicable i, every seq[i] &le; seq[i+1].
11052   *
11053   * Meaning (in pseudo-FOL):
11054   *
11055   * forall i in { 0..seq.length-2 } : seq[i] &le; seq[i+1]
11056   *
11057   */
11058  @EnsuresNonNullIf(result=true, expression="#1")
11059  @Pure
11060  public static boolean eltwiseLTE(short @Nullable [] seq) {
11061  if (seq == null) {
11062    return false;
11063  }
11064    for (int i = 0 ; i < seq.length ; i++) {
11065      if (i < seq.length - 1) {
11066        if (gt(seq[i], seq[i + 1])) {
11067          return false;
11068        }
11069      }
11070    }
11071    return true;
11072  }
11073
11074  /** True iff for all applicable i, every seq[i] &gt; seq[i+1].
11075   *
11076   * Meaning (in pseudo-FOL):
11077   *
11078   * forall i in { 0..seq.length-2 } : seq[i] &gt; seq[i+1]
11079   *
11080   */
11081  @EnsuresNonNullIf(result=true, expression="#1")
11082  @Pure
11083  public static boolean eltwiseGT(short @Nullable [] seq) {
11084  if (seq == null) {
11085    return false;
11086  }
11087    for (int i = 0 ; i < seq.length ; i++) {
11088      if (i < seq.length - 1) {
11089        if (lte(seq[i], seq[i + 1])) {
11090          return false;
11091        }
11092      }
11093    }
11094    return true;
11095  }
11096
11097  /** True iff for all applicable i, every seq[i] &ge; seq[i+1].
11098   *
11099   * Meaning (in pseudo-FOL):
11100   *
11101   * forall i in { 0..seq.length-2 } : seq[i] &ge; seq[i+1]
11102   *
11103   */
11104  @EnsuresNonNullIf(result=true, expression="#1")
11105  @Pure
11106  public static boolean eltwiseGTE(short @Nullable [] seq) {
11107  if (seq == null) {
11108    return false;
11109  }
11110    for (int i = 0 ; i < seq.length ; i++) {
11111      if (i < seq.length - 1) {
11112        if (lt(seq[i], seq[i + 1])) {
11113          return false;
11114        }
11115      }
11116    }
11117    return true;
11118  }
11119
11120  /** True iff for all applicable i, every seq[i] == i.
11121   *
11122   * Meaning (in pseudo-FOL):
11123   *
11124   * forall i in { 0..seq.length-1 } : seq[i] == i
11125   *
11126   */
11127  @EnsuresNonNullIf(result=true, expression="#1")
11128  @Pure
11129  public static boolean eltsEqualIndex(short @Nullable [] seq) {
11130  if (seq == null) {
11131    return false;
11132  }
11133    for (int i = 0 ; i < seq.length ; i++) {
11134      if (ne(seq[i], i)) {
11135        return false;
11136      }
11137    }
11138    return true;
11139  }
11140
11141  /** True iff for all applicable i, every seq[i] != i.
11142   *
11143   * Meaning (in pseudo-FOL):
11144   *
11145   * forall i in { 0..seq.length-1 } : seq[i] != i
11146   *
11147   */
11148  @EnsuresNonNullIf(result=true, expression="#1")
11149  @Pure
11150  public static boolean eltsNotEqualIndex(short @Nullable [] seq) {
11151  if (seq == null) {
11152    return false;
11153  }
11154    for (int i = 0 ; i < seq.length ; i++) {
11155      if (eq(seq[i], i)) {
11156        return false;
11157      }
11158    }
11159    return true;
11160  }
11161
11162  /** True iff for all applicable i, every seq[i] &lt; i.
11163   *
11164   * Meaning (in pseudo-FOL):
11165   *
11166   * forall i in { 0..seq.length-1 } : seq[i] &lt; i
11167   *
11168   */
11169  @EnsuresNonNullIf(result=true, expression="#1")
11170  @Pure
11171  public static boolean eltsLtIndex(short @Nullable [] seq) {
11172  if (seq == null) {
11173    return false;
11174  }
11175    for (int i = 0 ; i < seq.length ; i++) {
11176      if (gte(seq[i], i)) {
11177        return false;
11178      }
11179    }
11180    return true;
11181  }
11182
11183  /** True iff for all applicable i, every seq[i] &le; i.
11184   *
11185   * Meaning (in pseudo-FOL):
11186   *
11187   * forall i in { 0..seq.length-1 } : seq[i] &le; i
11188   *
11189   */
11190  @EnsuresNonNullIf(result=true, expression="#1")
11191  @Pure
11192  public static boolean eltsLteIndex(short @Nullable [] seq) {
11193  if (seq == null) {
11194    return false;
11195  }
11196    for (int i = 0 ; i < seq.length ; i++) {
11197      if (gt(seq[i], i)) {
11198        return false;
11199      }
11200    }
11201    return true;
11202  }
11203
11204  /** True iff for all applicable i, every seq[i] &gt; i.
11205   *
11206   * Meaning (in pseudo-FOL):
11207   *
11208   * forall i in { 0..seq.length-1 } : seq[i] &gt; i
11209   *
11210   */
11211  @EnsuresNonNullIf(result=true, expression="#1")
11212  @Pure
11213  public static boolean eltsGtIndex(short @Nullable [] seq) {
11214  if (seq == null) {
11215    return false;
11216  }
11217    for (int i = 0 ; i < seq.length ; i++) {
11218      if (lte(seq[i], i)) {
11219        return false;
11220      }
11221    }
11222    return true;
11223  }
11224
11225  /** True iff for all applicable i, every seq[i] &ge; i.
11226   *
11227   * Meaning (in pseudo-FOL):
11228   *
11229   * forall i in { 0..seq.length-1 } : seq[i] &ge; i
11230   *
11231   */
11232  @EnsuresNonNullIf(result=true, expression="#1")
11233  @Pure
11234  public static boolean eltsGteIndex(short @Nullable [] seq) {
11235  if (seq == null) {
11236    return false;
11237  }
11238    for (int i = 0 ; i < seq.length ; i++) {
11239      if (lt(seq[i], i)) {
11240        return false;
11241      }
11242    }
11243    return true;
11244  }
11245
11246  // Deferencing (accessing) fields
11247
11248  /**
11249   * collectshort accepts an object and a list of fields (one of which is of array type, and the
11250   * rest of which are not), and produces an array in which the original object has had the given
11251   * fields accessed.
11252   *
11253   * <p>Daikon creates invariants over "variables" such as the following.
11254   *
11255   * <dl>
11256   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
11257   *              for all y's in array x.arr.</dd>
11258   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
11259   *              for all x's in array arr.</dd>
11260   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
11261   * </dl>
11262   *
11263   * <p>The collectshort() method does this collecting work.
11264   *
11265   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
11266   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
11267   * elements that result from following the fields, one of which is assumed to be an array.
11268   *
11269   * <p>
11270   * requires: fieldStr.length() &gt; 0 and object != null
11271   * <p>
11272   * requires: fieldStr contains only field names, no "[]" strings.
11273   * <p>
11274   * requires: the method only works for field sequences with exactly one field representing an
11275   * array. For example, the collection a[].b[].c will fail.
11276   *
11277   * @return if the resulting collection is of non-primitive type, then returns an array of type
11278   * Object[]. Returns null if any array or field access causes an exception.
11279   */
11280
11281  @SideEffectFree
11282  public static short @Nullable [] collectshort(@Nullable Object object, @Nullable String fieldStr) {
11283
11284    if (object == null) {
11285      return null;
11286    }
11287    if (fieldStr == null) {
11288      return null;
11289    }
11290
11291    // assert fieldStr != null && !"".equals(fieldStr);
11292    String[] fieldNames = fieldStr.split("\\.");
11293    short[] retval = collectshort(object, fieldNames, 0);
11294    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
11295    return retval;
11296  }
11297
11298  // @PolyNull does not work for return type, because null is returned on error.
11299  /** Helper method for collectshort(Object, String).
11300   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
11301   * @see collectshort(Object, String)
11302   */
11303
11304  @SideEffectFree
11305  private static short @Nullable [] collectshort(@Nullable Object object,
11306                                                   String[] fields, int fieldsStartIdx) {
11307
11308    if (object == null) {
11309      return null;
11310    }
11311    assert (fields != null);
11312    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
11313
11314    Object fieldObj;
11315    try {
11316      Field field = (object instanceof java.lang.Class<?>)
11317        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
11318        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
11319      field.setAccessible(true);
11320      // Class cls = field.getType();
11321      fieldObj = field.get(object);
11322      // System.out.println("***fieldObj="+fieldObj);
11323
11324    } catch (Exception e) {
11325      return null;
11326
11327    }
11328
11329    if (fieldObj == null) {
11330      return null;
11331    }
11332
11333    // base case: just accessed the last field
11334    if (fields.length - 1 == fieldsStartIdx) {
11335
11336      if (fieldObj.getClass().isArray()) {
11337        // last field is an array
11338        return (short[])fieldObj;
11339      } else {
11340        // This hack should be removed in favor of, at "oneEltArray = ..."
11341        // below, calling a version of collectshort_field that throws an
11342        // error.  Then, this case becomes a run-time error.  -MDE
11343
11344        // Just one element; return a one-element array.
11345        // assert cls.equals(Short.TYPE);
11346        return new short[] { ((Short)fieldObj).shortValue() };
11347      }
11348    } else {
11349      // recursive case: more fields to access after this one
11350
11351      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
11352
11353        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
11354        short[] intermediate = new short[collection.size()];
11355        int index = 0;
11356        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
11357          Object obj = i.next();
11358          short[] oneEltArray = collectshort(obj, fields, fieldsStartIdx + 1);
11359          if (oneEltArray == null) {
11360            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
11361          }
11362          // assert oneEltArray.length == 1;
11363          intermediate[index++] = oneEltArray[0];
11364        }
11365        return intermediate;
11366      } else if (fieldObj.getClass().isArray()) {
11367
11368        // collect elements across array
11369        short[] intermediate = new short[Array.getLength(fieldObj)];
11370        for (int i = 0 ; i < intermediate.length ; i++) {
11371          Object obj = Array.get(fieldObj, i);
11372          short[] oneEltArray = collectshort(obj, fields, fieldsStartIdx + 1);
11373          if (oneEltArray == null) {
11374            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
11375          }
11376          // assert oneEltArray.length == 1;
11377          intermediate[i] = oneEltArray[0];
11378        }
11379        return intermediate;
11380      } else {
11381
11382        return collectshort(fieldObj, fields, fieldsStartIdx + 1);
11383      }
11384    }
11385  }
11386
11387  /**
11388   * Returns the results of dereferencing the fields for 'object'. For example, the call
11389   *
11390   * <pre>collectshort_field(x, "f.g.h")</pre>
11391   *
11392   * has the same value as
11393   *
11394   * <pre>x.f.g.h</pre>.
11395   * Returns a default value if any field access causes an exception.
11396   */
11397  @SideEffectFree
11398  public static short collectshort_field(Object object, String fieldStr) {
11399
11400    if (object == null) {
11401      return Short.MAX_VALUE; // return default value
11402    }
11403    if (fieldStr == null) {
11404      return Short.MAX_VALUE; // return default value
11405    }
11406
11407    String[] fieldNames = fieldStr.split("\\.");
11408
11409    // Holds the intermediate (and final) result
11410    Object fieldObj = object;
11411
11412    for (int i = 0 ; i < fieldNames.length ; i++) {
11413
11414      String fieldName = fieldNames[i];
11415
11416      try {
11417        Field field =
11418          (fieldObj instanceof java.lang.Class<?>)
11419          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
11420          : fieldObj.getClass().getDeclaredField(fieldName);
11421        field.setAccessible(true);
11422        fieldObj = field.get(fieldObj);
11423
11424        if (fieldObj == null) {
11425          return Short.MAX_VALUE; // return default value
11426        }
11427
11428      } catch (Exception e) {
11429        return Short.MAX_VALUE; // return default value
11430
11431      }
11432
11433    }
11434
11435    return ((Short)fieldObj).shortValue();
11436  }
11437
11438  // ///////////////////////////////////////////////////////////////////////////
11439  // Methods for #@Interned Object (from QuantBody.java.jpp)
11440  //
11441
11442  /**
11443   * Returns the ith element of the array or collection argument. If the argument is null or not an
11444   * array or collection, returns a default value (null).
11445   */
11446
11447  @SuppressWarnings("interning") // reflection
11448
11449  @Pure
11450  public static @Nullable @Interned Object getElement_Object(Object o, long i) {
11451    if (o == null) {
11452      return null; // return default value
11453    }
11454    java.lang.Class<?> c = o.getClass();
11455    if (c.isArray()) {
11456      return java.lang.reflect.Array.get(o, (int)i);
11457    } else if (o instanceof java.util.AbstractCollection<?>) {
11458      return java.lang.reflect.Array.get(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
11459    } else {
11460      return null; // return default value
11461    }
11462  }
11463
11464  @SuppressWarnings("interning") // called reflectively
11465
11466  @Pure
11467  public static @Nullable @Interned Object getElement_Object(Object[] arr, long i) {
11468    if (arr == null) {
11469      return null; // return default value
11470    }
11471    return arr[(int)i];
11472  }
11473
11474  private static boolean eq(@Interned Object x, @Interned Object y) {
11475    return x == y;
11476  }
11477
11478  private static boolean ne(@Interned Object x, @Interned Object y) {
11479    return x != y;
11480  }
11481
11482  /**
11483   * Returns an array of Strings, where the strings are the result of invoking
11484   * x.getClass().toString() for each element x in the array. If an element of the array is null,
11485   * its slot in the returned array is null.
11486   */
11487  @SideEffectFree
11488  public static @PolyNull/*("elt")*/ String @PolyNull/*("container")*/ [] typeArray(@PolyNull/*("elt")*/ @Interned Object @PolyNull/*("container")*/ [] seq) {
11489    if (seq == null) {
11490      return null;
11491    }
11492    @PolyNull/*("elt")*/ String[] retval = new @PolyNull/*("elt")*/ String[seq.length];
11493    for (int i = 0 ; i < seq.length ; i++) {
11494      if (seq[i] == null) {
11495        retval[i] = null;
11496      } else {
11497        retval[i] = seq[i].getClass().toString();
11498      }
11499    }
11500    return retval;
11501  }
11502
11503  /** True iff both sequences are non-null and have the same length. */
11504  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
11505  @Pure
11506  public static boolean sameLength(Object @Nullable [] seq1, Object @Nullable [] seq2) {
11507    return ((seq1 != null)
11508            && (seq2 != null)
11509            && seq1.length == seq2.length);
11510  }
11511
11512  /**
11513   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
11514   *
11515   * <p>If either array is null, returns null. If either array is empty, returns only those
11516   * elements in the other array. If both arrays are empty, returns a new empty array.
11517   */
11518  @SideEffectFree
11519  public static @Interned Object @PolyNull [] concat(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11520    if (seq1 == null) {
11521      return null;
11522    }
11523    if (seq2 == null) {
11524      return null;
11525    }
11526    return ArraysPlume.concat(seq1, seq2);
11527  }
11528
11529  /**
11530   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
11531   * assurances about the order or repetition of elements: elements may be repeated, and their
11532   * order may be different from the order of elements in seq1 and seq2.
11533   */
11534  @SideEffectFree
11535  public static @Interned Object @PolyNull [] union(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11536    if (seq1 == null) {
11537      return null;
11538    }
11539    if (seq2 == null) {
11540      return null;
11541    }
11542    return concat(seq1, seq2);
11543  }
11544
11545  /**
11546   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
11547   * gives no assurances about the order or repetition of elements: elements may be repeated, and
11548   * their order may be different from the order of elements in seq1 and seq2.
11549   */
11550  @Pure
11551  public static @Interned Object @PolyNull [] intersection(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11552    if (seq1 == null) {
11553      return null;
11554    }
11555    if (seq2 == null) {
11556      return null;
11557    }
11558    @Interned Object[] intermediate = new @Interned Object[Math.min(seq1.length, seq2.length)];
11559    int length = 0;
11560    for (int i = 0 ; i < seq1.length ; i++) {
11561      if (memberOf(seq1[i], seq2) ) {
11562        intermediate[length++] = seq1[i];
11563      }
11564    }
11565    return ArraysPlume.subarray(intermediate, 0, length);
11566  }
11567
11568  /**
11569   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
11570   * no assurances about the order or repetition of elements: elements may be repeated, and their
11571   * order may be different from the order of elements in seq1 and seq2.
11572   */
11573  @Pure
11574  public static @Interned Object @PolyNull [] setDiff(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) {
11575    if (seq1 == null) {
11576      return null;
11577    }
11578    if (seq2 == null) {
11579      return null;
11580    }
11581    @Interned Object[] intermediate = new @Interned Object[seq1.length];
11582    int length = 0;
11583    for (int i = 0 ; i < seq1.length ; i++) {
11584      if (!memberOf(seq1[i], seq2)) {
11585        intermediate[length++] = seq1[i];
11586      }
11587    }
11588    return ArraysPlume.subarray(intermediate, 0, length);
11589  }
11590
11591  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
11592  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11593  @Pure
11594  public static boolean setEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11595    if (seq1 == null) {
11596      return false;
11597    }
11598    if (seq2 == null) {
11599      return false;
11600    }
11601    for (int i = 0; i < seq1.length ; i++) {
11602      if (!memberOf(seq1[i], seq2) ) {
11603        return false;
11604      }
11605    }
11606    for (int i = 0; i < seq2.length ; i++) {
11607      if (!memberOf(seq2[i], seq1) ) {
11608        return false;
11609      }
11610    }
11611    return true;
11612  }
11613
11614  /** True iff seq1 is the reverse of seq2.
11615   *
11616   * Meaning (in pseudo-FOL):
11617   *
11618   * <pre>
11619   * /\ seq1.length == seq2.length
11620   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
11621   * </pre>
11622   *
11623   */
11624  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11625  @Pure
11626  public static boolean isReverse(@Interned Object[] seq1, @Interned Object[] seq2) {
11627    if (!sameLength(seq1, seq2)) {
11628      return false;
11629    }
11630    assert seq1 != null && seq2 != null; // because sameLength() = true
11631    int length = seq1.length;
11632    for (int i = 0 ; i < length ; i++) {
11633      if (ne(seq1[i], seq2[length - i - 1])) {
11634        return false;
11635      }
11636    }
11637    return true;
11638  }
11639
11640  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11641  @Pure
11642  public static boolean isReverse(@PolyNull Collection<? extends @Interned Object> seq1, @Interned Object @Nullable [] seq2) {
11643    if (seq1 == null) {
11644      return false;
11645    }
11646    if (seq2 == null) {
11647      return false;
11648    }
11649    @Interned Object[] seq1_array = seq1.toArray(new @Interned Object[]{});
11650    return isReverse(seq1_array, seq2);
11651  }
11652
11653  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
11654  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11655  @Pure
11656  public static boolean subsetOf(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11657    if (seq1 == null) {
11658      return false;
11659    }
11660    if (seq2 == null) {
11661      return false;
11662    }
11663    for (int i = 0 ; i < seq1.length ; i++) {
11664      if (!memberOf(seq1[i], seq2)) {
11665        return false;
11666      }
11667    }
11668    return true;
11669  }
11670
11671  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11672  @Pure
11673  public static boolean subsetOf(@Nullable Collection<? extends @Interned Object> seq1, @Interned Object @Nullable [] seq2) {
11674    if (seq1 == null) {
11675      return false;
11676    }
11677    if (seq2 == null) {
11678      return false;
11679    }
11680    @Interned Object[] seq1_array = seq1.toArray(new @Interned Object[]{});
11681    return subsetOf(seq1_array, seq2);
11682  }
11683
11684  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11685  @Pure
11686  public static boolean subsetOf(@Interned Object @Nullable [] seq1, @Nullable Collection<? extends @Interned Object> seq2) {
11687    if (seq1 == null) {
11688      return false;
11689    }
11690    if (seq2 == null) {
11691      return false;
11692    }
11693    @Interned Object[] seq2_array = seq2.toArray(new @Interned Object[]{});
11694    return subsetOf(seq1, seq2_array);
11695  }
11696
11697  /** Returns true iff seq contains no duplicate elements. */
11698  @EnsuresNonNullIf(result=true, expression="#1")
11699  @Pure
11700  public static boolean noDups(@Interned Object @Nullable [] seq) {
11701    if (seq == null) {
11702      return false;
11703    }
11704    return ArraysPlume.hasNoDuplicates(seq);
11705  }
11706
11707 /** Returns true iff elt is in array arr. */
11708  @EnsuresNonNullIf(result=true, expression="#2")
11709  @Pure
11710  public static boolean memberOf(@Interned Object elt, @Interned Object @Nullable [] arr) {
11711    if (arr == null) {
11712      return false;
11713    }
11714    for (int i = 0 ; i < arr.length ; i++) {
11715      if (eq(arr[i], elt)) {
11716        return true;
11717      }
11718    }
11719    return false;
11720  }
11721
11722  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
11723  @Pure
11724  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, int start, int end) {
11725    if (seq == null) {
11726      return null;
11727    }
11728    int sliceStart = start;
11729    int sliceEnd = end;
11730    if (start < 0) {
11731      return new @Interned Object[] { };
11732    }
11733    if (end > seq.length - 1) {
11734      return new @Interned Object[] { };
11735    }
11736    if (sliceStart > sliceEnd) {
11737      return new @Interned Object[] { };
11738    }
11739    int length = sliceEnd - sliceStart + 1;
11740    return ArraysPlume.subarray(seq, sliceStart, length);
11741  }
11742
11743  @Pure
11744  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, long start, int end) {
11745    return slice(seq, (int)start, end);
11746  }
11747  @Pure
11748  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, int start, long end) {
11749    return slice(seq, start, (int)end);
11750  }
11751  @Pure
11752  public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, long start, long end) {
11753    return slice(seq, (int)start, (int)end);
11754  }
11755
11756  /** True iff all elements in arr equal elt.
11757   *
11758   * Meaning (in pseudo-FOL):
11759   *
11760   * forall i in { 0..arr.length-1 } : arr[i] == elt
11761   *
11762   */
11763  @EnsuresNonNullIf(result=true, expression="#1")
11764  @Pure
11765  public static boolean eltsEqual(@Interned Object @Nullable [] arr, @Interned Object elt) {
11766    if (arr == null) {
11767      return false;
11768    }
11769    for (int i = 0 ; i < arr.length ; i++) {
11770      if (ne(arr[i], elt)) {
11771        return false;
11772      }
11773    }
11774    return true;
11775  }
11776
11777  /** True iff every element in arr does not equal elt.
11778   *
11779   * Meaning (in pseudo-FOL):
11780   *
11781   * forall i in { 0..arr.length-1 } : arr[i] != elt
11782   *
11783   */
11784  @EnsuresNonNullIf(result=true, expression="#1")
11785  @Pure
11786  public static boolean eltsNotEqual(@Interned Object @Nullable [] arr, @Interned Object elt) {
11787    if (arr == null) {
11788      return false;
11789    }
11790    for (int i = 0 ; i < arr.length ; i++) {
11791      if (eq(arr[i], elt)) {
11792        return false;
11793      }
11794    }
11795    return true;
11796  }
11797
11798  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
11799   *
11800   * Meaning (in pseudo-FOL):
11801   *
11802   * /\ seq1.length == se2.length
11803   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
11804   *
11805   */
11806
11807  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11808  @Pure
11809  public static boolean pairwiseEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11810    if (!sameLength(seq1, seq2)) {
11811      return false;
11812    }
11813    assert seq1 != null && seq2 != null; // because sameLength() = true
11814    for (int i = 0 ; i < seq1.length ; i++) {
11815      if (ne(seq1[i], seq2[i])) {
11816        return false;
11817      }
11818    }
11819    return true;
11820  }
11821
11822  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11823  @Pure
11824  public static boolean pairwiseEqual(@Nullable AbstractCollection<@Interned Object> seq1, @Interned Object @Nullable [] seq2) {
11825    if (seq1 == null) {
11826      return false;
11827    }
11828    if (seq2 == null) {
11829      return false;
11830    }
11831    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
11832    @Interned Object[] seq1a = (@Interned Object[]) seq1.toArray(new @Interned Object[0]);
11833    return pairwiseEqual(seq1a, seq2);
11834  }
11835
11836  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11837  @Pure
11838  public static boolean pairwiseEqual(@Interned Object @Nullable [] seq1, @Nullable AbstractCollection<@Interned Object> seq2) {
11839    if (seq1 == null) {
11840      return false;
11841    }
11842    if (seq2 == null) {
11843      return false;
11844    }
11845    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
11846    @Interned Object[] seq2a = (@Interned Object[]) seq2.toArray();
11847    return pairwiseEqual(seq1, seq2a);
11848  }
11849
11850  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
11851   *
11852   * Meaning (in pseudo-FOL):
11853   *
11854   * /\ seq1.length == se2.length
11855   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
11856   *
11857   */
11858  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11859  @Pure
11860  public static boolean pairwiseNotEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11861    if (!sameLength(seq1, seq2)) {
11862      return false;
11863    }
11864    assert seq1 != null && seq2 != null; // because sameLength() = true
11865    for (int i = 0 ; i < seq1.length ; i++) {
11866      if (eq(seq1[i], seq2[i])) {
11867        return false;
11868      }
11869    }
11870    return true;
11871  }
11872
11873  /**
11874   * Returns true iff seq1 is lexically equal to seq2.
11875   * For equality, "lexically" and "pairwise" are the same.
11876   */
11877  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11878  @Pure
11879  public static boolean lexEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11880    if (seq1 == null) {
11881      return false;
11882    }
11883    if (seq2 == null) {
11884      return false;
11885    }
11886    return pairwiseEqual(seq1, seq2);
11887  }
11888
11889  /** Returns true iff seq1 is lexically not equal to seq2. */
11890  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
11891  @Pure
11892  public static boolean lexNotEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) {
11893    if (seq1 == null) {
11894      return false;
11895    }
11896    if (seq2 == null) {
11897      return false;
11898    }
11899    return !lexEqual(seq1, seq2);
11900  }
11901
11902  /** True iff for all applicable i, every seq[i] == seq[i+1].
11903   *
11904   * Meaning (in pseudo-FOL):
11905   *
11906   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
11907   *
11908   */
11909  @EnsuresNonNullIf(result=true, expression="#1")
11910  @Pure
11911  public static boolean eltwiseEqual(@Interned Object @Nullable [] seq) {
11912  if (seq == null) {
11913    return false;
11914  }
11915    for (int i = 0 ; i < seq.length ; i++) {
11916      if (i < seq.length - 1) {
11917        if (ne(seq[i], seq[i + 1])) {
11918          return false;
11919        }
11920      }
11921    }
11922    return true;
11923  }
11924
11925  /** True iff for all applicable i, every seq[i] != seq[i+1].
11926   *
11927   * Meaning (in pseudo-FOL):
11928   *
11929   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
11930   *
11931   */
11932  @EnsuresNonNullIf(result=true, expression="#1")
11933  @Pure
11934  public static boolean eltwiseNotEqual(@Interned Object @Nullable [] seq) {
11935  if (seq == null) {
11936    return false;
11937  }
11938    for (int i = 0 ; i < seq.length ; i++) {
11939      if (i < seq.length - 1) {
11940        if (eq(seq[i], seq[i + 1])) {
11941          return false;
11942        }
11943      }
11944    }
11945    return true;
11946  }
11947
11948  // Deferencing (accessing) fields
11949
11950  /**
11951   * collectObject accepts an object and a list of fields (one of which is of array type, and the
11952   * rest of which are not), and produces an array in which the original object has had the given
11953   * fields accessed.
11954   *
11955   * <p>Daikon creates invariants over "variables" such as the following.
11956   *
11957   * <dl>
11958   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
11959   *              for all y's in array x.arr.</dd>
11960   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
11961   *              for all x's in array arr.</dd>
11962   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
11963   * </dl>
11964   *
11965   * <p>The collectObject() method does this collecting work.
11966   *
11967   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
11968   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
11969   * elements that result from following the fields, one of which is assumed to be an array.
11970   *
11971   * <p>
11972   * requires: fieldStr.length() &gt; 0 and object != null
11973   * <p>
11974   * requires: fieldStr contains only field names, no "[]" strings.
11975   * <p>
11976   * requires: the method only works for field sequences with exactly one field representing an
11977   * array. For example, the collection a[].b[].c will fail.
11978   *
11979   * @return if the resulting collection is of non-primitive type, then returns an array of type
11980   * Object[]. Returns null if any array or field access causes an exception.
11981   */
11982
11983  @SuppressWarnings("interning") // reflection
11984
11985  @SideEffectFree
11986  public static Object @Nullable [] collectObject(@Nullable Object object, @Nullable String fieldStr) {
11987
11988    if (object == null) {
11989      return null;
11990    }
11991    if (fieldStr == null) {
11992      return null;
11993    }
11994
11995    // assert fieldStr != null && !"".equals(fieldStr);
11996    String[] fieldNames = fieldStr.split("\\.");
11997    @Interned Object[] retval = collectObject(object, fieldNames, 0);
11998    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
11999    return retval;
12000  }
12001
12002  // @PolyNull does not work for return type, because null is returned on error.
12003  /** Helper method for collectObject(Object, String).
12004   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
12005   * @see collectObject(Object, String)
12006   */
12007
12008  @SuppressWarnings("interning") // reflection
12009
12010  @SideEffectFree
12011  private static Object @Nullable [] collectObject(@Nullable Object object,
12012                                                   String[] fields, int fieldsStartIdx) {
12013
12014    if (object == null) {
12015      return null;
12016    }
12017    assert (fields != null);
12018    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
12019
12020    Object fieldObj;
12021    try {
12022      Field field = (object instanceof java.lang.Class<?>)
12023        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
12024        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
12025      field.setAccessible(true);
12026      // Class cls = field.getType();
12027      fieldObj = field.get(object);
12028      // System.out.println("***fieldObj="+fieldObj);
12029
12030    } catch (Exception e) {
12031      return null;
12032
12033    }
12034
12035    if (fieldObj == null) {
12036      return null;
12037    }
12038
12039    // base case: just accessed the last field
12040    if (fields.length - 1 == fieldsStartIdx) {
12041
12042      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12043        // last field is the collection
12044        @SuppressWarnings("unchecked")
12045        java.util.AbstractCollection<@Interned Object> ac = (java.util.AbstractCollection<@Interned Object>)fieldObj;
12046        return ac.toArray(new @Interned Object[]{});
12047      } else
12048
12049      if (fieldObj.getClass().isArray()) {
12050        // last field is an array
12051        return (@Interned Object[])fieldObj;
12052      } else {
12053        // This hack should be removed in favor of, at "oneEltArray = ..."
12054        // below, calling a version of collectObject_field that throws an
12055        // error.  Then, this case becomes a run-time error.  -MDE
12056
12057        // Just one element; return a one-element array.
12058        // assert cls.equals(_TYPE_WRAPPER_NAME.TYPE);
12059        return new @Interned Object[] { fieldObj };
12060      }
12061    } else {
12062      // recursive case: more fields to access after this one
12063
12064      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12065
12066        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
12067        @Interned Object[] intermediate = new @Interned Object[collection.size()];
12068        int index = 0;
12069        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
12070          Object obj = i.next();
12071          Object[] oneEltArray = collectObject(obj, fields, fieldsStartIdx + 1);
12072          if (oneEltArray == null) {
12073            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12074          }
12075          // assert oneEltArray.length == 1;
12076          intermediate[index++] = oneEltArray[0];
12077        }
12078        return intermediate;
12079      } else if (fieldObj.getClass().isArray()) {
12080
12081        // collect elements across array
12082        @Interned Object[] intermediate = new @Interned Object[Array.getLength(fieldObj)];
12083        for (int i = 0 ; i < intermediate.length ; i++) {
12084          Object obj = Array.get(fieldObj, i);
12085          Object[] oneEltArray = collectObject(obj, fields, fieldsStartIdx + 1);
12086          if (oneEltArray == null) {
12087            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12088          }
12089          // assert oneEltArray.length == 1;
12090          intermediate[i] = oneEltArray[0];
12091        }
12092        return intermediate;
12093      } else {
12094
12095        return collectObject(fieldObj, fields, fieldsStartIdx + 1);
12096      }
12097    }
12098  }
12099
12100  /**
12101   * Returns the results of dereferencing the fields for 'object'. For example, the call
12102   *
12103   * <pre>collectObject_field(x, "f.g.h")</pre>
12104   *
12105   * has the same value as
12106   *
12107   * <pre>x.f.g.h</pre>.
12108   * Returns a default value if any field access causes an exception.
12109   */
12110  @SideEffectFree
12111  public static @Nullable Object collectObject_field(Object object, String fieldStr) {
12112
12113    if (object == null) {
12114      return null; // return default value
12115    }
12116    if (fieldStr == null) {
12117      return null; // return default value
12118    }
12119
12120    String[] fieldNames = fieldStr.split("\\.");
12121
12122    // Holds the intermediate (and final) result
12123    Object fieldObj = object;
12124
12125    for (int i = 0 ; i < fieldNames.length ; i++) {
12126
12127      String fieldName = fieldNames[i];
12128
12129      try {
12130        Field field =
12131          (fieldObj instanceof java.lang.Class<?>)
12132          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
12133          : fieldObj.getClass().getDeclaredField(fieldName);
12134        field.setAccessible(true);
12135        fieldObj = field.get(fieldObj);
12136
12137        if (fieldObj == null) {
12138          return null; // return default value
12139        }
12140
12141      } catch (Exception e) {
12142        return null; // return default value
12143
12144      }
12145
12146    }
12147
12148    return fieldObj;
12149  }
12150
12151  // ///////////////////////////////////////////////////////////////////////////
12152  // Methods for #@Interned String (from QuantBody.java.jpp)
12153  //
12154
12155  /**
12156   * Returns the ith element of the array or collection argument. If the argument is null or not an
12157   * array or collection, returns a default value (null).
12158   */
12159
12160  @SuppressWarnings("interning") // reflection
12161
12162  @Pure
12163  public static @Nullable @Interned String getElement_String(Object o, long i) {
12164    if (o == null) {
12165      return null; // return default value
12166    }
12167    java.lang.Class<?> c = o.getClass();
12168    if (c.isArray()) {
12169      return (String)java.lang.reflect.Array.get(o, (int)i);
12170    } else if (o instanceof java.util.AbstractCollection<?>) {
12171      return (String)java.lang.reflect.Array.get(((java.util.AbstractCollection<?>)o).toArray(), (int)i);
12172    } else {
12173      return null; // return default value
12174    }
12175  }
12176
12177  @SuppressWarnings("interning") // called reflectively
12178
12179  @Pure
12180  public static @Nullable @Interned String getElement_String(String[] arr, long i) {
12181    if (arr == null) {
12182      return null; // return default value
12183    }
12184    return arr[(int)i];
12185  }
12186
12187  private static boolean eq(@Interned String x, @Interned String y) {
12188    return x == y;
12189  }
12190
12191  private static boolean ne(@Interned String x, @Interned String y) {
12192    return x != y;
12193  }
12194
12195  /** True iff both sequences are non-null and have the same length. */
12196  @EnsuresNonNullIf(result=true, expression={"#1", "#2"})
12197  @Pure
12198  public static boolean sameLength(String @Nullable [] seq1, String @Nullable [] seq2) {
12199    return ((seq1 != null)
12200            && (seq2 != null)
12201            && seq1.length == seq2.length);
12202  }
12203
12204  /**
12205   * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } .
12206   *
12207   * <p>If either array is null, returns null. If either array is empty, returns only those
12208   * elements in the other array. If both arrays are empty, returns a new empty array.
12209   */
12210  @SideEffectFree
12211  public static @Interned String @PolyNull [] concat(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12212    if (seq1 == null) {
12213      return null;
12214    }
12215    if (seq2 == null) {
12216      return null;
12217    }
12218    return ArraysPlume.concat(seq1, seq2);
12219  }
12220
12221  /**
12222   * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no
12223   * assurances about the order or repetition of elements: elements may be repeated, and their
12224   * order may be different from the order of elements in seq1 and seq2.
12225   */
12226  @SideEffectFree
12227  public static @Interned String @PolyNull [] union(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12228    if (seq1 == null) {
12229      return null;
12230    }
12231    if (seq2 == null) {
12232      return null;
12233    }
12234    return concat(seq1, seq2);
12235  }
12236
12237  /**
12238   * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method
12239   * gives no assurances about the order or repetition of elements: elements may be repeated, and
12240   * their order may be different from the order of elements in seq1 and seq2.
12241   */
12242  @Pure
12243  public static @Interned String @PolyNull [] intersection(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12244    if (seq1 == null) {
12245      return null;
12246    }
12247    if (seq2 == null) {
12248      return null;
12249    }
12250    @Interned String[] intermediate = new @Interned String[Math.min(seq1.length, seq2.length)];
12251    int length = 0;
12252    for (int i = 0 ; i < seq1.length ; i++) {
12253      if (memberOf(seq1[i], seq2) ) {
12254        intermediate[length++] = seq1[i];
12255      }
12256    }
12257    return ArraysPlume.subarray(intermediate, 0, length);
12258  }
12259
12260  /**
12261   * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives
12262   * no assurances about the order or repetition of elements: elements may be repeated, and their
12263   * order may be different from the order of elements in seq1 and seq2.
12264   */
12265  @Pure
12266  public static @Interned String @PolyNull [] setDiff(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) {
12267    if (seq1 == null) {
12268      return null;
12269    }
12270    if (seq2 == null) {
12271      return null;
12272    }
12273    @Interned String[] intermediate = new @Interned String[seq1.length];
12274    int length = 0;
12275    for (int i = 0 ; i < seq1.length ; i++) {
12276      if (!memberOf(seq1[i], seq2)) {
12277        intermediate[length++] = seq1[i];
12278      }
12279    }
12280    return ArraysPlume.subarray(intermediate, 0, length);
12281  }
12282
12283  /** Returns true iff seq1 and seq2 are equal when considered as sets. */
12284  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12285  @Pure
12286  public static boolean setEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12287    if (seq1 == null) {
12288      return false;
12289    }
12290    if (seq2 == null) {
12291      return false;
12292    }
12293    for (int i = 0; i < seq1.length ; i++) {
12294      if (!memberOf(seq1[i], seq2) ) {
12295        return false;
12296      }
12297    }
12298    for (int i = 0; i < seq2.length ; i++) {
12299      if (!memberOf(seq2[i], seq1) ) {
12300        return false;
12301      }
12302    }
12303    return true;
12304  }
12305
12306  /** True iff seq1 is the reverse of seq2.
12307   *
12308   * Meaning (in pseudo-FOL):
12309   *
12310   * <pre>
12311   * /\ seq1.length == seq2.length
12312   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i]
12313   * </pre>
12314   *
12315   */
12316  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12317  @Pure
12318  public static boolean isReverse(@Interned String[] seq1, @Interned String[] seq2) {
12319    if (!sameLength(seq1, seq2)) {
12320      return false;
12321    }
12322    assert seq1 != null && seq2 != null; // because sameLength() = true
12323    int length = seq1.length;
12324    for (int i = 0 ; i < length ; i++) {
12325      if (ne(seq1[i], seq2[length - i - 1])) {
12326        return false;
12327      }
12328    }
12329    return true;
12330  }
12331
12332  /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */
12333  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12334  @Pure
12335  public static boolean subsetOf(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12336    if (seq1 == null) {
12337      return false;
12338    }
12339    if (seq2 == null) {
12340      return false;
12341    }
12342    for (int i = 0 ; i < seq1.length ; i++) {
12343      if (!memberOf(seq1[i], seq2)) {
12344        return false;
12345      }
12346    }
12347    return true;
12348  }
12349
12350  /** Returns true iff seq contains no duplicate elements. */
12351  @EnsuresNonNullIf(result=true, expression="#1")
12352  @Pure
12353  public static boolean noDups(@Interned String @Nullable [] seq) {
12354    if (seq == null) {
12355      return false;
12356    }
12357    return ArraysPlume.hasNoDuplicates(seq);
12358  }
12359
12360 /** Returns true iff elt is in array arr. */
12361  @EnsuresNonNullIf(result=true, expression="#2")
12362  @Pure
12363  public static boolean memberOf(@Interned String elt, @Interned String @Nullable [] arr) {
12364    if (arr == null) {
12365      return false;
12366    }
12367    for (int i = 0 ; i < arr.length ; i++) {
12368      if (eq(arr[i], elt)) {
12369        return true;
12370      }
12371    }
12372    return false;
12373  }
12374
12375  /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */
12376  @Pure
12377  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, int start, int end) {
12378    if (seq == null) {
12379      return null;
12380    }
12381    int sliceStart = start;
12382    int sliceEnd = end;
12383    if (start < 0) {
12384      return new @Interned String[] { };
12385    }
12386    if (end > seq.length - 1) {
12387      return new @Interned String[] { };
12388    }
12389    if (sliceStart > sliceEnd) {
12390      return new @Interned String[] { };
12391    }
12392    int length = sliceEnd - sliceStart + 1;
12393    return ArraysPlume.subarray(seq, sliceStart, length);
12394  }
12395
12396  @Pure
12397  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, long start, int end) {
12398    return slice(seq, (int)start, end);
12399  }
12400  @Pure
12401  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, int start, long end) {
12402    return slice(seq, start, (int)end);
12403  }
12404  @Pure
12405  public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, long start, long end) {
12406    return slice(seq, (int)start, (int)end);
12407  }
12408
12409  /** True iff all elements in arr equal elt.
12410   *
12411   * Meaning (in pseudo-FOL):
12412   *
12413   * forall i in { 0..arr.length-1 } : arr[i] == elt
12414   *
12415   */
12416  @EnsuresNonNullIf(result=true, expression="#1")
12417  @Pure
12418  public static boolean eltsEqual(@Interned String @Nullable [] arr, @Interned String elt) {
12419    if (arr == null) {
12420      return false;
12421    }
12422    for (int i = 0 ; i < arr.length ; i++) {
12423      if (ne(arr[i], elt)) {
12424        return false;
12425      }
12426    }
12427    return true;
12428  }
12429
12430  /** True iff every element in arr does not equal elt.
12431   *
12432   * Meaning (in pseudo-FOL):
12433   *
12434   * forall i in { 0..arr.length-1 } : arr[i] != elt
12435   *
12436   */
12437  @EnsuresNonNullIf(result=true, expression="#1")
12438  @Pure
12439  public static boolean eltsNotEqual(@Interned String @Nullable [] arr, @Interned String elt) {
12440    if (arr == null) {
12441      return false;
12442    }
12443    for (int i = 0 ; i < arr.length ; i++) {
12444      if (eq(arr[i], elt)) {
12445        return false;
12446      }
12447    }
12448    return true;
12449  }
12450
12451  /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i].
12452   *
12453   * Meaning (in pseudo-FOL):
12454   *
12455   * /\ seq1.length == se2.length
12456   * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i]
12457   *
12458   */
12459
12460  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12461  @Pure
12462  public static boolean pairwiseEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12463    if (!sameLength(seq1, seq2)) {
12464      return false;
12465    }
12466    assert seq1 != null && seq2 != null; // because sameLength() = true
12467    for (int i = 0 ; i < seq1.length ; i++) {
12468      if (ne(seq1[i], seq2[i])) {
12469        return false;
12470      }
12471    }
12472    return true;
12473  }
12474
12475  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12476  @Pure
12477  public static boolean pairwiseEqual(@Nullable AbstractCollection<@Interned String> seq1, @Interned String @Nullable [] seq2) {
12478    if (seq1 == null) {
12479      return false;
12480    }
12481    if (seq2 == null) {
12482      return false;
12483    }
12484    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
12485    @Interned String[] seq1a = (@Interned String[]) seq1.toArray(new @Interned String[0]);
12486    return pairwiseEqual(seq1a, seq2);
12487  }
12488
12489  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12490  @Pure
12491  public static boolean pairwiseEqual(@Interned String @Nullable [] seq1, @Nullable AbstractCollection<@Interned String> seq2) {
12492    if (seq1 == null) {
12493      return false;
12494    }
12495    if (seq2 == null) {
12496      return false;
12497    }
12498    @SuppressWarnings("cast") // cast is redundant (except in JSR 308)
12499    @Interned String[] seq2a = (@Interned String[]) seq2.toArray();
12500    return pairwiseEqual(seq1, seq2a);
12501  }
12502
12503  /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i].
12504   *
12505   * Meaning (in pseudo-FOL):
12506   *
12507   * /\ seq1.length == se2.length
12508   * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i]
12509   *
12510   */
12511  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12512  @Pure
12513  public static boolean pairwiseNotEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12514    if (!sameLength(seq1, seq2)) {
12515      return false;
12516    }
12517    assert seq1 != null && seq2 != null; // because sameLength() = true
12518    for (int i = 0 ; i < seq1.length ; i++) {
12519      if (eq(seq1[i], seq2[i])) {
12520        return false;
12521      }
12522    }
12523    return true;
12524  }
12525
12526  /**
12527   * Returns true iff seq1 is lexically equal to seq2.
12528   * For equality, "lexically" and "pairwise" are the same.
12529   */
12530  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12531  @Pure
12532  public static boolean lexEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12533    if (seq1 == null) {
12534      return false;
12535    }
12536    if (seq2 == null) {
12537      return false;
12538    }
12539    return pairwiseEqual(seq1, seq2);
12540  }
12541
12542  /** Returns true iff seq1 is lexically not equal to seq2. */
12543  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12544  @Pure
12545  public static boolean lexNotEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) {
12546    if (seq1 == null) {
12547      return false;
12548    }
12549    if (seq2 == null) {
12550      return false;
12551    }
12552    return !lexEqual(seq1, seq2);
12553  }
12554
12555  /** True iff for all applicable i, every seq[i] == seq[i+1].
12556   *
12557   * Meaning (in pseudo-FOL):
12558   *
12559   * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1]
12560   *
12561   */
12562  @EnsuresNonNullIf(result=true, expression="#1")
12563  @Pure
12564  public static boolean eltwiseEqual(@Interned String @Nullable [] seq) {
12565  if (seq == null) {
12566    return false;
12567  }
12568    for (int i = 0 ; i < seq.length ; i++) {
12569      if (i < seq.length - 1) {
12570        if (ne(seq[i], seq[i + 1])) {
12571          return false;
12572        }
12573      }
12574    }
12575    return true;
12576  }
12577
12578  /** True iff for all applicable i, every seq[i] != seq[i+1].
12579   *
12580   * Meaning (in pseudo-FOL):
12581   *
12582   * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1]
12583   *
12584   */
12585  @EnsuresNonNullIf(result=true, expression="#1")
12586  @Pure
12587  public static boolean eltwiseNotEqual(@Interned String @Nullable [] seq) {
12588  if (seq == null) {
12589    return false;
12590  }
12591    for (int i = 0 ; i < seq.length ; i++) {
12592      if (i < seq.length - 1) {
12593        if (eq(seq[i], seq[i + 1])) {
12594          return false;
12595        }
12596      }
12597    }
12598    return true;
12599  }
12600
12601  // Deferencing (accessing) fields
12602
12603  /**
12604   * collectString accepts an object and a list of fields (one of which is of array type, and the
12605   * rest of which are not), and produces an array in which the original object has had the given
12606   * fields accessed.
12607   *
12608   * <p>Daikon creates invariants over "variables" such as the following.
12609   *
12610   * <dl>
12611   * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z
12612   *              for all y's in array x.arr.</dd>
12613   * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z
12614   *              for all x's in array arr.</dd>
12615   * <dt>x.y.z[]</dt>   <dd>The result of collecting all elements in array x.y.z[]</dd>
12616   * </dl>
12617   *
12618   * <p>The collectString() method does this collecting work.
12619   *
12620   * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string"
12621   * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the
12622   * elements that result from following the fields, one of which is assumed to be an array.
12623   *
12624   * <p>
12625   * requires: fieldStr.length() &gt; 0 and object != null
12626   * <p>
12627   * requires: fieldStr contains only field names, no "[]" strings.
12628   * <p>
12629   * requires: the method only works for field sequences with exactly one field representing an
12630   * array. For example, the collection a[].b[].c will fail.
12631   *
12632   * @return if the resulting collection is of non-primitive type, then returns an array of type
12633   * Object[]. Returns null if any array or field access causes an exception.
12634   */
12635
12636  @SuppressWarnings("interning") // reflection
12637
12638  @SideEffectFree
12639  public static String @Nullable [] collectString(@Nullable Object object, @Nullable String fieldStr) {
12640
12641    if (object == null) {
12642      return null;
12643    }
12644    if (fieldStr == null) {
12645      return null;
12646    }
12647
12648    // assert fieldStr != null && !"".equals(fieldStr);
12649    String[] fieldNames = fieldStr.split("\\.");
12650    @Interned String[] retval = collectString(object, fieldNames, 0);
12651    // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval));
12652    return retval;
12653  }
12654
12655  // @PolyNull does not work for return type, because null is returned on error.
12656  /** Helper method for collectString(Object, String).
12657   * Operates on a subset of the fields: those in fields[fieldsStartIdx..].
12658   * @see collectString(Object, String)
12659   */
12660
12661  @SuppressWarnings("interning") // reflection
12662
12663  @SideEffectFree
12664  private static String @Nullable [] collectString(@Nullable Object object,
12665                                                   String[] fields, int fieldsStartIdx) {
12666
12667    if (object == null) {
12668      return null;
12669    }
12670    assert (fields != null);
12671    assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length);
12672
12673    Object fieldObj;
12674    try {
12675      Field field = (object instanceof java.lang.Class<?>)
12676        ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx])
12677        : object.getClass().getDeclaredField(fields[fieldsStartIdx]);
12678      field.setAccessible(true);
12679      // Class cls = field.getType();
12680      fieldObj = field.get(object);
12681      // System.out.println("***fieldObj="+fieldObj);
12682
12683    } catch (Exception e) {
12684      return null;
12685
12686    }
12687
12688    if (fieldObj == null) {
12689      return null;
12690    }
12691
12692    // base case: just accessed the last field
12693    if (fields.length - 1 == fieldsStartIdx) {
12694
12695      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12696        // last field is the collection
12697        @SuppressWarnings("unchecked")
12698        java.util.AbstractCollection<@Interned String> ac = (java.util.AbstractCollection<@Interned String>)fieldObj;
12699        return ac.toArray(new @Interned String[]{});
12700      } else
12701
12702      if (fieldObj.getClass().isArray()) {
12703        // last field is an array
12704        return (@Interned String[])fieldObj;
12705      } else {
12706        // This hack should be removed in favor of, at "oneEltArray = ..."
12707        // below, calling a version of collectString_field that throws an
12708        // error.  Then, this case becomes a run-time error.  -MDE
12709
12710        // Just one element; return a one-element array.
12711        // assert cls.equals(_TYPE_WRAPPER_NAME.TYPE);
12712        return new @Interned String[] { (String)fieldObj };
12713      }
12714    } else {
12715      // recursive case: more fields to access after this one
12716
12717      if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) {
12718
12719        java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj;
12720        @Interned String[] intermediate = new @Interned String[collection.size()];
12721        int index = 0;
12722        for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) {
12723          Object obj = i.next();
12724          String[] oneEltArray = collectString(obj, fields, fieldsStartIdx + 1);
12725          if (oneEltArray == null) {
12726            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12727          }
12728          // assert oneEltArray.length == 1;
12729          intermediate[index++] = oneEltArray[0];
12730        }
12731        return intermediate;
12732      } else if (fieldObj.getClass().isArray()) {
12733
12734        // collect elements across array
12735        @Interned String[] intermediate = new @Interned String[Array.getLength(fieldObj)];
12736        for (int i = 0 ; i < intermediate.length ; i++) {
12737          Object obj = Array.get(fieldObj, i);
12738          String[] oneEltArray = collectString(obj, fields, fieldsStartIdx + 1);
12739          if (oneEltArray == null) {
12740            throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1));
12741          }
12742          // assert oneEltArray.length == 1;
12743          intermediate[i] = oneEltArray[0];
12744        }
12745        return intermediate;
12746      } else {
12747
12748        return collectString(fieldObj, fields, fieldsStartIdx + 1);
12749      }
12750    }
12751  }
12752
12753  /**
12754   * Returns the results of dereferencing the fields for 'object'. For example, the call
12755   *
12756   * <pre>collectString_field(x, "f.g.h")</pre>
12757   *
12758   * has the same value as
12759   *
12760   * <pre>x.f.g.h</pre>.
12761   * Returns a default value if any field access causes an exception.
12762   */
12763  @SideEffectFree
12764  public static @Nullable String collectString_field(Object object, String fieldStr) {
12765
12766    if (object == null) {
12767      return null; // return default value
12768    }
12769    if (fieldStr == null) {
12770      return null; // return default value
12771    }
12772
12773    String[] fieldNames = fieldStr.split("\\.");
12774
12775    // Holds the intermediate (and final) result
12776    Object fieldObj = object;
12777
12778    for (int i = 0 ; i < fieldNames.length ; i++) {
12779
12780      String fieldName = fieldNames[i];
12781
12782      try {
12783        Field field =
12784          (fieldObj instanceof java.lang.Class<?>)
12785          ? ((Class<?>)fieldObj).getDeclaredField(fieldName)
12786          : fieldObj.getClass().getDeclaredField(fieldName);
12787        field.setAccessible(true);
12788        fieldObj = field.get(fieldObj);
12789
12790        if (fieldObj == null) {
12791          return null; // return default value
12792        }
12793
12794      } catch (Exception e) {
12795        return null; // return default value
12796
12797      }
12798
12799    }
12800
12801    return (String)fieldObj;
12802  }
12803
12804  // ///////////////////////////////////////////////////////////////////////////
12805  // Collection methods (dispatch to array methods)
12806  //
12807
12808  // These methods handle calls to quant methods that instead of passing an
12809  // Object[] array, pass a Collection.  Each method handles arrays or
12810  // Collections.  They convert any Collection to an array, then invoke the
12811  // Object[] version of the method.
12812
12813  /**
12814   * See {@link #noDups(Object[])}.
12815   * @see #noDups(Object[])
12816   */
12817  @SuppressWarnings("interning") // cast from Object
12818  @EnsuresNonNullIf(result=true, expression="#1")
12819  @Pure
12820  public static boolean noDups(Object seq) {
12821    if (seq == null) {
12822      return false;
12823    }
12824    return noDups(toObjArray(seq));
12825  }
12826
12827  /**
12828   * See {@link #typeArray(Object[])}.
12829   * @see #typeArray(Object[])
12830   */
12831  @SuppressWarnings("interning") // cast from Object
12832  /*TODO: @AssertNonNullIfNonNull({"#1"})*/
12833  /* pure */ public static String @PolyNull [] typeArray(@PolyNull Object seq) {
12834    if (seq == null) {
12835      return null;
12836    }
12837    return typeArray(toObjArray(seq));
12838  }
12839
12840  /**
12841   * See {@link #eltwiseEqual(Object[])}.
12842   * @see #eltwiseEqual(Object[])
12843   */
12844  @SuppressWarnings("interning") // cast from Object
12845  @EnsuresNonNullIf(result=true, expression="#1")
12846  @Pure
12847  public static boolean eltwiseEqual(Object seq) {
12848    if (seq == null) {
12849      return false;
12850    }
12851    return eltwiseEqual(toObjArray(seq));
12852  }
12853
12854  /**
12855   * See {@link #eltwiseNotEqual(Object[])}.
12856   * @see #eltwiseNotEqual(Object[])
12857   */
12858  @SuppressWarnings("interning") // cast from Object
12859  @EnsuresNonNullIf(result=true, expression="#1")
12860  @Pure
12861  public static boolean eltwiseNotEqual(Object seq) {
12862    if (seq == null) {
12863      return false;
12864    }
12865    return eltwiseNotEqual(toObjArray(seq));
12866  }
12867
12868  /**
12869   * See {@link #concat(Object[], Object[])}.
12870   * @see #concat(Object[], Object[])
12871   */
12872  @SuppressWarnings("interning") // cast from Object
12873  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12874  @SideEffectFree
12875  public static java.lang.Object @PolyNull [] concat(@PolyNull Object seq1, @PolyNull Object seq2) {
12876    if (seq1 == null) {
12877      return null;
12878    }
12879    if (seq2 == null) {
12880      return null;
12881    }
12882    return concat(toObjArray(seq1), toObjArray(seq2));
12883  }
12884
12885  /**
12886   * See {@link #union(Object[], Object[])}.
12887   * @see #union(Object[], Object[])
12888   */
12889  @SuppressWarnings("interning") // cast from Object
12890  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12891  @SideEffectFree
12892  public static java.lang.Object @PolyNull [] union(@PolyNull Object seq1, @PolyNull Object seq2) {
12893    if (seq1 == null) {
12894      return null;
12895    }
12896    if (seq2 == null) {
12897      return null;
12898    }
12899    return union(toObjArray(seq1), toObjArray(seq2));
12900  }
12901
12902  /**
12903   * See {@link #intersection(Object[], Object[])}.
12904   * @see #intersection(Object[], Object[])
12905   */
12906  @SuppressWarnings("interning") // cast from Object
12907  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12908  @SideEffectFree
12909  public static java.lang.Object @PolyNull [] intersection(@PolyNull Object seq1, @PolyNull Object seq2) {
12910    if (seq1 == null) {
12911      return null;
12912    }
12913    if (seq2 == null) {
12914      return null;
12915    }
12916    return intersection(toObjArray(seq1), toObjArray(seq2));
12917  }
12918
12919  /**
12920   * See {@link #setDiff(Object[], Object[])}.
12921   * @see #setDiff(Object[], Object[])
12922   */
12923  @SuppressWarnings("interning") // cast from Object
12924  /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/
12925  @SideEffectFree
12926  public static java.lang.Object @PolyNull [] setDiff(@PolyNull Object seq1, @PolyNull Object seq2) {
12927    if (seq1 == null) {
12928      return null;
12929    }
12930    if (seq2 == null) {
12931      return null;
12932    }
12933    return setDiff(toObjArray(seq1), toObjArray(seq2));
12934  }
12935
12936  /**
12937   * See {@link #setEqual(Object[], Object[])}.
12938   * @see #setEqual(Object[], Object[])
12939   */
12940  @SuppressWarnings("interning")  // cast from Object
12941  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12942  @Pure
12943  public static boolean setEqual(@Nullable Object seq1, @Nullable Object seq2) {
12944    if (seq1 == null) {
12945      return false;
12946    }
12947    if (seq2 == null) {
12948      return false;
12949    }
12950    return setEqual(toObjArray(seq1), toObjArray(seq2));
12951  }
12952
12953  /**
12954   * See {@link #isReverse(Object[], Object[])}.
12955   * @see #isReverse(Object[], Object[])
12956   */
12957  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12958  @SuppressWarnings("interning")  // cast from Object
12959  @Pure
12960  public static boolean isReverse(@Nullable Object seq1, @Nullable Object seq2) {
12961    if (seq1 == null) {
12962      return false;
12963    }
12964    if (seq2 == null) {
12965      return false;
12966    }
12967    return isReverse(toObjArray(seq1), toObjArray(seq2));
12968  }
12969
12970  /**
12971   * See {@link #pairwiseEqual(Object[], Object[])}.
12972   * @see #pairwiseEqual(Object[], Object[])
12973   */
12974  @SuppressWarnings("interning")  // cast from Object
12975  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12976  @Pure
12977  public static boolean pairwiseEqual(@Nullable Object seq1, @Nullable Object seq2) {
12978    if (seq1 == null) {
12979      return false;
12980    }
12981    if (seq2 == null) {
12982      return false;
12983    }
12984    return pairwiseEqual(toObjArray(seq1), toObjArray(seq2));
12985  }
12986
12987  /**
12988   * See {@link #pairwiseNotEqual(Object[], Object[])}.
12989   * @see #pairwiseNotEqual(Object[], Object[])
12990   */
12991  @SuppressWarnings("interning")  // cast from Object
12992  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
12993  @Pure
12994  public static boolean pairwiseNotEqual(@Nullable Object seq1, @Nullable Object seq2) {
12995    if (seq1 == null) {
12996      return false;
12997    }
12998    if (seq2 == null) {
12999      return false;
13000    }
13001    return pairwiseNotEqual(toObjArray(seq1), toObjArray(seq2));
13002  }
13003
13004  /**
13005   * See {@link #lexEqual(Object[], Object[])}.
13006   * @see #lexEqual(Object[], Object[])
13007   */
13008  @SuppressWarnings("interning")  // cast from Object
13009  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
13010  @Pure
13011  public static boolean lexEqual(@Nullable Object seq1, @Nullable Object seq2) {
13012    if (seq1 == null) {
13013      return false;
13014    }
13015    if (seq2 == null) {
13016      return false;
13017    }
13018    return lexEqual(toObjArray(seq1), toObjArray(seq2));
13019  }
13020
13021  /**
13022   * See {@link #lexNotEqual(Object[], Object[])}.
13023   * @see #lexNotEqual(Object[], Object[])
13024   */
13025  @SuppressWarnings("interning")  // cast from Object
13026  @EnsuresNonNullIf(result=true, expression={"#1","#2"})
13027  @Pure
13028  public static boolean lexNotEqual(@Nullable Object seq1, @Nullable Object seq2) {
13029    if (seq1 == null) {
13030      return false;
13031    }
13032    if (seq2 == null) {
13033      return false;
13034    }
13035    return lexNotEqual(toObjArray(seq1), toObjArray(seq2));
13036  }
13037
13038  /**
13039   * See {@link #memberOf(Object, Object[])}.
13040   * @see #memberOf(Object, Object[])
13041   */
13042  @SuppressWarnings("interning")  // cast from Object
13043  @EnsuresNonNullIf(result=true, expression="#2")
13044  @Pure
13045  public static boolean memberOf(Object elt, @Nullable Object arr) {
13046    if (arr == null) {
13047      return false;
13048    }
13049    return memberOf(elt, toObjArray(arr));
13050  }
13051
13052  /**
13053   * See {@link #slice(Object[], int, int)}.
13054   * @see #slice(Object[], int, int)
13055   */
13056  @SuppressWarnings("interning")  // cast from Object
13057  /*TODO: @AssertNonNullIfNonNull("#1")*/
13058  @SideEffectFree
13059  public static Object @PolyNull [] slice(@PolyNull Object seq, int start, int end) {
13060    if (seq == null) {
13061      return null;
13062    }
13063    return slice(toObjArray(seq), start, end);
13064  }
13065
13066  /**
13067   * See {@link #eltsEqual(Object[], Object)}.
13068   * @see #eltsEqual(Object[], Object)
13069   */
13070  @SuppressWarnings("interning")  // cast from Object
13071  @EnsuresNonNullIf(result=true, expression="#1")
13072  @Pure
13073  public static boolean eltsEqual(@Nullable Object arr, Object elt) {
13074    if (arr == null) {
13075      return false;
13076    }
13077    return eltsEqual(toObjArray(arr), elt);
13078  }
13079
13080  /**
13081   * See {@link #eltsNotEqual(Object[], Object)}.
13082   * @see #eltsNotEqual(Object[], Object)
13083   */
13084  @SuppressWarnings("interning")  // cast from Object
13085  @EnsuresNonNullIf(result=true, expression="#1")
13086  @Pure
13087  public static boolean eltsNotEqual(@Nullable Object arr, Object elt) {
13088    if (arr == null) {
13089      return false;
13090    }
13091    return eltsNotEqual(toObjArray(arr), elt);
13092  }
13093
13094  @EnsuresNonNullIf(result=true, expression="#1")
13095  @Pure
13096  public static boolean isIntegralType(@Nullable Class<?> c) {
13097    if (c == null) {
13098      return false;
13099    }
13100    return
13101      (c.equals(Byte.TYPE)
13102       || c.equals(Short.TYPE)
13103       || c.equals(Integer.TYPE)
13104       || c.equals(Long.TYPE));
13105  }
13106
13107  @EnsuresNonNullIf(result=true, expression="#1")
13108  @Pure
13109  public static boolean isRealType(@Nullable Class<?> c) {
13110    if (c == null) {
13111      return false;
13112    }
13113    return
13114      (c.equals(Float.TYPE)
13115       || c.equals(Double.TYPE));
13116  }
13117
13118  @EnsuresNonNullIf(result=true, expression="#1")
13119  @Pure
13120  public static boolean isNumericType(Class<?> c) {
13121    if (c == null) {
13122      return false;
13123    }
13124    return isIntegralType(c) || isRealType(c);
13125  }
13126
13127  /** Returns an Object[] array, either by casting or by conversion from an
13128   * AbstractCollection.
13129   */
13130  /*TODO: @AssertNonNullIfNonNull("#1")*/
13131  public static Object @PolyNull [] toObjArray(@PolyNull Object o) {
13132    if (o == null) {
13133      return null;
13134    }
13135    if (o instanceof java.util.AbstractCollection<?>) {
13136      @SuppressWarnings({"unchecked"})
13137        AbstractCollection<Object> ac = (AbstractCollection<Object>)o;
13138      Object [] result = ac.toArray(new java.lang.Object []{});
13139      return result;
13140    } else if (o.getClass().isArray()) {
13141      return (Object[])o;
13142    } else {
13143      throw new IllegalArgumentException("not an array or collection: " + o);
13144    }
13145  }
13146}