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 ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 1542 * 1543 * Meaning (in pseudo-FOL): 1544 * 1545 * /\ seq1.length == se2.length 1546 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 1580 * Meaning (in pseudo-FOL): 1581 * 1582 * /\ seq1.length == se2.length 1583 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 1617 * Meaning (in pseudo-FOL): 1618 * 1619 * /\ seq1.length == se2.length 1620 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 1654 * Meaning (in pseudo-FOL): 1655 * 1656 * /\ seq1.length == se2.length 1657 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 1978 * 1979 * Meaning (in pseudo-FOL): 1980 * 1981 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 2001 * 2002 * Meaning (in pseudo-FOL): 2003 * 2004 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 2024 * 2025 * Meaning (in pseudo-FOL): 2026 * 2027 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 2047 * 2048 * Meaning (in pseudo-FOL): 2049 * 2050 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 2112 * 2113 * Meaning (in pseudo-FOL): 2114 * 2115 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 2133 * 2134 * Meaning (in pseudo-FOL): 2135 * 2136 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 2154 * 2155 * Meaning (in pseudo-FOL): 2156 * 2157 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 2175 * 2176 * Meaning (in pseudo-FOL): 2177 * 2178 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 2831 * 2832 * Meaning (in pseudo-FOL): 2833 * 2834 * /\ seq1.length == se2.length 2835 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 2854 * Meaning (in pseudo-FOL): 2855 * 2856 * /\ seq1.length == se2.length 2857 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 2876 * Meaning (in pseudo-FOL): 2877 * 2878 * /\ seq1.length == se2.length 2879 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 2898 * Meaning (in pseudo-FOL): 2899 * 2900 * /\ seq1.length == se2.length 2901 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 3091 * 3092 * Meaning (in pseudo-FOL): 3093 * 3094 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 3114 * 3115 * Meaning (in pseudo-FOL): 3116 * 3117 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 3137 * 3138 * Meaning (in pseudo-FOL): 3139 * 3140 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 3160 * 3161 * Meaning (in pseudo-FOL): 3162 * 3163 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 3225 * 3226 * Meaning (in pseudo-FOL): 3227 * 3228 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 3246 * 3247 * Meaning (in pseudo-FOL): 3248 * 3249 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 3267 * 3268 * Meaning (in pseudo-FOL): 3269 * 3270 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 3288 * 3289 * Meaning (in pseudo-FOL): 3290 * 3291 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 4288 * 4289 * Meaning (in pseudo-FOL): 4290 * 4291 * /\ seq1.length == se2.length 4292 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 4326 * Meaning (in pseudo-FOL): 4327 * 4328 * /\ seq1.length == se2.length 4329 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 4363 * Meaning (in pseudo-FOL): 4364 * 4365 * /\ seq1.length == se2.length 4366 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 4400 * Meaning (in pseudo-FOL): 4401 * 4402 * /\ seq1.length == se2.length 4403 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 4724 * 4725 * Meaning (in pseudo-FOL): 4726 * 4727 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 4747 * 4748 * Meaning (in pseudo-FOL): 4749 * 4750 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 4770 * 4771 * Meaning (in pseudo-FOL): 4772 * 4773 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 4793 * 4794 * Meaning (in pseudo-FOL): 4795 * 4796 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 4858 * 4859 * Meaning (in pseudo-FOL): 4860 * 4861 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 4879 * 4880 * Meaning (in pseudo-FOL): 4881 * 4882 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 4900 * 4901 * Meaning (in pseudo-FOL): 4902 * 4903 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 4921 * 4922 * Meaning (in pseudo-FOL): 4923 * 4924 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 5921 * 5922 * Meaning (in pseudo-FOL): 5923 * 5924 * /\ seq1.length == se2.length 5925 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 5959 * Meaning (in pseudo-FOL): 5960 * 5961 * /\ seq1.length == se2.length 5962 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 5996 * Meaning (in pseudo-FOL): 5997 * 5998 * /\ seq1.length == se2.length 5999 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 6033 * Meaning (in pseudo-FOL): 6034 * 6035 * /\ seq1.length == se2.length 6036 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 6357 * 6358 * Meaning (in pseudo-FOL): 6359 * 6360 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 6380 * 6381 * Meaning (in pseudo-FOL): 6382 * 6383 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 6403 * 6404 * Meaning (in pseudo-FOL): 6405 * 6406 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 6426 * 6427 * Meaning (in pseudo-FOL): 6428 * 6429 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 6491 * 6492 * Meaning (in pseudo-FOL): 6493 * 6494 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 6512 * 6513 * Meaning (in pseudo-FOL): 6514 * 6515 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 6533 * 6534 * Meaning (in pseudo-FOL): 6535 * 6536 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 6554 * 6555 * Meaning (in pseudo-FOL): 6556 * 6557 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 7753 * 7754 * Meaning (in pseudo-FOL): 7755 * 7756 * /\ seq1.length == se2.length 7757 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 7791 * Meaning (in pseudo-FOL): 7792 * 7793 * /\ seq1.length == se2.length 7794 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 7828 * Meaning (in pseudo-FOL): 7829 * 7830 * /\ seq1.length == se2.length 7831 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 7865 * Meaning (in pseudo-FOL): 7866 * 7867 * /\ seq1.length == se2.length 7868 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 8189 * 8190 * Meaning (in pseudo-FOL): 8191 * 8192 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 8212 * 8213 * Meaning (in pseudo-FOL): 8214 * 8215 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 8235 * 8236 * Meaning (in pseudo-FOL): 8237 * 8238 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 8258 * 8259 * Meaning (in pseudo-FOL): 8260 * 8261 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 8323 * 8324 * Meaning (in pseudo-FOL): 8325 * 8326 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 8344 * 8345 * Meaning (in pseudo-FOL): 8346 * 8347 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 8365 * 8366 * Meaning (in pseudo-FOL): 8367 * 8368 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 8386 * 8387 * Meaning (in pseudo-FOL): 8388 * 8389 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 9466 * 9467 * Meaning (in pseudo-FOL): 9468 * 9469 * /\ seq1.length == se2.length 9470 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 9504 * Meaning (in pseudo-FOL): 9505 * 9506 * /\ seq1.length == se2.length 9507 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 9541 * Meaning (in pseudo-FOL): 9542 * 9543 * /\ seq1.length == se2.length 9544 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 9578 * Meaning (in pseudo-FOL): 9579 * 9580 * /\ seq1.length == se2.length 9581 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 9902 * 9903 * Meaning (in pseudo-FOL): 9904 * 9905 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 9925 * 9926 * Meaning (in pseudo-FOL): 9927 * 9928 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 9948 * 9949 * Meaning (in pseudo-FOL): 9950 * 9951 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 9971 * 9972 * Meaning (in pseudo-FOL): 9973 * 9974 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 10036 * 10037 * Meaning (in pseudo-FOL): 10038 * 10039 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 10057 * 10058 * Meaning (in pseudo-FOL): 10059 * 10060 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 10078 * 10079 * Meaning (in pseudo-FOL): 10080 * 10081 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 10099 * 10100 * Meaning (in pseudo-FOL): 10101 * 10102 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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] > 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] ≥ 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] < 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] ≤ 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] < seq2[i]. 10769 * 10770 * Meaning (in pseudo-FOL): 10771 * 10772 * /\ seq1.length == se2.length 10773 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < 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] ≤ seq2[i]. 10792 * Meaning (in pseudo-FOL): 10793 * 10794 * /\ seq1.length == se2.length 10795 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ 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] > seq2[i]. 10814 * Meaning (in pseudo-FOL): 10815 * 10816 * /\ seq1.length == se2.length 10817 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > 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] ≥ seq2[i]. 10836 * Meaning (in pseudo-FOL): 10837 * 10838 * /\ seq1.length == se2.length 10839 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ 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 < 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 ≤ 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 > 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 ≥ 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] < seq[i+1]. 11029 * 11030 * Meaning (in pseudo-FOL): 11031 * 11032 * forall i in { 0..seq.length-2 } : seq[i] < 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] ≤ seq[i+1]. 11052 * 11053 * Meaning (in pseudo-FOL): 11054 * 11055 * forall i in { 0..seq.length-2 } : seq[i] ≤ 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] > seq[i+1]. 11075 * 11076 * Meaning (in pseudo-FOL): 11077 * 11078 * forall i in { 0..seq.length-2 } : seq[i] > 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] ≥ seq[i+1]. 11098 * 11099 * Meaning (in pseudo-FOL): 11100 * 11101 * forall i in { 0..seq.length-2 } : seq[i] ≥ 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] < i. 11163 * 11164 * Meaning (in pseudo-FOL): 11165 * 11166 * forall i in { 0..seq.length-1 } : seq[i] < 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] ≤ i. 11184 * 11185 * Meaning (in pseudo-FOL): 11186 * 11187 * forall i in { 0..seq.length-1 } : seq[i] ≤ 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] > i. 11205 * 11206 * Meaning (in pseudo-FOL): 11207 * 11208 * forall i in { 0..seq.length-1 } : seq[i] > 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] ≥ i. 11226 * 11227 * Meaning (in pseudo-FOL): 11228 * 11229 * forall i in { 0..seq.length-1 } : seq[i] ≥ 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() > 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() > 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() > 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}