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.noDuplicates(seq); 336 } 337 338 /** Returns true iff elt is in array arr. */ 339 @EnsuresNonNullIf(result=true, expression="#2") 340 @Pure 341 public static boolean memberOf(boolean elt, boolean @Nullable [] arr) { 342 if (arr == null) { 343 return false; 344 } 345 for (int i = 0 ; i < arr.length ; i++) { 346 if (eq(arr[i], elt)) { 347 return true; 348 } 349 } 350 return false; 351 } 352 353 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 354 @Pure 355 public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, int start, int end) { 356 if (seq == null) { 357 return null; 358 } 359 int sliceStart = start; 360 int sliceEnd = end; 361 if (start < 0) { 362 return new boolean[] { }; 363 } 364 if (end > seq.length - 1) { 365 return new boolean[] { }; 366 } 367 if (sliceStart > sliceEnd) { 368 return new boolean[] { }; 369 } 370 int length = sliceEnd - sliceStart + 1; 371 return ArraysPlume.subarray(seq, sliceStart, length); 372 } 373 374 @Pure 375 public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, long start, int end) { 376 return slice(seq, (int)start, end); 377 } 378 @Pure 379 public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, int start, long end) { 380 return slice(seq, start, (int)end); 381 } 382 @Pure 383 public static boolean @PolyNull [] slice(boolean @PolyNull [] seq, long start, long end) { 384 return slice(seq, (int)start, (int)end); 385 } 386 387 /** True iff all elements in arr equal elt. 388 * 389 * Meaning (in pseudo-FOL): 390 * 391 * forall i in { 0..arr.length-1 } : arr[i] == elt 392 * 393 */ 394 @EnsuresNonNullIf(result=true, expression="#1") 395 @Pure 396 public static boolean eltsEqual(boolean @Nullable [] arr, boolean elt) { 397 if (arr == null) { 398 return false; 399 } 400 for (int i = 0 ; i < arr.length ; i++) { 401 if (ne(arr[i], elt)) { 402 return false; 403 } 404 } 405 return true; 406 } 407 408 /** True iff every element in arr does not equal elt. 409 * 410 * Meaning (in pseudo-FOL): 411 * 412 * forall i in { 0..arr.length-1 } : arr[i] != elt 413 * 414 */ 415 @EnsuresNonNullIf(result=true, expression="#1") 416 @Pure 417 public static boolean eltsNotEqual(boolean @Nullable [] arr, boolean elt) { 418 if (arr == null) { 419 return false; 420 } 421 for (int i = 0 ; i < arr.length ; i++) { 422 if (eq(arr[i], elt)) { 423 return false; 424 } 425 } 426 return true; 427 } 428 429 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 430 * 431 * Meaning (in pseudo-FOL): 432 * 433 * /\ seq1.length == se2.length 434 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 435 * 436 */ 437 438 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 439 @Pure 440 public static boolean pairwiseEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) { 441 if (!sameLength(seq1, seq2)) { 442 return false; 443 } 444 assert seq1 != null && seq2 != null; // because sameLength() = true 445 for (int i = 0 ; i < seq1.length ; i++) { 446 if (ne(seq1[i], seq2[i])) { 447 return false; 448 } 449 } 450 return true; 451 } 452 453 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 454 * 455 * Meaning (in pseudo-FOL): 456 * 457 * /\ seq1.length == se2.length 458 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 459 * 460 */ 461 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 462 @Pure 463 public static boolean pairwiseNotEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) { 464 if (!sameLength(seq1, seq2)) { 465 return false; 466 } 467 assert seq1 != null && seq2 != null; // because sameLength() = true 468 for (int i = 0 ; i < seq1.length ; i++) { 469 if (eq(seq1[i], seq2[i])) { 470 return false; 471 } 472 } 473 return true; 474 } 475 476 /** 477 * Returns true iff seq1 is lexically equal to seq2. 478 * For equality, "lexically" and "pairwise" are the same. 479 */ 480 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 481 @Pure 482 public static boolean lexEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) { 483 if (seq1 == null) { 484 return false; 485 } 486 if (seq2 == null) { 487 return false; 488 } 489 return pairwiseEqual(seq1, seq2); 490 } 491 492 /** Returns true iff seq1 is lexically not equal to seq2. */ 493 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 494 @Pure 495 public static boolean lexNotEqual(boolean @Nullable [] seq1, boolean @Nullable [] seq2) { 496 if (seq1 == null) { 497 return false; 498 } 499 if (seq2 == null) { 500 return false; 501 } 502 return !lexEqual(seq1, seq2); 503 } 504 505 /** True iff for all applicable i, every seq[i] == seq[i+1]. 506 * 507 * Meaning (in pseudo-FOL): 508 * 509 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 510 * 511 */ 512 @EnsuresNonNullIf(result=true, expression="#1") 513 @Pure 514 public static boolean eltwiseEqual(boolean @Nullable [] seq) { 515 if (seq == null) { 516 return false; 517 } 518 for (int i = 0 ; i < seq.length ; i++) { 519 if (i < seq.length - 1) { 520 if (ne(seq[i], seq[i + 1])) { 521 return false; 522 } 523 } 524 } 525 return true; 526 } 527 528 /** True iff for all applicable i, every seq[i] != seq[i+1]. 529 * 530 * Meaning (in pseudo-FOL): 531 * 532 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 533 * 534 */ 535 @EnsuresNonNullIf(result=true, expression="#1") 536 @Pure 537 public static boolean eltwiseNotEqual(boolean @Nullable [] seq) { 538 if (seq == null) { 539 return false; 540 } 541 for (int i = 0 ; i < seq.length ; i++) { 542 if (i < seq.length - 1) { 543 if (eq(seq[i], seq[i + 1])) { 544 return false; 545 } 546 } 547 } 548 return true; 549 } 550 551 /// Deferencing (accessing) fields 552 553 /** 554 * collectboolean accepts an object and a list of fields (one of which is of array type, and the 555 * rest of which are not), and produces an array in which the original object has had the given 556 * fields accessed. 557 * 558 * <p>Daikon creates invariants over "variables" such as the following. 559 * 560 * <dl> 561 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 562 * for all y's in array x.arr.</dd> 563 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 564 * for all x's in array arr.</dd> 565 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 566 * </dl> 567 * 568 * <p>The collectboolean() method does this collecting work. 569 * 570 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 571 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 572 * elements that result from following the fields, one of which is assumed to be an array. 573 * 574 * <p> 575 * requires: fieldStr.length() > 0 and object != null 576 * <p> 577 * requires: fieldStr contains only field names, no "[]" strings. 578 * <p> 579 * requires: the method only works for field sequences with exactly one field representing an 580 * array. For example, the collection a[].b[].c will fail. 581 * 582 * @return if the resulting collection is of non-primitive type, then returns an array of type 583 * Object[]. Returns null if any array or field access causes an exception. 584 */ 585 586 @SideEffectFree 587 public static boolean @Nullable [] collectboolean(@Nullable Object object, @Nullable String fieldStr) { 588 589 if (object == null) { 590 return null; 591 } 592 if (fieldStr == null) { 593 return null; 594 } 595 596 // assert fieldStr != null && !"".equals(fieldStr); 597 String[] fieldNames = fieldStr.split("\\."); 598 boolean[] retval = collectboolean(object, fieldNames, 0); 599 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 600 return retval; 601 } 602 603 /** Helper method for collectboolean(Object, String). 604 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 605 * @see collectboolean(Object, String) 606 */ 607 // @PolyNull does not work for return type, because null is returned on error. 608 @SideEffectFree 609 private static boolean @Nullable [] collectboolean(@Nullable Object object, 610 String[] fields, int fieldsStartIdx) { 611 612 if (object == null) { 613 return null; 614 } 615 assert (fields != null); 616 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 617 618 Object fieldObj; 619 try { 620 Field field = (object instanceof java.lang.Class<?>) 621 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 622 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 623 field.setAccessible(true); 624 // Class cls = field.getType(); 625 fieldObj = field.get(object); 626 // System.out.println("***fieldObj="+fieldObj); 627 628 } catch (Exception e) { 629 return null; 630 631 } 632 633 if (fieldObj == null) { 634 return null; 635 } 636 637 // base case: just accessed the last field 638 if (fields.length - 1 == fieldsStartIdx) { 639 640 if (fieldObj.getClass().isArray()) { 641 // last field is an array 642 return (boolean[])fieldObj; 643 } else { 644 // This hack should be removed in favor of, at "oneEltArray = ..." 645 // below, calling a version of collectboolean_field that throws an 646 // error. Then, this case becomes a run-time error. -MDE 647 648 // Just one element; return a one-element array. 649 // assert cls.equals(Boolean.TYPE); 650 return new boolean[] { ((Boolean)fieldObj).booleanValue() }; 651 } 652 } else { 653 // recursive case: more fields to access after this one 654 655 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 656 657 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 658 boolean[] intermediate = new boolean[collection.size()]; 659 int index = 0; 660 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 661 Object obj = i.next(); 662 boolean[] oneEltArray = collectboolean(obj, fields, fieldsStartIdx + 1); 663 if (oneEltArray == null) { 664 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 665 } 666 // assert oneEltArray.length == 1; 667 intermediate[index++] = oneEltArray[0]; 668 } 669 return intermediate; 670 } else if (fieldObj.getClass().isArray()) { 671 672 // collect elements across array 673 boolean[] intermediate = new boolean[Array.getLength(fieldObj)]; 674 for (int i = 0 ; i < intermediate.length ; i++) { 675 Object obj = Array.get(fieldObj, i); 676 boolean[] oneEltArray = collectboolean(obj, fields, fieldsStartIdx + 1); 677 if (oneEltArray == null) { 678 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 679 } 680 // assert oneEltArray.length == 1; 681 intermediate[i] = oneEltArray[0]; 682 } 683 return intermediate; 684 } else { 685 686 return collectboolean(fieldObj, fields, fieldsStartIdx + 1); 687 } 688 } 689 } 690 691 /** 692 * Returns the results of dereferencing the fields for 'object'. For example, the call 693 * 694 * <pre>collectboolean_field(x, "f.g.h")</pre> 695 * 696 * has the same value as 697 * 698 * <pre>x.f.g.h</pre>. 699 * Returns a default value if any field access causes an exception. 700 */ 701 @SideEffectFree 702 public static boolean collectboolean_field(Object object, String fieldStr) { 703 704 if (object == null) { 705 return false; // return default value 706 } 707 if (fieldStr == null) { 708 return false; // return default value 709 } 710 711 String[] fieldNames = fieldStr.split("\\."); 712 713 // Holds the intermediate (and final) result 714 Object fieldObj = object; 715 716 for (int i = 0 ; i < fieldNames.length ; i++) { 717 718 String fieldName = fieldNames[i]; 719 720 try { 721 Field field = 722 (fieldObj instanceof java.lang.Class<?>) 723 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 724 : fieldObj.getClass().getDeclaredField(fieldName); 725 field.setAccessible(true); 726 fieldObj = field.get(fieldObj); 727 728 if (fieldObj == null) { 729 return false; // return default value 730 } 731 732 } catch (Exception e) { 733 return false; // return default value 734 735 } 736 737 } 738 739 return ((Boolean)fieldObj).booleanValue(); 740 } 741 742 /////////////////////////////////////////////////////////////////////////// 743 /// Methods for "byte" (from QuantBody.java.jpp) 744 /// 745 746 /** 747 * Returns the ith element of the array or collection argument. If the argument is null or not an 748 * array or collection, returns a default value (Byte.MAX_VALUE). 749 */ 750 751 @Pure 752 public static byte getElement_byte(Object o, long i) { 753 if (o == null) { 754 return Byte.MAX_VALUE; // return default value 755 } 756 java.lang.Class<?> c = o.getClass(); 757 if (c.isArray()) { 758 return java.lang.reflect.Array.getByte(o, (int)i); 759 } else if (o instanceof java.util.AbstractCollection<?>) { 760 return java.lang.reflect.Array.getByte(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 761 } else { 762 return Byte.MAX_VALUE; // return default value 763 } 764 } 765 766 @Pure 767 public static byte getElement_byte(byte[] arr, long i) { 768 if (arr == null) { 769 return Byte.MAX_VALUE; // return default value 770 } 771 return arr[(int)i]; 772 } 773 774 private static boolean eq(byte x, byte y) { 775 return x == y; 776 } 777 778 private static boolean ne(byte x, byte y) { 779 return x != y; 780 } 781 782 private static boolean lt(byte x, byte y) { 783 return x < y; 784 } 785 786 private static boolean lte(byte x, byte y) { 787 return x <= y; 788 } 789 790 private static boolean gt(byte x, byte y) { 791 return x > y; 792 } 793 794 private static boolean gte(byte x, byte y) { 795 return x >= y; 796 } 797 798 /** True iff both sequences are non-null and have the same length. */ 799 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 800 @Pure 801 public static boolean sameLength(byte @Nullable [] seq1, byte @Nullable [] seq2) { 802 return ((seq1 != null) 803 && (seq2 != null) 804 && seq1.length == seq2.length); 805 } 806 807 /** True iff both sequences are non-null and have the same length. */ 808 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 809 @Pure 810 public static boolean sameLength(byte @Nullable [] seq1, int @Nullable [] seq2) { 811 return ((seq1 != null) 812 && (seq2 != null) 813 && seq1.length == seq2.length); 814 } 815 816 /** True iff both sequences have the same length, and all seq2[i] divide seq1[i]. 817 * 818 * Meaning (in pseudo-FOL): 819 * 820 * <pre> 821 * /\ seq1.length == seq2.length 822 * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i] 823 * </pre> 824 * 825 */ 826 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 827 @Pure 828 public static boolean pairwiseDivides(byte[] seq1, byte[] seq2) { 829 if (!sameLength(seq1, seq2)) { 830 return false; 831 } 832 assert seq1 != null && seq2 != null; // because sameLength() = true 833 for (int i = 0 ; i < seq1.length ; i++) { 834 if (ne(seq1[i] % seq2[i], 0)) { 835 return false; 836 } 837 } 838 return true; 839 } 840 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 841 @Pure 842 public static boolean pairwiseDivides(byte[] seq1, int[] seq2) { 843 if (!sameLength(seq1, seq2)) { 844 return false; 845 } 846 assert seq1 != null && seq2 != null; // because sameLength() = true 847 for (int i = 0 ; i < seq1.length ; i++) { 848 if (ne(seq1[i] % seq2[i], 0)) { 849 return false; 850 } 851 } 852 return true; 853 } 854 855 /** 856 * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i]. 857 * 858 * Meaning (in pseudo-FOL): 859 * 860 * <pre> 861 * /\ seq1.length == seq2.length 862 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i] 863 * </pre> 864 * 865 */ 866 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 867 @Pure 868 public static boolean pairwiseSquare(byte[] seq1, byte[] seq2) { 869 if (!sameLength(seq1, seq2)) { 870 return false; 871 } 872 assert seq1 != null && seq2 != null; // because sameLength() = true 873 for (int i = 0 ; i < seq1.length ; i++) { 874 if (ne(seq1[i], seq2[i] * seq2[i])) { 875 return false; 876 } 877 } 878 return true; 879 } 880 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 881 @Pure 882 public static boolean pairwiseSquare(byte[] seq1, int[] seq2) { 883 if (!sameLength(seq1, seq2)) { 884 return false; 885 } 886 assert seq1 != null && seq2 != null; // because sameLength() = true 887 for (int i = 0 ; i < seq1.length ; i++) { 888 889 if (ne(seq1[i], seq2[i] * seq2[i])) { 890 891 return false; 892 } 893 } 894 return true; 895 } 896 897 /** 898 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 899 * 900 * <p>If either array is null, returns null. If either array is empty, returns only those 901 * elements in the other array. If both arrays are empty, returns a new empty array. 902 */ 903 @SideEffectFree 904 public static byte @PolyNull [] concat(byte @PolyNull [] seq1, byte @PolyNull [] seq2) { 905 if (seq1 == null) { 906 return null; 907 } 908 if (seq2 == null) { 909 return null; 910 } 911 return ArraysPlume.concat(seq1, seq2); 912 } 913 914 @SideEffectFree 915 public static int @PolyNull [] concat(byte @PolyNull [] seq1, int @PolyNull [] seq2) { 916 if (seq1 == null) { 917 return null; 918 } 919 if (seq2 == null) { 920 return null; 921 } 922 // Cannot just use ArraysPlume.concat because the two arrays 923 // have different types. This essentially inlines that method. 924 int newLength = seq1.length + seq2.length; 925 int[] retval = new int[newLength]; 926 927 for (int j = 0 ; j < seq1.length ; j++) { 928 retval[j] = seq1[j]; 929 } 930 System.arraycopy(seq2, 0, retval, seq1.length, seq2.length); 931 932 return retval; 933 } 934 935 /** 936 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 937 * assurances about the order or repetition of elements: elements may be repeated, and their 938 * order may be different from the order of elements in seq1 and seq2. 939 */ 940 @SideEffectFree 941 public static byte @PolyNull [] union(byte @PolyNull [] seq1, byte @PolyNull [] seq2) { 942 if (seq1 == null) { 943 return null; 944 } 945 if (seq2 == null) { 946 return null; 947 } 948 return concat(seq1, seq2); 949 } 950 951 @Pure 952 public static int @PolyNull [] union(byte @PolyNull [] seq1, int @PolyNull [] seq2) { 953 if (seq1 == null) { 954 return null; 955 } 956 if (seq2 == null) { 957 return null; 958 } 959 return concat(seq1, seq2); 960 } 961 962 /** 963 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 964 * gives no assurances about the order or repetition of elements: elements may be repeated, and 965 * their order may be different from the order of elements in seq1 and seq2. 966 */ 967 @Pure 968 public static byte @PolyNull [] intersection(byte @PolyNull [] seq1, byte @PolyNull [] seq2) { 969 if (seq1 == null) { 970 return null; 971 } 972 if (seq2 == null) { 973 return null; 974 } 975 byte[] intermediate = new byte[Math.min(seq1.length, seq2.length)]; 976 int length = 0; 977 for (int i = 0 ; i < seq1.length ; i++) { 978 if (memberOf(seq1[i], seq2) ) { 979 intermediate[length++] = seq1[i]; 980 } 981 } 982 return ArraysPlume.subarray(intermediate, 0, length); 983 } 984 985 @Pure 986 public static int @PolyNull [] intersection(byte @PolyNull [] seq1, int @PolyNull [] seq2) { 987 if (seq1 == null) { 988 return null; 989 } 990 if (seq2 == null) { 991 return null; 992 } 993 int[] intermediate = new int[Math.min(seq1.length, seq2.length)]; 994 int length = 0; 995 for (int i = 0 ; i < seq1.length ; i++) { 996 if (memberOf(seq1[i], seq2) ) { 997 intermediate[length++] = seq1[i]; 998 } 999 } 1000 return ArraysPlume.subarray(intermediate, 0, length); 1001 } 1002 1003 /** 1004 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 1005 * no assurances about the order or repetition of elements: elements may be repeated, and their 1006 * order may be different from the order of elements in seq1 and seq2. 1007 */ 1008 @Pure 1009 public static byte @PolyNull [] setDiff(byte @PolyNull [] seq1, byte @PolyNull [] seq2) { 1010 if (seq1 == null) { 1011 return null; 1012 } 1013 if (seq2 == null) { 1014 return null; 1015 } 1016 byte[] intermediate = new byte[seq1.length]; 1017 int length = 0; 1018 for (int i = 0 ; i < seq1.length ; i++) { 1019 if (!memberOf(seq1[i], seq2)) { 1020 intermediate[length++] = seq1[i]; 1021 } 1022 } 1023 return ArraysPlume.subarray(intermediate, 0, length); 1024 } 1025 1026 @Pure 1027 public static int @PolyNull [] setDiff(byte @PolyNull [] seq1, int @PolyNull [] seq2) { 1028 if (seq1 == null) { 1029 return null; 1030 } 1031 if (seq2 == null) { 1032 return null; 1033 } 1034 int[] intermediate = new int[seq1.length]; 1035 int length = 0; 1036 for (int i = 0 ; i < seq1.length ; i++) { 1037 if (!memberOf(seq1[i], seq2)) { 1038 intermediate[length++] = seq1[i]; 1039 } 1040 } 1041 return ArraysPlume.subarray(intermediate, 0, length); 1042 } 1043 1044 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 1045 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1046 @Pure 1047 public static boolean setEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1048 if (seq1 == null) { 1049 return false; 1050 } 1051 if (seq2 == null) { 1052 return false; 1053 } 1054 for (int i = 0; i < seq1.length ; i++) { 1055 if (!memberOf(seq1[i], seq2) ) { 1056 return false; 1057 } 1058 } 1059 for (int i = 0; i < seq2.length ; i++) { 1060 if (!memberOf(seq2[i], seq1) ) { 1061 return false; 1062 } 1063 } 1064 return true; 1065 } 1066 1067 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1068 @Pure 1069 public static boolean setEqual(byte @Nullable [] seq1, int @Nullable [] seq2) { 1070 if (seq1 == null) { 1071 return false; 1072 } 1073 if (seq2 == null) { 1074 return false; 1075 } 1076 for (int i = 0; i < seq1.length ; i++) { 1077 if (!memberOf(seq1[i], seq2) ) { 1078 return false; 1079 } 1080 } 1081 for (int i = 0; i < seq2.length ; i++) { 1082 if (!memberOf(seq2[i], seq1) ) { 1083 return false; 1084 } 1085 } 1086 return true; 1087 } 1088 1089 /** True iff seq1 is the reverse of seq2. 1090 * 1091 * Meaning (in pseudo-FOL): 1092 * 1093 * <pre> 1094 * /\ seq1.length == seq2.length 1095 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 1096 * </pre> 1097 * 1098 */ 1099 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1100 @Pure 1101 public static boolean isReverse(byte[] seq1, byte[] seq2) { 1102 if (!sameLength(seq1, seq2)) { 1103 return false; 1104 } 1105 assert seq1 != null && seq2 != null; // because sameLength() = true 1106 int length = seq1.length; 1107 for (int i = 0 ; i < length ; i++) { 1108 if (ne(seq1[i], seq2[length - i - 1])) { 1109 return false; 1110 } 1111 } 1112 return true; 1113 } 1114 1115 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1116 @Pure 1117 public static boolean isReverse(byte @Nullable [] seq1, int @Nullable [] seq2) { 1118 if (!sameLength(seq1, seq2)) { 1119 return false; 1120 } 1121 assert seq1 != null && seq2 != null; // because sameLength() = true 1122 int length = seq1.length; 1123 for (int i = 0 ; i < length ; i++) { 1124 if (ne(seq1[i], seq2[length - i - 1])) { 1125 return false; 1126 } 1127 } 1128 return true; 1129 } 1130 1131 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 1132 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1133 @Pure 1134 public static boolean subsetOf(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1135 if (seq1 == null) { 1136 return false; 1137 } 1138 if (seq2 == null) { 1139 return false; 1140 } 1141 for (int i = 0 ; i < seq1.length ; i++) { 1142 if (!memberOf(seq1[i], seq2)) { 1143 return false; 1144 } 1145 } 1146 return true; 1147 } 1148 1149 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1150 @Pure 1151 public static boolean subsetOf(byte @Nullable [] seq1, int @Nullable [] seq2) { 1152 if (seq1 == null) { 1153 return false; 1154 } 1155 if (seq2 == null) { 1156 return false; 1157 } 1158 for (int i = 0 ; i < seq1.length ; i++) { 1159 if (!memberOf(seq1[i], seq2)) { 1160 return false; 1161 } 1162 } 1163 return true; 1164 } 1165 1166 /** Returns true iff seq contains no duplicate elements. */ 1167 @EnsuresNonNullIf(result=true, expression="#1") 1168 @Pure 1169 public static boolean noDups(byte @Nullable [] seq) { 1170 if (seq == null) { 1171 return false; 1172 } 1173 return ArraysPlume.noDuplicates(seq); 1174 } 1175 1176 /** Returns true iff elt is in array arr. */ 1177 @EnsuresNonNullIf(result=true, expression="#2") 1178 @Pure 1179 public static boolean memberOf(byte elt, byte @Nullable [] arr) { 1180 if (arr == null) { 1181 return false; 1182 } 1183 for (int i = 0 ; i < arr.length ; i++) { 1184 if (eq(arr[i], elt)) { 1185 return true; 1186 } 1187 } 1188 return false; 1189 } 1190 1191 @EnsuresNonNullIf(result=true, expression="#2") 1192 @Pure 1193 public static boolean memberOf(byte elt, int @Nullable [] arr) { 1194 if (arr == null) { 1195 return false; 1196 } 1197 for (int i = 0 ; i < arr.length ; i++) { 1198 if (eq(arr[i], elt)) { 1199 return true; 1200 } 1201 } 1202 return false; 1203 } 1204 1205 @EnsuresNonNullIf(result=true, expression="#2") 1206 @Pure 1207 public static boolean memberOf(long elt, byte @Nullable [] arr) { 1208 if (arr == null) { 1209 return false; 1210 } 1211 for (int i = 0 ; i < arr.length ; i++) { 1212 if (eq(arr[i], elt)) { 1213 return true; 1214 } 1215 } 1216 return false; 1217 } 1218 1219 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 1220 @Pure 1221 public static byte @PolyNull [] slice(byte @PolyNull [] seq, int start, int end) { 1222 if (seq == null) { 1223 return null; 1224 } 1225 int sliceStart = start; 1226 int sliceEnd = end; 1227 if (start < 0) { 1228 return new byte[] { }; 1229 } 1230 if (end > seq.length - 1) { 1231 return new byte[] { }; 1232 } 1233 if (sliceStart > sliceEnd) { 1234 return new byte[] { }; 1235 } 1236 int length = sliceEnd - sliceStart + 1; 1237 return ArraysPlume.subarray(seq, sliceStart, length); 1238 } 1239 1240 @Pure 1241 public static byte @PolyNull [] slice(byte @PolyNull [] seq, long start, int end) { 1242 return slice(seq, (int)start, end); 1243 } 1244 @Pure 1245 public static byte @PolyNull [] slice(byte @PolyNull [] seq, int start, long end) { 1246 return slice(seq, start, (int)end); 1247 } 1248 @Pure 1249 public static byte @PolyNull [] slice(byte @PolyNull [] seq, long start, long end) { 1250 return slice(seq, (int)start, (int)end); 1251 } 1252 1253 /** True iff all elements in arr equal elt. 1254 * 1255 * Meaning (in pseudo-FOL): 1256 * 1257 * forall i in { 0..arr.length-1 } : arr[i] == elt 1258 * 1259 */ 1260 @EnsuresNonNullIf(result=true, expression="#1") 1261 @Pure 1262 public static boolean eltsEqual(byte @Nullable [] arr, byte elt) { 1263 if (arr == null) { 1264 return false; 1265 } 1266 for (int i = 0 ; i < arr.length ; i++) { 1267 if (ne(arr[i], elt)) { 1268 return false; 1269 } 1270 } 1271 return true; 1272 } 1273 1274 @EnsuresNonNullIf(result=true, expression="#1") 1275 @Pure 1276 public static boolean eltsEqual(byte @Nullable [] arr, int elt) { 1277 if (arr == null) { 1278 return false; 1279 } 1280 for (int i = 0 ; i < arr.length ; i++) { 1281 if (ne(arr[i], elt)) { 1282 return false; 1283 } 1284 } 1285 return true; 1286 } 1287 1288 /** True iff every element in arr does not equal elt. 1289 * 1290 * Meaning (in pseudo-FOL): 1291 * 1292 * forall i in { 0..arr.length-1 } : arr[i] != elt 1293 * 1294 */ 1295 @EnsuresNonNullIf(result=true, expression="#1") 1296 @Pure 1297 public static boolean eltsNotEqual(byte @Nullable [] arr, byte elt) { 1298 if (arr == null) { 1299 return false; 1300 } 1301 for (int i = 0 ; i < arr.length ; i++) { 1302 if (eq(arr[i], elt)) { 1303 return false; 1304 } 1305 } 1306 return true; 1307 } 1308 1309 @EnsuresNonNullIf(result=true, expression="#1") 1310 @Pure 1311 public static boolean eltsNotEqual(byte @Nullable [] arr, int elt) { 1312 if (arr == null) { 1313 return false; 1314 } 1315 for (int i = 0 ; i < arr.length ; i++) { 1316 if (eq(arr[i], elt)) { 1317 return false; 1318 } 1319 } 1320 return true; 1321 } 1322 1323 /** True iff every element in arr is greater than elt. 1324 * 1325 * Meaning (in pseudo-FOL): 1326 * 1327 * forall i in { 0..arr.length-1 } : arr[i] > elt 1328 * 1329 */ 1330 @EnsuresNonNullIf(result=true, expression="#1") 1331 @Pure 1332 public static boolean eltsGT(byte @Nullable [] arr, byte elt) { 1333 if (arr == null) { 1334 return false; 1335 } 1336 for (int i = 0 ; i < arr.length ; i++) { 1337 if (lte(arr[i], elt)) { 1338 return false; 1339 } 1340 } 1341 return true; 1342 } 1343 1344 @EnsuresNonNullIf(result=true, expression="#1") 1345 @Pure 1346 public static boolean eltsGT(byte @Nullable [] arr, int elt) { 1347 if (arr == null) { 1348 return false; 1349 } 1350 for (int i = 0 ; i < arr.length ; i++) { 1351 if (lte(arr[i], elt)) { 1352 return false; 1353 } 1354 } 1355 return true; 1356 } 1357 1358 /** True iff every element in arr is greater than or equal to elt. 1359 * 1360 * Meaning (in pseudo-FOL): 1361 * 1362 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 1363 * 1364 */ 1365 @EnsuresNonNullIf(result=true, expression="#1") 1366 @Pure 1367 public static boolean eltsGTE(byte @Nullable [] arr, byte elt) { 1368 if (arr == null) { 1369 return false; 1370 } 1371 for (int i = 0 ; i < arr.length ; i++) { 1372 if (lt(arr[i], elt)) { 1373 return false; 1374 } 1375 } 1376 return true; 1377 } 1378 1379 @EnsuresNonNullIf(result=true, expression="#1") 1380 @Pure 1381 public static boolean eltsGTE(byte @Nullable [] arr, int elt) { 1382 if (arr == null) { 1383 return false; 1384 } 1385 for (int i = 0 ; i < arr.length ; i++) { 1386 if (lt(arr[i], elt)) { 1387 return false; 1388 } 1389 } 1390 return true; 1391 } 1392 1393 /** True iff every element in arr is less than elt. 1394 * 1395 * Meaning (in pseudo-FOL): 1396 * 1397 * forall i in { 0..arr.length-1 } : arr[i] < elt 1398 * 1399 */ 1400 @EnsuresNonNullIf(result=true, expression="#1") 1401 @Pure 1402 public static boolean eltsLT(byte @Nullable [] arr, byte elt) { 1403 if (arr == null) { 1404 return false; 1405 } 1406 for (int i = 0 ; i < arr.length ; i++) { 1407 if (gte(arr[i], elt)) { 1408 return false; 1409 } 1410 } 1411 return true; 1412 } 1413 1414 @EnsuresNonNullIf(result=true, expression="#1") 1415 @Pure 1416 public static boolean eltsLT(byte @Nullable [] arr, int elt) { 1417 if (arr == null) { 1418 return false; 1419 } 1420 for (int i = 0 ; i < arr.length ; i++) { 1421 if (gte(arr[i], elt)) { 1422 return false; 1423 } 1424 } 1425 return true; 1426 } 1427 1428 /** True iff every element in arr is less than or equal to elt. 1429 * 1430 * Meaning (in pseudo-FOL): 1431 * 1432 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 1433 * 1434 */ 1435 @EnsuresNonNullIf(result=true, expression="#1") 1436 @Pure 1437 public static boolean eltsLTE(byte @Nullable [] arr, byte elt) { 1438 if (arr == null) { 1439 return false; 1440 } 1441 for (int i = 0 ; i < arr.length ; i++) { 1442 if (gt(arr[i], elt)) { 1443 return false; 1444 } 1445 } 1446 return true; 1447 } 1448 1449 @EnsuresNonNullIf(result=true, expression="#1") 1450 @Pure 1451 public static boolean eltsLTE(byte @Nullable [] arr, int elt) { 1452 if (arr == null) { 1453 return false; 1454 } 1455 for (int i = 0 ; i < arr.length ; i++) { 1456 if (gt(arr[i], elt)) { 1457 return false; 1458 } 1459 } 1460 return true; 1461 } 1462 1463 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 1464 * 1465 * Meaning (in pseudo-FOL): 1466 * 1467 * /\ seq1.length == se2.length 1468 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 1469 * 1470 */ 1471 1472 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1473 @Pure 1474 public static boolean pairwiseEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1475 if (!sameLength(seq1, seq2)) { 1476 return false; 1477 } 1478 assert seq1 != null && seq2 != null; // because sameLength() = true 1479 for (int i = 0 ; i < seq1.length ; i++) { 1480 if (ne(seq1[i], seq2[i])) { 1481 return false; 1482 } 1483 } 1484 return true; 1485 } 1486 1487 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1488 @Pure 1489 public static boolean pairwiseEqual(byte @Nullable [] seq1, int @Nullable [] seq2) { 1490 if (!sameLength(seq1, seq2)) { 1491 return false; 1492 } 1493 assert seq1 != null && seq2 != null; // because sameLength() = true 1494 for (int i = 0 ; i < seq1.length ; i++) { 1495 if (ne(seq1[i], seq2[i])) { 1496 return false; 1497 } 1498 } 1499 return true; 1500 } 1501 1502 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 1503 * 1504 * Meaning (in pseudo-FOL): 1505 * 1506 * /\ seq1.length == se2.length 1507 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 1508 * 1509 */ 1510 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1511 @Pure 1512 public static boolean pairwiseNotEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1513 if (!sameLength(seq1, seq2)) { 1514 return false; 1515 } 1516 assert seq1 != null && seq2 != null; // because sameLength() = true 1517 for (int i = 0 ; i < seq1.length ; i++) { 1518 if (eq(seq1[i], seq2[i])) { 1519 return false; 1520 } 1521 } 1522 return true; 1523 } 1524 1525 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1526 @Pure 1527 public static boolean pairwiseNotEqual(byte @Nullable [] seq1, int @Nullable [] seq2) { 1528 if (!sameLength(seq1, seq2)) { 1529 return false; 1530 } 1531 assert seq1 != null && seq2 != null; // because sameLength() = true 1532 for (int i = 0 ; i < seq1.length ; i++) { 1533 if (eq(seq1[i], seq2[i])) { 1534 return false; 1535 } 1536 } 1537 return true; 1538 } 1539 1540 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 1541 * 1542 * Meaning (in pseudo-FOL): 1543 * 1544 * /\ seq1.length == se2.length 1545 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 1546 * 1547 */ 1548 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1549 @Pure 1550 public static boolean pairwiseLT(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1551 if (!sameLength(seq1, seq2)) { 1552 return false; 1553 } 1554 assert seq1 != null && seq2 != null; // because sameLength() = true 1555 for (int i = 0 ; i < seq1.length ; i++) { 1556 if (gte(seq1[i], seq2[i])) { 1557 return false; 1558 } 1559 } 1560 return true; 1561 } 1562 1563 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1564 @Pure 1565 public static boolean pairwiseLT(byte @Nullable [] seq1, int @Nullable [] seq2) { 1566 if (!sameLength(seq1, seq2)) { 1567 return false; 1568 } 1569 assert seq1 != null && seq2 != null; // because sameLength() = true 1570 for (int i = 0 ; i < seq1.length ; i++) { 1571 if (gte(seq1[i], seq2[i])) { 1572 return false; 1573 } 1574 } 1575 return true; 1576 } 1577 1578 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 1579 * Meaning (in pseudo-FOL): 1580 * 1581 * /\ seq1.length == se2.length 1582 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 1583 * 1584 */ 1585 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1586 @Pure 1587 public static boolean pairwiseLTE(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1588 if (!sameLength(seq1, seq2)) { 1589 return false; 1590 } 1591 assert seq1 != null && seq2 != null; // because sameLength() = true 1592 for (int i = 0 ; i < seq1.length ; i++) { 1593 if (gt(seq1[i], seq2[i])) { 1594 return false; 1595 } 1596 } 1597 return true; 1598 } 1599 1600 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1601 @Pure 1602 public static boolean pairwiseLTE(byte @Nullable [] seq1, int @Nullable [] seq2) { 1603 if (!sameLength(seq1, seq2)) { 1604 return false; 1605 } 1606 assert seq1 != null && seq2 != null; // because sameLength() = true 1607 for (int i = 0 ; i < seq1.length ; i++) { 1608 if (gt(seq1[i], seq2[i])) { 1609 return false; 1610 } 1611 } 1612 return true; 1613 } 1614 1615 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 1616 * Meaning (in pseudo-FOL): 1617 * 1618 * /\ seq1.length == se2.length 1619 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 1620 * 1621 */ 1622 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1623 @Pure 1624 public static boolean pairwiseGT(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1625 if (!sameLength(seq1, seq2)) { 1626 return false; 1627 } 1628 assert seq1 != null && seq2 != null; // because sameLength() = true 1629 for (int i = 0 ; i < seq1.length ; i++) { 1630 if (lte(seq1[i], seq2[i])) { 1631 return false; 1632 } 1633 } 1634 return true; 1635 } 1636 1637 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1638 @Pure 1639 public static boolean pairwiseGT(byte @Nullable [] seq1, int @Nullable [] seq2) { 1640 if (!sameLength(seq1, seq2)) { 1641 return false; 1642 } 1643 assert seq1 != null && seq2 != null; // because sameLength() = true 1644 for (int i = 0 ; i < seq1.length ; i++) { 1645 if (lte(seq1[i], seq2[i])) { 1646 return false; 1647 } 1648 } 1649 return true; 1650 } 1651 1652 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 1653 * Meaning (in pseudo-FOL): 1654 * 1655 * /\ seq1.length == se2.length 1656 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 1657 * 1658 */ 1659 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1660 @Pure 1661 public static boolean pairwiseGTE(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1662 if (!sameLength(seq1, seq2)) { 1663 return false; 1664 } 1665 assert seq1 != null && seq2 != null; // because sameLength() = true 1666 for (int i = 0 ; i < seq1.length ; i++) { 1667 if (lt(seq1[i], seq2[i])) { 1668 return false; 1669 } 1670 } 1671 return true; 1672 } 1673 1674 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1675 @Pure 1676 public static boolean pairwiseGTE(byte @Nullable [] seq1, int @Nullable [] seq2) { 1677 if (!sameLength(seq1, seq2)) { 1678 return false; 1679 } 1680 assert seq1 != null && seq2 != null; // because sameLength() = true 1681 for (int i = 0 ; i < seq1.length ; i++) { 1682 if (lt(seq1[i], seq2[i])) { 1683 return false; 1684 } 1685 } 1686 return true; 1687 } 1688 1689 /** 1690 * Returns true iff seq1 is lexically equal to seq2. 1691 * For equality, "lexically" and "pairwise" are the same. 1692 */ 1693 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1694 @Pure 1695 public static boolean lexEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1696 if (seq1 == null) { 1697 return false; 1698 } 1699 if (seq2 == null) { 1700 return false; 1701 } 1702 return pairwiseEqual(seq1, seq2); 1703 } 1704 1705 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1706 @Pure 1707 public static boolean lexEqual(byte @Nullable [] seq1, int @Nullable [] seq2) { 1708 if (seq1 == null) { 1709 return false; 1710 } 1711 if (seq2 == null) { 1712 return false; 1713 } 1714 return pairwiseEqual(seq1, seq2); 1715 } 1716 1717 /** Returns true iff seq1 is lexically not equal to seq2. */ 1718 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1719 @Pure 1720 public static boolean lexNotEqual(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1721 if (seq1 == null) { 1722 return false; 1723 } 1724 if (seq2 == null) { 1725 return false; 1726 } 1727 return !lexEqual(seq1, seq2); 1728 } 1729 1730 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1731 @Pure 1732 public static boolean lexNotEqual(byte @Nullable [] seq1, int @Nullable [] seq2) { 1733 if (seq1 == null) { 1734 return false; 1735 } 1736 if (seq2 == null) { 1737 return false; 1738 } 1739 return !lexEqual(seq1, seq2); 1740 } 1741 1742 /** Returns true iff seq1 is lexically < seq2. */ 1743 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1744 @Pure 1745 public static boolean lexLT(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1746 if (seq1 == null) { 1747 return false; 1748 } 1749 if (seq2 == null) { 1750 return false; 1751 } 1752 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1753 for (int i = 0 ; i < minlength ; i++) { 1754 if (gt(seq1[i], seq2[i])) { 1755 return false; 1756 } else if (lt(seq1[i], seq2[i])) { 1757 return true; 1758 } 1759 } 1760 if (seq1.length >= seq2.length) { 1761 return false; 1762 } 1763 return true; 1764 } 1765 1766 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1767 @Pure 1768 public static boolean lexLT(byte @Nullable [] seq1, int @Nullable [] seq2) { 1769 if (seq1 == null) { 1770 return false; 1771 } 1772 if (seq2 == null) { 1773 return false; 1774 } 1775 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1776 for (int i = 0 ; i < minlength ; i++) { 1777 if (gt(seq1[i], seq2[i])) { 1778 return false; 1779 } else if (lt(seq1[i], seq2[i])) { 1780 return true; 1781 } 1782 } 1783 if (seq1.length >= seq2.length) { 1784 return false; 1785 } 1786 return true; 1787 } 1788 1789 /** Returns true iff seq1 is lexically ≤ to seq2. */ 1790 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1791 @Pure 1792 public static boolean lexLTE(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1793 if (seq1 == null) { 1794 return false; 1795 } 1796 if (seq2 == null) { 1797 return false; 1798 } 1799 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1800 for (int i = 0 ; i < minlength ; i++) { 1801 if (gt(seq1[i], seq2[i])) { 1802 return false; 1803 } else if (lt(seq1[i], seq2[i])) { 1804 return true; 1805 } 1806 } 1807 if (seq1.length > seq2.length) { 1808 return false; 1809 } 1810 return true; 1811 } 1812 1813 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1814 @Pure 1815 public static boolean lexLTE(byte @Nullable [] seq1, int @Nullable [] seq2) { 1816 if (seq1 == null) { 1817 return false; 1818 } 1819 if (seq2 == null) { 1820 return false; 1821 } 1822 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1823 for (int i = 0 ; i < minlength ; i++) { 1824 if (gt(seq1[i], seq2[i])) { 1825 return false; 1826 } else if (lt(seq1[i], seq2[i])) { 1827 return true; 1828 } 1829 } 1830 if (seq1.length > seq2.length) { 1831 return false; 1832 } 1833 return true; 1834 } 1835 1836 /** Returns true iff seq1 is lexically > to seq2. */ 1837 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1838 @Pure 1839 public static boolean lexGT(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1840 if (seq1 == null) { 1841 return false; 1842 } 1843 if (seq2 == null) { 1844 return false; 1845 } 1846 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1847 for (int i = 0 ; i < minlength ; i++) { 1848 if (lt(seq1[i], seq2[i])) { 1849 return false; 1850 } else if (gt(seq1[i], seq2[i])) { 1851 return true; 1852 } 1853 } 1854 if (seq1.length <= seq2.length) { 1855 return false; 1856 } 1857 return true; 1858 } 1859 1860 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1861 @Pure 1862 public static boolean lexGT(byte @Nullable [] seq1, int @Nullable [] seq2) { 1863 if (seq1 == null) { 1864 return false; 1865 } 1866 if (seq2 == null) { 1867 return false; 1868 } 1869 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1870 for (int i = 0 ; i < minlength ; i++) { 1871 if (lt(seq1[i], seq2[i])) { 1872 return false; 1873 } else if (gt(seq1[i], seq2[i])) { 1874 return true; 1875 } 1876 } 1877 if (seq1.length <= seq2.length) { 1878 return false; 1879 } 1880 return true; 1881 } 1882 1883 /** Returns true iff seq1 is lexically ≥ to seq2. */ 1884 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1885 @Pure 1886 public static boolean lexGTE(byte @Nullable [] seq1, byte @Nullable [] seq2) { 1887 if (seq1 == null) { 1888 return false; 1889 } 1890 if (seq2 == null) { 1891 return false; 1892 } 1893 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1894 for (int i = 0 ; i < minlength ; i++) { 1895 if (lt(seq1[i], seq2[i])) { 1896 return false; 1897 } else if (gt(seq1[i], seq2[i])) { 1898 return true; 1899 } 1900 } 1901 if (seq1.length < seq2.length) { 1902 return false; 1903 } 1904 return true; 1905 } 1906 1907 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 1908 @Pure 1909 public static boolean lexGTE(byte @Nullable [] seq1, int @Nullable [] seq2) { 1910 if (seq1 == null) { 1911 return false; 1912 } 1913 if (seq2 == null) { 1914 return false; 1915 } 1916 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 1917 for (int i = 0 ; i < minlength ; i++) { 1918 if (lt(seq1[i], seq2[i])) { 1919 return false; 1920 } else if (gt(seq1[i], seq2[i])) { 1921 return true; 1922 } 1923 } 1924 if (seq1.length < seq2.length) { 1925 return false; 1926 } 1927 return true; 1928 } 1929 1930 /** True iff for all applicable i, every seq[i] == seq[i+1]. 1931 * 1932 * Meaning (in pseudo-FOL): 1933 * 1934 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 1935 * 1936 */ 1937 @EnsuresNonNullIf(result=true, expression="#1") 1938 @Pure 1939 public static boolean eltwiseEqual(byte @Nullable [] seq) { 1940 if (seq == null) { 1941 return false; 1942 } 1943 for (int i = 0 ; i < seq.length ; i++) { 1944 if (i < seq.length - 1) { 1945 if (ne(seq[i], seq[i + 1])) { 1946 return false; 1947 } 1948 } 1949 } 1950 return true; 1951 } 1952 1953 /** True iff for all applicable i, every seq[i] != seq[i+1]. 1954 * 1955 * Meaning (in pseudo-FOL): 1956 * 1957 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 1958 * 1959 */ 1960 @EnsuresNonNullIf(result=true, expression="#1") 1961 @Pure 1962 public static boolean eltwiseNotEqual(byte @Nullable [] seq) { 1963 if (seq == null) { 1964 return false; 1965 } 1966 for (int i = 0 ; i < seq.length ; i++) { 1967 if (i < seq.length - 1) { 1968 if (eq(seq[i], seq[i + 1])) { 1969 return false; 1970 } 1971 } 1972 } 1973 return true; 1974 } 1975 1976 /** True iff for all applicable i, every seq[i] < seq[i+1]. 1977 * 1978 * Meaning (in pseudo-FOL): 1979 * 1980 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 1981 * 1982 */ 1983 @EnsuresNonNullIf(result=true, expression="#1") 1984 @Pure 1985 public static boolean eltwiseLT(byte @Nullable [] seq) { 1986 if (seq == null) { 1987 return false; 1988 } 1989 for (int i = 0 ; i < seq.length ; i++) { 1990 if (i < seq.length - 1) { 1991 if (gte(seq[i], seq[i + 1])) { 1992 return false; 1993 } 1994 } 1995 } 1996 return true; 1997 } 1998 1999 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 2000 * 2001 * Meaning (in pseudo-FOL): 2002 * 2003 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 2004 * 2005 */ 2006 @EnsuresNonNullIf(result=true, expression="#1") 2007 @Pure 2008 public static boolean eltwiseLTE(byte @Nullable [] seq) { 2009 if (seq == null) { 2010 return false; 2011 } 2012 for (int i = 0 ; i < seq.length ; i++) { 2013 if (i < seq.length - 1) { 2014 if (gt(seq[i], seq[i + 1])) { 2015 return false; 2016 } 2017 } 2018 } 2019 return true; 2020 } 2021 2022 /** True iff for all applicable i, every seq[i] > seq[i+1]. 2023 * 2024 * Meaning (in pseudo-FOL): 2025 * 2026 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 2027 * 2028 */ 2029 @EnsuresNonNullIf(result=true, expression="#1") 2030 @Pure 2031 public static boolean eltwiseGT(byte @Nullable [] seq) { 2032 if (seq == null) { 2033 return false; 2034 } 2035 for (int i = 0 ; i < seq.length ; i++) { 2036 if (i < seq.length - 1) { 2037 if (lte(seq[i], seq[i + 1])) { 2038 return false; 2039 } 2040 } 2041 } 2042 return true; 2043 } 2044 2045 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 2046 * 2047 * Meaning (in pseudo-FOL): 2048 * 2049 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 2050 * 2051 */ 2052 @EnsuresNonNullIf(result=true, expression="#1") 2053 @Pure 2054 public static boolean eltwiseGTE(byte @Nullable [] seq) { 2055 if (seq == null) { 2056 return false; 2057 } 2058 for (int i = 0 ; i < seq.length ; i++) { 2059 if (i < seq.length - 1) { 2060 if (lt(seq[i], seq[i + 1])) { 2061 return false; 2062 } 2063 } 2064 } 2065 return true; 2066 } 2067 2068 /** True iff for all applicable i, every seq[i] == i. 2069 * 2070 * Meaning (in pseudo-FOL): 2071 * 2072 * forall i in { 0..seq.length-1 } : seq[i] == i 2073 * 2074 */ 2075 @EnsuresNonNullIf(result=true, expression="#1") 2076 @Pure 2077 public static boolean eltsEqualIndex(byte @Nullable [] seq) { 2078 if (seq == null) { 2079 return false; 2080 } 2081 for (int i = 0 ; i < seq.length ; i++) { 2082 if (ne(seq[i], i)) { 2083 return false; 2084 } 2085 } 2086 return true; 2087 } 2088 2089 /** True iff for all applicable i, every seq[i] != i. 2090 * 2091 * Meaning (in pseudo-FOL): 2092 * 2093 * forall i in { 0..seq.length-1 } : seq[i] != i 2094 * 2095 */ 2096 @EnsuresNonNullIf(result=true, expression="#1") 2097 @Pure 2098 public static boolean eltsNotEqualIndex(byte @Nullable [] seq) { 2099 if (seq == null) { 2100 return false; 2101 } 2102 for (int i = 0 ; i < seq.length ; i++) { 2103 if (eq(seq[i], i)) { 2104 return false; 2105 } 2106 } 2107 return true; 2108 } 2109 2110 /** True iff for all applicable i, every seq[i] < i. 2111 * 2112 * Meaning (in pseudo-FOL): 2113 * 2114 * forall i in { 0..seq.length-1 } : seq[i] < i 2115 * 2116 */ 2117 @EnsuresNonNullIf(result=true, expression="#1") 2118 @Pure 2119 public static boolean eltsLtIndex(byte @Nullable [] seq) { 2120 if (seq == null) { 2121 return false; 2122 } 2123 for (int i = 0 ; i < seq.length ; i++) { 2124 if (gte(seq[i], i)) { 2125 return false; 2126 } 2127 } 2128 return true; 2129 } 2130 2131 /** True iff for all applicable i, every seq[i] ≤ i. 2132 * 2133 * Meaning (in pseudo-FOL): 2134 * 2135 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 2136 * 2137 */ 2138 @EnsuresNonNullIf(result=true, expression="#1") 2139 @Pure 2140 public static boolean eltsLteIndex(byte @Nullable [] seq) { 2141 if (seq == null) { 2142 return false; 2143 } 2144 for (int i = 0 ; i < seq.length ; i++) { 2145 if (gt(seq[i], i)) { 2146 return false; 2147 } 2148 } 2149 return true; 2150 } 2151 2152 /** True iff for all applicable i, every seq[i] > i. 2153 * 2154 * Meaning (in pseudo-FOL): 2155 * 2156 * forall i in { 0..seq.length-1 } : seq[i] > i 2157 * 2158 */ 2159 @EnsuresNonNullIf(result=true, expression="#1") 2160 @Pure 2161 public static boolean eltsGtIndex(byte @Nullable [] seq) { 2162 if (seq == null) { 2163 return false; 2164 } 2165 for (int i = 0 ; i < seq.length ; i++) { 2166 if (lte(seq[i], i)) { 2167 return false; 2168 } 2169 } 2170 return true; 2171 } 2172 2173 /** True iff for all applicable i, every seq[i] ≥ i. 2174 * 2175 * Meaning (in pseudo-FOL): 2176 * 2177 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 2178 * 2179 */ 2180 @EnsuresNonNullIf(result=true, expression="#1") 2181 @Pure 2182 public static boolean eltsGteIndex(byte @Nullable [] seq) { 2183 if (seq == null) { 2184 return false; 2185 } 2186 for (int i = 0 ; i < seq.length ; i++) { 2187 if (lt(seq[i], i)) { 2188 return false; 2189 } 2190 } 2191 return true; 2192 } 2193 2194 /// Deferencing (accessing) fields 2195 2196 /** 2197 * collectbyte accepts an object and a list of fields (one of which is of array type, and the 2198 * rest of which are not), and produces an array in which the original object has had the given 2199 * fields accessed. 2200 * 2201 * <p>Daikon creates invariants over "variables" such as the following. 2202 * 2203 * <dl> 2204 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 2205 * for all y's in array x.arr.</dd> 2206 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 2207 * for all x's in array arr.</dd> 2208 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 2209 * </dl> 2210 * 2211 * <p>The collectbyte() method does this collecting work. 2212 * 2213 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 2214 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 2215 * elements that result from following the fields, one of which is assumed to be an array. 2216 * 2217 * <p> 2218 * requires: fieldStr.length() > 0 and object != null 2219 * <p> 2220 * requires: fieldStr contains only field names, no "[]" strings. 2221 * <p> 2222 * requires: the method only works for field sequences with exactly one field representing an 2223 * array. For example, the collection a[].b[].c will fail. 2224 * 2225 * @return if the resulting collection is of non-primitive type, then returns an array of type 2226 * Object[]. Returns null if any array or field access causes an exception. 2227 */ 2228 2229 @SideEffectFree 2230 public static byte @Nullable [] collectbyte(@Nullable Object object, @Nullable String fieldStr) { 2231 2232 if (object == null) { 2233 return null; 2234 } 2235 if (fieldStr == null) { 2236 return null; 2237 } 2238 2239 // assert fieldStr != null && !"".equals(fieldStr); 2240 String[] fieldNames = fieldStr.split("\\."); 2241 byte[] retval = collectbyte(object, fieldNames, 0); 2242 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 2243 return retval; 2244 } 2245 2246 /** Helper method for collectbyte(Object, String). 2247 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 2248 * @see collectbyte(Object, String) 2249 */ 2250 // @PolyNull does not work for return type, because null is returned on error. 2251 @SideEffectFree 2252 private static byte @Nullable [] collectbyte(@Nullable Object object, 2253 String[] fields, int fieldsStartIdx) { 2254 2255 if (object == null) { 2256 return null; 2257 } 2258 assert (fields != null); 2259 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 2260 2261 Object fieldObj; 2262 try { 2263 Field field = (object instanceof java.lang.Class<?>) 2264 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 2265 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 2266 field.setAccessible(true); 2267 // Class cls = field.getType(); 2268 fieldObj = field.get(object); 2269 // System.out.println("***fieldObj="+fieldObj); 2270 2271 } catch (Exception e) { 2272 return null; 2273 2274 } 2275 2276 if (fieldObj == null) { 2277 return null; 2278 } 2279 2280 // base case: just accessed the last field 2281 if (fields.length - 1 == fieldsStartIdx) { 2282 2283 if (fieldObj.getClass().isArray()) { 2284 // last field is an array 2285 return (byte[])fieldObj; 2286 } else { 2287 // This hack should be removed in favor of, at "oneEltArray = ..." 2288 // below, calling a version of collectbyte_field that throws an 2289 // error. Then, this case becomes a run-time error. -MDE 2290 2291 // Just one element; return a one-element array. 2292 // assert cls.equals(Byte.TYPE); 2293 return new byte[] { ((Byte)fieldObj).byteValue() }; 2294 } 2295 } else { 2296 // recursive case: more fields to access after this one 2297 2298 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 2299 2300 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 2301 byte[] intermediate = new byte[collection.size()]; 2302 int index = 0; 2303 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 2304 Object obj = i.next(); 2305 byte[] oneEltArray = collectbyte(obj, fields, fieldsStartIdx + 1); 2306 if (oneEltArray == null) { 2307 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 2308 } 2309 // assert oneEltArray.length == 1; 2310 intermediate[index++] = oneEltArray[0]; 2311 } 2312 return intermediate; 2313 } else if (fieldObj.getClass().isArray()) { 2314 2315 // collect elements across array 2316 byte[] intermediate = new byte[Array.getLength(fieldObj)]; 2317 for (int i = 0 ; i < intermediate.length ; i++) { 2318 Object obj = Array.get(fieldObj, i); 2319 byte[] oneEltArray = collectbyte(obj, fields, fieldsStartIdx + 1); 2320 if (oneEltArray == null) { 2321 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 2322 } 2323 // assert oneEltArray.length == 1; 2324 intermediate[i] = oneEltArray[0]; 2325 } 2326 return intermediate; 2327 } else { 2328 2329 return collectbyte(fieldObj, fields, fieldsStartIdx + 1); 2330 } 2331 } 2332 } 2333 2334 /** 2335 * Returns the results of dereferencing the fields for 'object'. For example, the call 2336 * 2337 * <pre>collectbyte_field(x, "f.g.h")</pre> 2338 * 2339 * has the same value as 2340 * 2341 * <pre>x.f.g.h</pre>. 2342 * Returns a default value if any field access causes an exception. 2343 */ 2344 @SideEffectFree 2345 public static byte collectbyte_field(Object object, String fieldStr) { 2346 2347 if (object == null) { 2348 return Byte.MAX_VALUE; // return default value 2349 } 2350 if (fieldStr == null) { 2351 return Byte.MAX_VALUE; // return default value 2352 } 2353 2354 String[] fieldNames = fieldStr.split("\\."); 2355 2356 // Holds the intermediate (and final) result 2357 Object fieldObj = object; 2358 2359 for (int i = 0 ; i < fieldNames.length ; i++) { 2360 2361 String fieldName = fieldNames[i]; 2362 2363 try { 2364 Field field = 2365 (fieldObj instanceof java.lang.Class<?>) 2366 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 2367 : fieldObj.getClass().getDeclaredField(fieldName); 2368 field.setAccessible(true); 2369 fieldObj = field.get(fieldObj); 2370 2371 if (fieldObj == null) { 2372 return Byte.MAX_VALUE; // return default value 2373 } 2374 2375 } catch (Exception e) { 2376 return Byte.MAX_VALUE; // return default value 2377 2378 } 2379 2380 } 2381 2382 return ((Byte)fieldObj).byteValue(); 2383 } 2384 2385 /////////////////////////////////////////////////////////////////////////// 2386 /// Methods for "char" (from QuantBody.java.jpp) 2387 /// 2388 2389 /** 2390 * Returns the ith element of the array or collection argument. If the argument is null or not an 2391 * array or collection, returns a default value (Character.MAX_VALUE). 2392 */ 2393 2394 @Pure 2395 public static char getElement_char(Object o, long i) { 2396 if (o == null) { 2397 return Character.MAX_VALUE; // return default value 2398 } 2399 java.lang.Class<?> c = o.getClass(); 2400 if (c.isArray()) { 2401 return java.lang.reflect.Array.getChar(o, (int)i); 2402 } else if (o instanceof java.util.AbstractCollection<?>) { 2403 return java.lang.reflect.Array.getChar(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 2404 } else { 2405 return Character.MAX_VALUE; // return default value 2406 } 2407 } 2408 2409 @Pure 2410 public static char getElement_char(char[] arr, long i) { 2411 if (arr == null) { 2412 return Character.MAX_VALUE; // return default value 2413 } 2414 return arr[(int)i]; 2415 } 2416 2417 private static boolean eq(char x, char y) { 2418 return x == y; 2419 } 2420 2421 private static boolean ne(char x, char y) { 2422 return x != y; 2423 } 2424 2425 private static boolean lt(char x, char y) { 2426 return x < y; 2427 } 2428 2429 private static boolean lte(char x, char y) { 2430 return x <= y; 2431 } 2432 2433 private static boolean gt(char x, char y) { 2434 return x > y; 2435 } 2436 2437 private static boolean gte(char x, char y) { 2438 return x >= y; 2439 } 2440 2441 /** True iff both sequences are non-null and have the same length. */ 2442 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 2443 @Pure 2444 public static boolean sameLength(char @Nullable [] seq1, char @Nullable [] seq2) { 2445 return ((seq1 != null) 2446 && (seq2 != null) 2447 && seq1.length == seq2.length); 2448 } 2449 2450 /** 2451 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 2452 * 2453 * <p>If either array is null, returns null. If either array is empty, returns only those 2454 * elements in the other array. If both arrays are empty, returns a new empty array. 2455 */ 2456 @SideEffectFree 2457 public static char @PolyNull [] concat(char @PolyNull [] seq1, char @PolyNull [] seq2) { 2458 if (seq1 == null) { 2459 return null; 2460 } 2461 if (seq2 == null) { 2462 return null; 2463 } 2464 return ArraysPlume.concat(seq1, seq2); 2465 } 2466 2467 /** 2468 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 2469 * assurances about the order or repetition of elements: elements may be repeated, and their 2470 * order may be different from the order of elements in seq1 and seq2. 2471 */ 2472 @SideEffectFree 2473 public static char @PolyNull [] union(char @PolyNull [] seq1, char @PolyNull [] seq2) { 2474 if (seq1 == null) { 2475 return null; 2476 } 2477 if (seq2 == null) { 2478 return null; 2479 } 2480 return concat(seq1, seq2); 2481 } 2482 2483 /** 2484 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 2485 * gives no assurances about the order or repetition of elements: elements may be repeated, and 2486 * their order may be different from the order of elements in seq1 and seq2. 2487 */ 2488 @Pure 2489 public static char @PolyNull [] intersection(char @PolyNull [] seq1, char @PolyNull [] seq2) { 2490 if (seq1 == null) { 2491 return null; 2492 } 2493 if (seq2 == null) { 2494 return null; 2495 } 2496 char[] intermediate = new char[Math.min(seq1.length, seq2.length)]; 2497 int length = 0; 2498 for (int i = 0 ; i < seq1.length ; i++) { 2499 if (memberOf(seq1[i], seq2) ) { 2500 intermediate[length++] = seq1[i]; 2501 } 2502 } 2503 return ArraysPlume.subarray(intermediate, 0, length); 2504 } 2505 2506 /** 2507 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 2508 * no assurances about the order or repetition of elements: elements may be repeated, and their 2509 * order may be different from the order of elements in seq1 and seq2. 2510 */ 2511 @Pure 2512 public static char @PolyNull [] setDiff(char @PolyNull [] seq1, char @PolyNull [] seq2) { 2513 if (seq1 == null) { 2514 return null; 2515 } 2516 if (seq2 == null) { 2517 return null; 2518 } 2519 char[] intermediate = new char[seq1.length]; 2520 int length = 0; 2521 for (int i = 0 ; i < seq1.length ; i++) { 2522 if (!memberOf(seq1[i], seq2)) { 2523 intermediate[length++] = seq1[i]; 2524 } 2525 } 2526 return ArraysPlume.subarray(intermediate, 0, length); 2527 } 2528 2529 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 2530 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2531 @Pure 2532 public static boolean setEqual(char @Nullable [] seq1, char @Nullable [] seq2) { 2533 if (seq1 == null) { 2534 return false; 2535 } 2536 if (seq2 == null) { 2537 return false; 2538 } 2539 for (int i = 0; i < seq1.length ; i++) { 2540 if (!memberOf(seq1[i], seq2) ) { 2541 return false; 2542 } 2543 } 2544 for (int i = 0; i < seq2.length ; i++) { 2545 if (!memberOf(seq2[i], seq1) ) { 2546 return false; 2547 } 2548 } 2549 return true; 2550 } 2551 2552 /** True iff seq1 is the reverse of seq2. 2553 * 2554 * Meaning (in pseudo-FOL): 2555 * 2556 * <pre> 2557 * /\ seq1.length == seq2.length 2558 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 2559 * </pre> 2560 * 2561 */ 2562 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2563 @Pure 2564 public static boolean isReverse(char[] seq1, char[] seq2) { 2565 if (!sameLength(seq1, seq2)) { 2566 return false; 2567 } 2568 assert seq1 != null && seq2 != null; // because sameLength() = true 2569 int length = seq1.length; 2570 for (int i = 0 ; i < length ; i++) { 2571 if (ne(seq1[i], seq2[length - i - 1])) { 2572 return false; 2573 } 2574 } 2575 return true; 2576 } 2577 2578 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 2579 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2580 @Pure 2581 public static boolean subsetOf(char @Nullable [] seq1, char @Nullable [] seq2) { 2582 if (seq1 == null) { 2583 return false; 2584 } 2585 if (seq2 == null) { 2586 return false; 2587 } 2588 for (int i = 0 ; i < seq1.length ; i++) { 2589 if (!memberOf(seq1[i], seq2)) { 2590 return false; 2591 } 2592 } 2593 return true; 2594 } 2595 2596 /** Returns true iff seq contains no duplicate elements. */ 2597 @EnsuresNonNullIf(result=true, expression="#1") 2598 @Pure 2599 public static boolean noDups(char @Nullable [] seq) { 2600 if (seq == null) { 2601 return false; 2602 } 2603 return ArraysPlume.noDuplicates(seq); 2604 } 2605 2606 /** Returns true iff elt is in array arr. */ 2607 @EnsuresNonNullIf(result=true, expression="#2") 2608 @Pure 2609 public static boolean memberOf(char elt, char @Nullable [] arr) { 2610 if (arr == null) { 2611 return false; 2612 } 2613 for (int i = 0 ; i < arr.length ; i++) { 2614 if (eq(arr[i], elt)) { 2615 return true; 2616 } 2617 } 2618 return false; 2619 } 2620 2621 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 2622 @Pure 2623 public static char @PolyNull [] slice(char @PolyNull [] seq, int start, int end) { 2624 if (seq == null) { 2625 return null; 2626 } 2627 int sliceStart = start; 2628 int sliceEnd = end; 2629 if (start < 0) { 2630 return new char[] { }; 2631 } 2632 if (end > seq.length - 1) { 2633 return new char[] { }; 2634 } 2635 if (sliceStart > sliceEnd) { 2636 return new char[] { }; 2637 } 2638 int length = sliceEnd - sliceStart + 1; 2639 return ArraysPlume.subarray(seq, sliceStart, length); 2640 } 2641 2642 @Pure 2643 public static char @PolyNull [] slice(char @PolyNull [] seq, long start, int end) { 2644 return slice(seq, (int)start, end); 2645 } 2646 @Pure 2647 public static char @PolyNull [] slice(char @PolyNull [] seq, int start, long end) { 2648 return slice(seq, start, (int)end); 2649 } 2650 @Pure 2651 public static char @PolyNull [] slice(char @PolyNull [] seq, long start, long end) { 2652 return slice(seq, (int)start, (int)end); 2653 } 2654 2655 /** True iff all elements in arr equal elt. 2656 * 2657 * Meaning (in pseudo-FOL): 2658 * 2659 * forall i in { 0..arr.length-1 } : arr[i] == elt 2660 * 2661 */ 2662 @EnsuresNonNullIf(result=true, expression="#1") 2663 @Pure 2664 public static boolean eltsEqual(char @Nullable [] arr, char elt) { 2665 if (arr == null) { 2666 return false; 2667 } 2668 for (int i = 0 ; i < arr.length ; i++) { 2669 if (ne(arr[i], elt)) { 2670 return false; 2671 } 2672 } 2673 return true; 2674 } 2675 2676 /** True iff every element in arr does not equal elt. 2677 * 2678 * Meaning (in pseudo-FOL): 2679 * 2680 * forall i in { 0..arr.length-1 } : arr[i] != elt 2681 * 2682 */ 2683 @EnsuresNonNullIf(result=true, expression="#1") 2684 @Pure 2685 public static boolean eltsNotEqual(char @Nullable [] arr, char elt) { 2686 if (arr == null) { 2687 return false; 2688 } 2689 for (int i = 0 ; i < arr.length ; i++) { 2690 if (eq(arr[i], elt)) { 2691 return false; 2692 } 2693 } 2694 return true; 2695 } 2696 2697 /** True iff every element in arr is greater than elt. 2698 * 2699 * Meaning (in pseudo-FOL): 2700 * 2701 * forall i in { 0..arr.length-1 } : arr[i] > elt 2702 * 2703 */ 2704 @EnsuresNonNullIf(result=true, expression="#1") 2705 @Pure 2706 public static boolean eltsGT(char @Nullable [] arr, char elt) { 2707 if (arr == null) { 2708 return false; 2709 } 2710 for (int i = 0 ; i < arr.length ; i++) { 2711 if (lte(arr[i], elt)) { 2712 return false; 2713 } 2714 } 2715 return true; 2716 } 2717 2718 /** True iff every element in arr is greater than or equal to elt. 2719 * 2720 * Meaning (in pseudo-FOL): 2721 * 2722 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 2723 * 2724 */ 2725 @EnsuresNonNullIf(result=true, expression="#1") 2726 @Pure 2727 public static boolean eltsGTE(char @Nullable [] arr, char elt) { 2728 if (arr == null) { 2729 return false; 2730 } 2731 for (int i = 0 ; i < arr.length ; i++) { 2732 if (lt(arr[i], elt)) { 2733 return false; 2734 } 2735 } 2736 return true; 2737 } 2738 2739 /** True iff every element in arr is less than elt. 2740 * 2741 * Meaning (in pseudo-FOL): 2742 * 2743 * forall i in { 0..arr.length-1 } : arr[i] < elt 2744 * 2745 */ 2746 @EnsuresNonNullIf(result=true, expression="#1") 2747 @Pure 2748 public static boolean eltsLT(char @Nullable [] arr, char elt) { 2749 if (arr == null) { 2750 return false; 2751 } 2752 for (int i = 0 ; i < arr.length ; i++) { 2753 if (gte(arr[i], elt)) { 2754 return false; 2755 } 2756 } 2757 return true; 2758 } 2759 2760 /** True iff every element in arr is less than or equal to elt. 2761 * 2762 * Meaning (in pseudo-FOL): 2763 * 2764 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 2765 * 2766 */ 2767 @EnsuresNonNullIf(result=true, expression="#1") 2768 @Pure 2769 public static boolean eltsLTE(char @Nullable [] arr, char elt) { 2770 if (arr == null) { 2771 return false; 2772 } 2773 for (int i = 0 ; i < arr.length ; i++) { 2774 if (gt(arr[i], elt)) { 2775 return false; 2776 } 2777 } 2778 return true; 2779 } 2780 2781 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 2782 * 2783 * Meaning (in pseudo-FOL): 2784 * 2785 * /\ seq1.length == se2.length 2786 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 2787 * 2788 */ 2789 2790 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2791 @Pure 2792 public static boolean pairwiseEqual(char @Nullable [] seq1, char @Nullable [] seq2) { 2793 if (!sameLength(seq1, seq2)) { 2794 return false; 2795 } 2796 assert seq1 != null && seq2 != null; // because sameLength() = true 2797 for (int i = 0 ; i < seq1.length ; i++) { 2798 if (ne(seq1[i], seq2[i])) { 2799 return false; 2800 } 2801 } 2802 return true; 2803 } 2804 2805 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 2806 * 2807 * Meaning (in pseudo-FOL): 2808 * 2809 * /\ seq1.length == se2.length 2810 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 2811 * 2812 */ 2813 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2814 @Pure 2815 public static boolean pairwiseNotEqual(char @Nullable [] seq1, char @Nullable [] seq2) { 2816 if (!sameLength(seq1, seq2)) { 2817 return false; 2818 } 2819 assert seq1 != null && seq2 != null; // because sameLength() = true 2820 for (int i = 0 ; i < seq1.length ; i++) { 2821 if (eq(seq1[i], seq2[i])) { 2822 return false; 2823 } 2824 } 2825 return true; 2826 } 2827 2828 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 2829 * 2830 * Meaning (in pseudo-FOL): 2831 * 2832 * /\ seq1.length == se2.length 2833 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 2834 * 2835 */ 2836 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2837 @Pure 2838 public static boolean pairwiseLT(char @Nullable [] seq1, char @Nullable [] seq2) { 2839 if (!sameLength(seq1, seq2)) { 2840 return false; 2841 } 2842 assert seq1 != null && seq2 != null; // because sameLength() = true 2843 for (int i = 0 ; i < seq1.length ; i++) { 2844 if (gte(seq1[i], seq2[i])) { 2845 return false; 2846 } 2847 } 2848 return true; 2849 } 2850 2851 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 2852 * Meaning (in pseudo-FOL): 2853 * 2854 * /\ seq1.length == se2.length 2855 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 2856 * 2857 */ 2858 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2859 @Pure 2860 public static boolean pairwiseLTE(char @Nullable [] seq1, char @Nullable [] seq2) { 2861 if (!sameLength(seq1, seq2)) { 2862 return false; 2863 } 2864 assert seq1 != null && seq2 != null; // because sameLength() = true 2865 for (int i = 0 ; i < seq1.length ; i++) { 2866 if (gt(seq1[i], seq2[i])) { 2867 return false; 2868 } 2869 } 2870 return true; 2871 } 2872 2873 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 2874 * Meaning (in pseudo-FOL): 2875 * 2876 * /\ seq1.length == se2.length 2877 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 2878 * 2879 */ 2880 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2881 @Pure 2882 public static boolean pairwiseGT(char @Nullable [] seq1, char @Nullable [] seq2) { 2883 if (!sameLength(seq1, seq2)) { 2884 return false; 2885 } 2886 assert seq1 != null && seq2 != null; // because sameLength() = true 2887 for (int i = 0 ; i < seq1.length ; i++) { 2888 if (lte(seq1[i], seq2[i])) { 2889 return false; 2890 } 2891 } 2892 return true; 2893 } 2894 2895 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 2896 * Meaning (in pseudo-FOL): 2897 * 2898 * /\ seq1.length == se2.length 2899 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 2900 * 2901 */ 2902 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2903 @Pure 2904 public static boolean pairwiseGTE(char @Nullable [] seq1, char @Nullable [] seq2) { 2905 if (!sameLength(seq1, seq2)) { 2906 return false; 2907 } 2908 assert seq1 != null && seq2 != null; // because sameLength() = true 2909 for (int i = 0 ; i < seq1.length ; i++) { 2910 if (lt(seq1[i], seq2[i])) { 2911 return false; 2912 } 2913 } 2914 return true; 2915 } 2916 2917 /** 2918 * Returns true iff seq1 is lexically equal to seq2. 2919 * For equality, "lexically" and "pairwise" are the same. 2920 */ 2921 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2922 @Pure 2923 public static boolean lexEqual(char @Nullable [] seq1, char @Nullable [] seq2) { 2924 if (seq1 == null) { 2925 return false; 2926 } 2927 if (seq2 == null) { 2928 return false; 2929 } 2930 return pairwiseEqual(seq1, seq2); 2931 } 2932 2933 /** Returns true iff seq1 is lexically not equal to seq2. */ 2934 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2935 @Pure 2936 public static boolean lexNotEqual(char @Nullable [] seq1, char @Nullable [] seq2) { 2937 if (seq1 == null) { 2938 return false; 2939 } 2940 if (seq2 == null) { 2941 return false; 2942 } 2943 return !lexEqual(seq1, seq2); 2944 } 2945 2946 /** Returns true iff seq1 is lexically < seq2. */ 2947 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2948 @Pure 2949 public static boolean lexLT(char @Nullable [] seq1, char @Nullable [] seq2) { 2950 if (seq1 == null) { 2951 return false; 2952 } 2953 if (seq2 == null) { 2954 return false; 2955 } 2956 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 2957 for (int i = 0 ; i < minlength ; i++) { 2958 if (gt(seq1[i], seq2[i])) { 2959 return false; 2960 } else if (lt(seq1[i], seq2[i])) { 2961 return true; 2962 } 2963 } 2964 if (seq1.length >= seq2.length) { 2965 return false; 2966 } 2967 return true; 2968 } 2969 2970 /** Returns true iff seq1 is lexically ≤ to seq2. */ 2971 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2972 @Pure 2973 public static boolean lexLTE(char @Nullable [] seq1, char @Nullable [] seq2) { 2974 if (seq1 == null) { 2975 return false; 2976 } 2977 if (seq2 == null) { 2978 return false; 2979 } 2980 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 2981 for (int i = 0 ; i < minlength ; i++) { 2982 if (gt(seq1[i], seq2[i])) { 2983 return false; 2984 } else if (lt(seq1[i], seq2[i])) { 2985 return true; 2986 } 2987 } 2988 if (seq1.length > seq2.length) { 2989 return false; 2990 } 2991 return true; 2992 } 2993 2994 /** Returns true iff seq1 is lexically > to seq2. */ 2995 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 2996 @Pure 2997 public static boolean lexGT(char @Nullable [] seq1, char @Nullable [] seq2) { 2998 if (seq1 == null) { 2999 return false; 3000 } 3001 if (seq2 == null) { 3002 return false; 3003 } 3004 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 3005 for (int i = 0 ; i < minlength ; i++) { 3006 if (lt(seq1[i], seq2[i])) { 3007 return false; 3008 } else if (gt(seq1[i], seq2[i])) { 3009 return true; 3010 } 3011 } 3012 if (seq1.length <= seq2.length) { 3013 return false; 3014 } 3015 return true; 3016 } 3017 3018 /** Returns true iff seq1 is lexically ≥ to seq2. */ 3019 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3020 @Pure 3021 public static boolean lexGTE(char @Nullable [] seq1, char @Nullable [] seq2) { 3022 if (seq1 == null) { 3023 return false; 3024 } 3025 if (seq2 == null) { 3026 return false; 3027 } 3028 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 3029 for (int i = 0 ; i < minlength ; i++) { 3030 if (lt(seq1[i], seq2[i])) { 3031 return false; 3032 } else if (gt(seq1[i], seq2[i])) { 3033 return true; 3034 } 3035 } 3036 if (seq1.length < seq2.length) { 3037 return false; 3038 } 3039 return true; 3040 } 3041 3042 /** True iff for all applicable i, every seq[i] == seq[i+1]. 3043 * 3044 * Meaning (in pseudo-FOL): 3045 * 3046 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 3047 * 3048 */ 3049 @EnsuresNonNullIf(result=true, expression="#1") 3050 @Pure 3051 public static boolean eltwiseEqual(char @Nullable [] seq) { 3052 if (seq == null) { 3053 return false; 3054 } 3055 for (int i = 0 ; i < seq.length ; i++) { 3056 if (i < seq.length - 1) { 3057 if (ne(seq[i], seq[i + 1])) { 3058 return false; 3059 } 3060 } 3061 } 3062 return true; 3063 } 3064 3065 /** True iff for all applicable i, every seq[i] != seq[i+1]. 3066 * 3067 * Meaning (in pseudo-FOL): 3068 * 3069 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 3070 * 3071 */ 3072 @EnsuresNonNullIf(result=true, expression="#1") 3073 @Pure 3074 public static boolean eltwiseNotEqual(char @Nullable [] seq) { 3075 if (seq == null) { 3076 return false; 3077 } 3078 for (int i = 0 ; i < seq.length ; i++) { 3079 if (i < seq.length - 1) { 3080 if (eq(seq[i], seq[i + 1])) { 3081 return false; 3082 } 3083 } 3084 } 3085 return true; 3086 } 3087 3088 /** True iff for all applicable i, every seq[i] < seq[i+1]. 3089 * 3090 * Meaning (in pseudo-FOL): 3091 * 3092 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 3093 * 3094 */ 3095 @EnsuresNonNullIf(result=true, expression="#1") 3096 @Pure 3097 public static boolean eltwiseLT(char @Nullable [] seq) { 3098 if (seq == null) { 3099 return false; 3100 } 3101 for (int i = 0 ; i < seq.length ; i++) { 3102 if (i < seq.length - 1) { 3103 if (gte(seq[i], seq[i + 1])) { 3104 return false; 3105 } 3106 } 3107 } 3108 return true; 3109 } 3110 3111 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 3112 * 3113 * Meaning (in pseudo-FOL): 3114 * 3115 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 3116 * 3117 */ 3118 @EnsuresNonNullIf(result=true, expression="#1") 3119 @Pure 3120 public static boolean eltwiseLTE(char @Nullable [] seq) { 3121 if (seq == null) { 3122 return false; 3123 } 3124 for (int i = 0 ; i < seq.length ; i++) { 3125 if (i < seq.length - 1) { 3126 if (gt(seq[i], seq[i + 1])) { 3127 return false; 3128 } 3129 } 3130 } 3131 return true; 3132 } 3133 3134 /** True iff for all applicable i, every seq[i] > seq[i+1]. 3135 * 3136 * Meaning (in pseudo-FOL): 3137 * 3138 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 3139 * 3140 */ 3141 @EnsuresNonNullIf(result=true, expression="#1") 3142 @Pure 3143 public static boolean eltwiseGT(char @Nullable [] seq) { 3144 if (seq == null) { 3145 return false; 3146 } 3147 for (int i = 0 ; i < seq.length ; i++) { 3148 if (i < seq.length - 1) { 3149 if (lte(seq[i], seq[i + 1])) { 3150 return false; 3151 } 3152 } 3153 } 3154 return true; 3155 } 3156 3157 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 3158 * 3159 * Meaning (in pseudo-FOL): 3160 * 3161 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 3162 * 3163 */ 3164 @EnsuresNonNullIf(result=true, expression="#1") 3165 @Pure 3166 public static boolean eltwiseGTE(char @Nullable [] seq) { 3167 if (seq == null) { 3168 return false; 3169 } 3170 for (int i = 0 ; i < seq.length ; i++) { 3171 if (i < seq.length - 1) { 3172 if (lt(seq[i], seq[i + 1])) { 3173 return false; 3174 } 3175 } 3176 } 3177 return true; 3178 } 3179 3180 /** True iff for all applicable i, every seq[i] == i. 3181 * 3182 * Meaning (in pseudo-FOL): 3183 * 3184 * forall i in { 0..seq.length-1 } : seq[i] == i 3185 * 3186 */ 3187 @EnsuresNonNullIf(result=true, expression="#1") 3188 @Pure 3189 public static boolean eltsEqualIndex(char @Nullable [] seq) { 3190 if (seq == null) { 3191 return false; 3192 } 3193 for (int i = 0 ; i < seq.length ; i++) { 3194 if (ne(seq[i], i)) { 3195 return false; 3196 } 3197 } 3198 return true; 3199 } 3200 3201 /** True iff for all applicable i, every seq[i] != i. 3202 * 3203 * Meaning (in pseudo-FOL): 3204 * 3205 * forall i in { 0..seq.length-1 } : seq[i] != i 3206 * 3207 */ 3208 @EnsuresNonNullIf(result=true, expression="#1") 3209 @Pure 3210 public static boolean eltsNotEqualIndex(char @Nullable [] seq) { 3211 if (seq == null) { 3212 return false; 3213 } 3214 for (int i = 0 ; i < seq.length ; i++) { 3215 if (eq(seq[i], i)) { 3216 return false; 3217 } 3218 } 3219 return true; 3220 } 3221 3222 /** True iff for all applicable i, every seq[i] < i. 3223 * 3224 * Meaning (in pseudo-FOL): 3225 * 3226 * forall i in { 0..seq.length-1 } : seq[i] < i 3227 * 3228 */ 3229 @EnsuresNonNullIf(result=true, expression="#1") 3230 @Pure 3231 public static boolean eltsLtIndex(char @Nullable [] seq) { 3232 if (seq == null) { 3233 return false; 3234 } 3235 for (int i = 0 ; i < seq.length ; i++) { 3236 if (gte(seq[i], i)) { 3237 return false; 3238 } 3239 } 3240 return true; 3241 } 3242 3243 /** True iff for all applicable i, every seq[i] ≤ i. 3244 * 3245 * Meaning (in pseudo-FOL): 3246 * 3247 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 3248 * 3249 */ 3250 @EnsuresNonNullIf(result=true, expression="#1") 3251 @Pure 3252 public static boolean eltsLteIndex(char @Nullable [] seq) { 3253 if (seq == null) { 3254 return false; 3255 } 3256 for (int i = 0 ; i < seq.length ; i++) { 3257 if (gt(seq[i], i)) { 3258 return false; 3259 } 3260 } 3261 return true; 3262 } 3263 3264 /** True iff for all applicable i, every seq[i] > i. 3265 * 3266 * Meaning (in pseudo-FOL): 3267 * 3268 * forall i in { 0..seq.length-1 } : seq[i] > i 3269 * 3270 */ 3271 @EnsuresNonNullIf(result=true, expression="#1") 3272 @Pure 3273 public static boolean eltsGtIndex(char @Nullable [] seq) { 3274 if (seq == null) { 3275 return false; 3276 } 3277 for (int i = 0 ; i < seq.length ; i++) { 3278 if (lte(seq[i], i)) { 3279 return false; 3280 } 3281 } 3282 return true; 3283 } 3284 3285 /** True iff for all applicable i, every seq[i] ≥ i. 3286 * 3287 * Meaning (in pseudo-FOL): 3288 * 3289 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 3290 * 3291 */ 3292 @EnsuresNonNullIf(result=true, expression="#1") 3293 @Pure 3294 public static boolean eltsGteIndex(char @Nullable [] seq) { 3295 if (seq == null) { 3296 return false; 3297 } 3298 for (int i = 0 ; i < seq.length ; i++) { 3299 if (lt(seq[i], i)) { 3300 return false; 3301 } 3302 } 3303 return true; 3304 } 3305 3306 /// Deferencing (accessing) fields 3307 3308 /** 3309 * collectchar accepts an object and a list of fields (one of which is of array type, and the 3310 * rest of which are not), and produces an array in which the original object has had the given 3311 * fields accessed. 3312 * 3313 * <p>Daikon creates invariants over "variables" such as the following. 3314 * 3315 * <dl> 3316 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 3317 * for all y's in array x.arr.</dd> 3318 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 3319 * for all x's in array arr.</dd> 3320 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 3321 * </dl> 3322 * 3323 * <p>The collectchar() method does this collecting work. 3324 * 3325 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 3326 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 3327 * elements that result from following the fields, one of which is assumed to be an array. 3328 * 3329 * <p> 3330 * requires: fieldStr.length() > 0 and object != null 3331 * <p> 3332 * requires: fieldStr contains only field names, no "[]" strings. 3333 * <p> 3334 * requires: the method only works for field sequences with exactly one field representing an 3335 * array. For example, the collection a[].b[].c will fail. 3336 * 3337 * @return if the resulting collection is of non-primitive type, then returns an array of type 3338 * Object[]. Returns null if any array or field access causes an exception. 3339 */ 3340 3341 @SideEffectFree 3342 public static char @Nullable [] collectchar(@Nullable Object object, @Nullable String fieldStr) { 3343 3344 if (object == null) { 3345 return null; 3346 } 3347 if (fieldStr == null) { 3348 return null; 3349 } 3350 3351 // assert fieldStr != null && !"".equals(fieldStr); 3352 String[] fieldNames = fieldStr.split("\\."); 3353 char[] retval = collectchar(object, fieldNames, 0); 3354 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 3355 return retval; 3356 } 3357 3358 /** Helper method for collectchar(Object, String). 3359 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 3360 * @see collectchar(Object, String) 3361 */ 3362 // @PolyNull does not work for return type, because null is returned on error. 3363 @SideEffectFree 3364 private static char @Nullable [] collectchar(@Nullable Object object, 3365 String[] fields, int fieldsStartIdx) { 3366 3367 if (object == null) { 3368 return null; 3369 } 3370 assert (fields != null); 3371 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 3372 3373 Object fieldObj; 3374 try { 3375 Field field = (object instanceof java.lang.Class<?>) 3376 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 3377 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 3378 field.setAccessible(true); 3379 // Class cls = field.getType(); 3380 fieldObj = field.get(object); 3381 // System.out.println("***fieldObj="+fieldObj); 3382 3383 } catch (Exception e) { 3384 return null; 3385 3386 } 3387 3388 if (fieldObj == null) { 3389 return null; 3390 } 3391 3392 // base case: just accessed the last field 3393 if (fields.length - 1 == fieldsStartIdx) { 3394 3395 if (fieldObj.getClass().isArray()) { 3396 // last field is an array 3397 return (char[])fieldObj; 3398 } else { 3399 // This hack should be removed in favor of, at "oneEltArray = ..." 3400 // below, calling a version of collectchar_field that throws an 3401 // error. Then, this case becomes a run-time error. -MDE 3402 3403 // Just one element; return a one-element array. 3404 // assert cls.equals(Character.TYPE); 3405 return new char[] { ((Character)fieldObj).charValue() }; 3406 } 3407 } else { 3408 // recursive case: more fields to access after this one 3409 3410 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 3411 3412 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 3413 char[] intermediate = new char[collection.size()]; 3414 int index = 0; 3415 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 3416 Object obj = i.next(); 3417 char[] oneEltArray = collectchar(obj, fields, fieldsStartIdx + 1); 3418 if (oneEltArray == null) { 3419 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 3420 } 3421 // assert oneEltArray.length == 1; 3422 intermediate[index++] = oneEltArray[0]; 3423 } 3424 return intermediate; 3425 } else if (fieldObj.getClass().isArray()) { 3426 3427 // collect elements across array 3428 char[] intermediate = new char[Array.getLength(fieldObj)]; 3429 for (int i = 0 ; i < intermediate.length ; i++) { 3430 Object obj = Array.get(fieldObj, i); 3431 char[] oneEltArray = collectchar(obj, fields, fieldsStartIdx + 1); 3432 if (oneEltArray == null) { 3433 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 3434 } 3435 // assert oneEltArray.length == 1; 3436 intermediate[i] = oneEltArray[0]; 3437 } 3438 return intermediate; 3439 } else { 3440 3441 return collectchar(fieldObj, fields, fieldsStartIdx + 1); 3442 } 3443 } 3444 } 3445 3446 /** 3447 * Returns the results of dereferencing the fields for 'object'. For example, the call 3448 * 3449 * <pre>collectchar_field(x, "f.g.h")</pre> 3450 * 3451 * has the same value as 3452 * 3453 * <pre>x.f.g.h</pre>. 3454 * Returns a default value if any field access causes an exception. 3455 */ 3456 @SideEffectFree 3457 public static char collectchar_field(Object object, String fieldStr) { 3458 3459 if (object == null) { 3460 return Character.MAX_VALUE; // return default value 3461 } 3462 if (fieldStr == null) { 3463 return Character.MAX_VALUE; // return default value 3464 } 3465 3466 String[] fieldNames = fieldStr.split("\\."); 3467 3468 // Holds the intermediate (and final) result 3469 Object fieldObj = object; 3470 3471 for (int i = 0 ; i < fieldNames.length ; i++) { 3472 3473 String fieldName = fieldNames[i]; 3474 3475 try { 3476 Field field = 3477 (fieldObj instanceof java.lang.Class<?>) 3478 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 3479 : fieldObj.getClass().getDeclaredField(fieldName); 3480 field.setAccessible(true); 3481 fieldObj = field.get(fieldObj); 3482 3483 if (fieldObj == null) { 3484 return Character.MAX_VALUE; // return default value 3485 } 3486 3487 } catch (Exception e) { 3488 return Character.MAX_VALUE; // return default value 3489 3490 } 3491 3492 } 3493 3494 return ((Character)fieldObj).charValue(); 3495 } 3496 3497 /////////////////////////////////////////////////////////////////////////// 3498 /// Methods for "double" (from QuantBody.java.jpp) 3499 /// 3500 3501 /** 3502 * Returns the ith element of the array or collection argument. If the argument is null or not an 3503 * array or collection, returns a default value (Double.NaN). 3504 */ 3505 3506 @Pure 3507 public static double getElement_double(Object o, long i) { 3508 if (o == null) { 3509 return Double.NaN; // return default value 3510 } 3511 java.lang.Class<?> c = o.getClass(); 3512 if (c.isArray()) { 3513 return java.lang.reflect.Array.getDouble(o, (int)i); 3514 } else if (o instanceof java.util.AbstractCollection<?>) { 3515 return java.lang.reflect.Array.getDouble(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 3516 } else { 3517 return Double.NaN; // return default value 3518 } 3519 } 3520 3521 @Pure 3522 public static double getElement_double(double[] arr, long i) { 3523 if (arr == null) { 3524 return Double.NaN; // return default value 3525 } 3526 return arr[(int)i]; 3527 } 3528 3529 private static boolean eq(double x, double y) { 3530 return fuzzy.eq(x,y); 3531 } 3532 3533 private static boolean ne(double x, double y) { 3534 return fuzzy.ne(x,y); 3535 } 3536 3537 private static boolean lt(double x, double y) { 3538 return fuzzy.lt(x,y); 3539 } 3540 3541 private static boolean lte(double x, double y) { 3542 return fuzzy.lte(x,y); 3543 } 3544 3545 private static boolean gt(double x, double y) { 3546 return fuzzy.gt(x,y); 3547 } 3548 3549 private static boolean gte(double x, double y) { 3550 return fuzzy.gte(x,y); 3551 } 3552 3553 /** True iff both sequences are non-null and have the same length. */ 3554 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 3555 @Pure 3556 public static boolean sameLength(double @Nullable [] seq1, double @Nullable [] seq2) { 3557 return ((seq1 != null) 3558 && (seq2 != null) 3559 && seq1.length == seq2.length); 3560 } 3561 3562 /** True iff both sequences are non-null and have the same length. */ 3563 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 3564 @Pure 3565 public static boolean sameLength(double @Nullable [] seq1, float @Nullable [] seq2) { 3566 return ((seq1 != null) 3567 && (seq2 != null) 3568 && seq1.length == seq2.length); 3569 } 3570 3571 /** True iff both sequences have the same length, and all seq2[i] divide seq1[i]. 3572 * 3573 * Meaning (in pseudo-FOL): 3574 * 3575 * <pre> 3576 * /\ seq1.length == seq2.length 3577 * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i] 3578 * </pre> 3579 * 3580 */ 3581 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3582 @Pure 3583 public static boolean pairwiseDivides(double[] seq1, double[] seq2) { 3584 if (!sameLength(seq1, seq2)) { 3585 return false; 3586 } 3587 assert seq1 != null && seq2 != null; // because sameLength() = true 3588 for (int i = 0 ; i < seq1.length ; i++) { 3589 if (ne(seq1[i] % seq2[i], 0)) { 3590 return false; 3591 } 3592 } 3593 return true; 3594 } 3595 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3596 @Pure 3597 public static boolean pairwiseDivides(double[] seq1, float[] seq2) { 3598 if (!sameLength(seq1, seq2)) { 3599 return false; 3600 } 3601 assert seq1 != null && seq2 != null; // because sameLength() = true 3602 for (int i = 0 ; i < seq1.length ; i++) { 3603 if (ne(seq1[i] % seq2[i], 0)) { 3604 return false; 3605 } 3606 } 3607 return true; 3608 } 3609 3610 /** 3611 * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i]. 3612 * 3613 * Meaning (in pseudo-FOL): 3614 * 3615 * <pre> 3616 * /\ seq1.length == seq2.length 3617 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i] 3618 * </pre> 3619 * 3620 */ 3621 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3622 @Pure 3623 public static boolean pairwiseSquare(double[] seq1, double[] seq2) { 3624 if (!sameLength(seq1, seq2)) { 3625 return false; 3626 } 3627 assert seq1 != null && seq2 != null; // because sameLength() = true 3628 for (int i = 0 ; i < seq1.length ; i++) { 3629 if (ne(seq1[i], seq2[i] * seq2[i])) { 3630 return false; 3631 } 3632 } 3633 return true; 3634 } 3635 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3636 @Pure 3637 public static boolean pairwiseSquare(double[] seq1, float[] seq2) { 3638 if (!sameLength(seq1, seq2)) { 3639 return false; 3640 } 3641 assert seq1 != null && seq2 != null; // because sameLength() = true 3642 for (int i = 0 ; i < seq1.length ; i++) { 3643 3644 if (ne(seq1[i], ((double) seq2[i]) * ((double) seq2[i]))) { 3645 3646 return false; 3647 } 3648 } 3649 return true; 3650 } 3651 3652 /** 3653 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 3654 * 3655 * <p>If either array is null, returns null. If either array is empty, returns only those 3656 * elements in the other array. If both arrays are empty, returns a new empty array. 3657 */ 3658 @SideEffectFree 3659 public static double @PolyNull [] concat(double @PolyNull [] seq1, double @PolyNull [] seq2) { 3660 if (seq1 == null) { 3661 return null; 3662 } 3663 if (seq2 == null) { 3664 return null; 3665 } 3666 return ArraysPlume.concat(seq1, seq2); 3667 } 3668 3669 @SideEffectFree 3670 public static double @PolyNull [] concat(double @PolyNull [] seq1, float @PolyNull [] seq2) { 3671 if (seq1 == null) { 3672 return null; 3673 } 3674 if (seq2 == null) { 3675 return null; 3676 } 3677 // Cannot just use ArraysPlume.concat because the two arrays 3678 // have different types. This essentially inlines that method. 3679 int newLength = seq1.length + seq2.length; 3680 double[] retval = new double[newLength]; 3681 3682 System.arraycopy(seq1, 0, retval, 0, seq1.length); 3683 for (int j = 0 ; j < seq2.length ; j++) { 3684 retval[seq1.length + j] = seq2[j]; 3685 } 3686 3687 return retval; 3688 } 3689 3690 /** 3691 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 3692 * assurances about the order or repetition of elements: elements may be repeated, and their 3693 * order may be different from the order of elements in seq1 and seq2. 3694 */ 3695 @SideEffectFree 3696 public static double @PolyNull [] union(double @PolyNull [] seq1, double @PolyNull [] seq2) { 3697 if (seq1 == null) { 3698 return null; 3699 } 3700 if (seq2 == null) { 3701 return null; 3702 } 3703 return concat(seq1, seq2); 3704 } 3705 3706 @Pure 3707 public static double @PolyNull [] union(double @PolyNull [] seq1, float @PolyNull [] seq2) { 3708 if (seq1 == null) { 3709 return null; 3710 } 3711 if (seq2 == null) { 3712 return null; 3713 } 3714 return concat(seq1, seq2); 3715 } 3716 3717 /** 3718 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 3719 * gives no assurances about the order or repetition of elements: elements may be repeated, and 3720 * their order may be different from the order of elements in seq1 and seq2. 3721 */ 3722 @Pure 3723 public static double @PolyNull [] intersection(double @PolyNull [] seq1, double @PolyNull [] seq2) { 3724 if (seq1 == null) { 3725 return null; 3726 } 3727 if (seq2 == null) { 3728 return null; 3729 } 3730 double[] intermediate = new double[Math.min(seq1.length, seq2.length)]; 3731 int length = 0; 3732 for (int i = 0 ; i < seq1.length ; i++) { 3733 if (memberOf(seq1[i], seq2) ) { 3734 intermediate[length++] = seq1[i]; 3735 } 3736 } 3737 return ArraysPlume.subarray(intermediate, 0, length); 3738 } 3739 3740 @Pure 3741 public static double @PolyNull [] intersection(double @PolyNull [] seq1, float @PolyNull [] seq2) { 3742 if (seq1 == null) { 3743 return null; 3744 } 3745 if (seq2 == null) { 3746 return null; 3747 } 3748 double[] intermediate = new double[Math.min(seq1.length, seq2.length)]; 3749 int length = 0; 3750 for (int i = 0 ; i < seq1.length ; i++) { 3751 if (memberOf(seq1[i], seq2) ) { 3752 intermediate[length++] = seq1[i]; 3753 } 3754 } 3755 return ArraysPlume.subarray(intermediate, 0, length); 3756 } 3757 3758 /** 3759 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 3760 * no assurances about the order or repetition of elements: elements may be repeated, and their 3761 * order may be different from the order of elements in seq1 and seq2. 3762 */ 3763 @Pure 3764 public static double @PolyNull [] setDiff(double @PolyNull [] seq1, double @PolyNull [] seq2) { 3765 if (seq1 == null) { 3766 return null; 3767 } 3768 if (seq2 == null) { 3769 return null; 3770 } 3771 double[] intermediate = new double[seq1.length]; 3772 int length = 0; 3773 for (int i = 0 ; i < seq1.length ; i++) { 3774 if (!memberOf(seq1[i], seq2)) { 3775 intermediate[length++] = seq1[i]; 3776 } 3777 } 3778 return ArraysPlume.subarray(intermediate, 0, length); 3779 } 3780 3781 @Pure 3782 public static double @PolyNull [] setDiff(double @PolyNull [] seq1, float @PolyNull [] seq2) { 3783 if (seq1 == null) { 3784 return null; 3785 } 3786 if (seq2 == null) { 3787 return null; 3788 } 3789 double[] intermediate = new double[seq1.length]; 3790 int length = 0; 3791 for (int i = 0 ; i < seq1.length ; i++) { 3792 if (!memberOf(seq1[i], seq2)) { 3793 intermediate[length++] = seq1[i]; 3794 } 3795 } 3796 return ArraysPlume.subarray(intermediate, 0, length); 3797 } 3798 3799 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 3800 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3801 @Pure 3802 public static boolean setEqual(double @Nullable [] seq1, double @Nullable [] seq2) { 3803 if (seq1 == null) { 3804 return false; 3805 } 3806 if (seq2 == null) { 3807 return false; 3808 } 3809 for (int i = 0; i < seq1.length ; i++) { 3810 if (!memberOf(seq1[i], seq2) ) { 3811 return false; 3812 } 3813 } 3814 for (int i = 0; i < seq2.length ; i++) { 3815 if (!memberOf(seq2[i], seq1) ) { 3816 return false; 3817 } 3818 } 3819 return true; 3820 } 3821 3822 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3823 @Pure 3824 public static boolean setEqual(double @Nullable [] seq1, float @Nullable [] seq2) { 3825 if (seq1 == null) { 3826 return false; 3827 } 3828 if (seq2 == null) { 3829 return false; 3830 } 3831 for (int i = 0; i < seq1.length ; i++) { 3832 if (!memberOf(seq1[i], seq2) ) { 3833 return false; 3834 } 3835 } 3836 for (int i = 0; i < seq2.length ; i++) { 3837 if (!memberOf(seq2[i], seq1) ) { 3838 return false; 3839 } 3840 } 3841 return true; 3842 } 3843 3844 /** True iff seq1 is the reverse of seq2. 3845 * 3846 * Meaning (in pseudo-FOL): 3847 * 3848 * <pre> 3849 * /\ seq1.length == seq2.length 3850 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 3851 * </pre> 3852 * 3853 */ 3854 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3855 @Pure 3856 public static boolean isReverse(double[] seq1, double[] seq2) { 3857 if (!sameLength(seq1, seq2)) { 3858 return false; 3859 } 3860 assert seq1 != null && seq2 != null; // because sameLength() = true 3861 int length = seq1.length; 3862 for (int i = 0 ; i < length ; i++) { 3863 if (ne(seq1[i], seq2[length - i - 1])) { 3864 return false; 3865 } 3866 } 3867 return true; 3868 } 3869 3870 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3871 @Pure 3872 public static boolean isReverse(double @Nullable [] seq1, float @Nullable [] seq2) { 3873 if (!sameLength(seq1, seq2)) { 3874 return false; 3875 } 3876 assert seq1 != null && seq2 != null; // because sameLength() = true 3877 int length = seq1.length; 3878 for (int i = 0 ; i < length ; i++) { 3879 if (ne(seq1[i], seq2[length - i - 1])) { 3880 return false; 3881 } 3882 } 3883 return true; 3884 } 3885 3886 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 3887 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3888 @Pure 3889 public static boolean subsetOf(double @Nullable [] seq1, double @Nullable [] seq2) { 3890 if (seq1 == null) { 3891 return false; 3892 } 3893 if (seq2 == null) { 3894 return false; 3895 } 3896 for (int i = 0 ; i < seq1.length ; i++) { 3897 if (!memberOf(seq1[i], seq2)) { 3898 return false; 3899 } 3900 } 3901 return true; 3902 } 3903 3904 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 3905 @Pure 3906 public static boolean subsetOf(double @Nullable [] seq1, float @Nullable [] seq2) { 3907 if (seq1 == null) { 3908 return false; 3909 } 3910 if (seq2 == null) { 3911 return false; 3912 } 3913 for (int i = 0 ; i < seq1.length ; i++) { 3914 if (!memberOf(seq1[i], seq2)) { 3915 return false; 3916 } 3917 } 3918 return true; 3919 } 3920 3921 /** Returns true iff seq contains no duplicate elements. */ 3922 @EnsuresNonNullIf(result=true, expression="#1") 3923 @Pure 3924 public static boolean noDups(double @Nullable [] seq) { 3925 if (seq == null) { 3926 return false; 3927 } 3928 return ArraysPlume.noDuplicates(seq); 3929 } 3930 3931 /** Returns true iff elt is in array arr. */ 3932 @EnsuresNonNullIf(result=true, expression="#2") 3933 @Pure 3934 public static boolean memberOf(double elt, double @Nullable [] arr) { 3935 if (arr == null) { 3936 return false; 3937 } 3938 for (int i = 0 ; i < arr.length ; i++) { 3939 if (eq(arr[i], elt)) { 3940 return true; 3941 } 3942 } 3943 return false; 3944 } 3945 3946 @EnsuresNonNullIf(result=true, expression="#2") 3947 @Pure 3948 public static boolean memberOf(double elt, float @Nullable [] arr) { 3949 if (arr == null) { 3950 return false; 3951 } 3952 for (int i = 0 ; i < arr.length ; i++) { 3953 if (eq(arr[i], elt)) { 3954 return true; 3955 } 3956 } 3957 return false; 3958 } 3959 3960 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 3961 @Pure 3962 public static double @PolyNull [] slice(double @PolyNull [] seq, int start, int end) { 3963 if (seq == null) { 3964 return null; 3965 } 3966 int sliceStart = start; 3967 int sliceEnd = end; 3968 if (start < 0) { 3969 return new double[] { }; 3970 } 3971 if (end > seq.length - 1) { 3972 return new double[] { }; 3973 } 3974 if (sliceStart > sliceEnd) { 3975 return new double[] { }; 3976 } 3977 int length = sliceEnd - sliceStart + 1; 3978 return ArraysPlume.subarray(seq, sliceStart, length); 3979 } 3980 3981 @Pure 3982 public static double @PolyNull [] slice(double @PolyNull [] seq, long start, int end) { 3983 return slice(seq, (int)start, end); 3984 } 3985 @Pure 3986 public static double @PolyNull [] slice(double @PolyNull [] seq, int start, long end) { 3987 return slice(seq, start, (int)end); 3988 } 3989 @Pure 3990 public static double @PolyNull [] slice(double @PolyNull [] seq, long start, long end) { 3991 return slice(seq, (int)start, (int)end); 3992 } 3993 3994 /** True iff all elements in arr equal elt. 3995 * 3996 * Meaning (in pseudo-FOL): 3997 * 3998 * forall i in { 0..arr.length-1 } : arr[i] == elt 3999 * 4000 */ 4001 @EnsuresNonNullIf(result=true, expression="#1") 4002 @Pure 4003 public static boolean eltsEqual(double @Nullable [] arr, double elt) { 4004 if (arr == null) { 4005 return false; 4006 } 4007 for (int i = 0 ; i < arr.length ; i++) { 4008 if (ne(arr[i], elt)) { 4009 return false; 4010 } 4011 } 4012 return true; 4013 } 4014 4015 @EnsuresNonNullIf(result=true, expression="#1") 4016 @Pure 4017 public static boolean eltsEqual(double @Nullable [] arr, float elt) { 4018 if (arr == null) { 4019 return false; 4020 } 4021 for (int i = 0 ; i < arr.length ; i++) { 4022 if (ne(arr[i], elt)) { 4023 return false; 4024 } 4025 } 4026 return true; 4027 } 4028 4029 /** True iff every element in arr does not equal elt. 4030 * 4031 * Meaning (in pseudo-FOL): 4032 * 4033 * forall i in { 0..arr.length-1 } : arr[i] != elt 4034 * 4035 */ 4036 @EnsuresNonNullIf(result=true, expression="#1") 4037 @Pure 4038 public static boolean eltsNotEqual(double @Nullable [] arr, double elt) { 4039 if (arr == null) { 4040 return false; 4041 } 4042 for (int i = 0 ; i < arr.length ; i++) { 4043 if (eq(arr[i], elt)) { 4044 return false; 4045 } 4046 } 4047 return true; 4048 } 4049 4050 @EnsuresNonNullIf(result=true, expression="#1") 4051 @Pure 4052 public static boolean eltsNotEqual(double @Nullable [] arr, float elt) { 4053 if (arr == null) { 4054 return false; 4055 } 4056 for (int i = 0 ; i < arr.length ; i++) { 4057 if (eq(arr[i], elt)) { 4058 return false; 4059 } 4060 } 4061 return true; 4062 } 4063 4064 /** True iff every element in arr is greater than elt. 4065 * 4066 * Meaning (in pseudo-FOL): 4067 * 4068 * forall i in { 0..arr.length-1 } : arr[i] > elt 4069 * 4070 */ 4071 @EnsuresNonNullIf(result=true, expression="#1") 4072 @Pure 4073 public static boolean eltsGT(double @Nullable [] arr, double elt) { 4074 if (arr == null) { 4075 return false; 4076 } 4077 for (int i = 0 ; i < arr.length ; i++) { 4078 if (lte(arr[i], elt)) { 4079 return false; 4080 } 4081 } 4082 return true; 4083 } 4084 4085 @EnsuresNonNullIf(result=true, expression="#1") 4086 @Pure 4087 public static boolean eltsGT(double @Nullable [] arr, float elt) { 4088 if (arr == null) { 4089 return false; 4090 } 4091 for (int i = 0 ; i < arr.length ; i++) { 4092 if (lte(arr[i], elt)) { 4093 return false; 4094 } 4095 } 4096 return true; 4097 } 4098 4099 /** True iff every element in arr is greater than or equal to elt. 4100 * 4101 * Meaning (in pseudo-FOL): 4102 * 4103 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 4104 * 4105 */ 4106 @EnsuresNonNullIf(result=true, expression="#1") 4107 @Pure 4108 public static boolean eltsGTE(double @Nullable [] arr, double elt) { 4109 if (arr == null) { 4110 return false; 4111 } 4112 for (int i = 0 ; i < arr.length ; i++) { 4113 if (lt(arr[i], elt)) { 4114 return false; 4115 } 4116 } 4117 return true; 4118 } 4119 4120 @EnsuresNonNullIf(result=true, expression="#1") 4121 @Pure 4122 public static boolean eltsGTE(double @Nullable [] arr, float elt) { 4123 if (arr == null) { 4124 return false; 4125 } 4126 for (int i = 0 ; i < arr.length ; i++) { 4127 if (lt(arr[i], elt)) { 4128 return false; 4129 } 4130 } 4131 return true; 4132 } 4133 4134 /** True iff every element in arr is less than elt. 4135 * 4136 * Meaning (in pseudo-FOL): 4137 * 4138 * forall i in { 0..arr.length-1 } : arr[i] < elt 4139 * 4140 */ 4141 @EnsuresNonNullIf(result=true, expression="#1") 4142 @Pure 4143 public static boolean eltsLT(double @Nullable [] arr, double elt) { 4144 if (arr == null) { 4145 return false; 4146 } 4147 for (int i = 0 ; i < arr.length ; i++) { 4148 if (gte(arr[i], elt)) { 4149 return false; 4150 } 4151 } 4152 return true; 4153 } 4154 4155 @EnsuresNonNullIf(result=true, expression="#1") 4156 @Pure 4157 public static boolean eltsLT(double @Nullable [] arr, float elt) { 4158 if (arr == null) { 4159 return false; 4160 } 4161 for (int i = 0 ; i < arr.length ; i++) { 4162 if (gte(arr[i], elt)) { 4163 return false; 4164 } 4165 } 4166 return true; 4167 } 4168 4169 /** True iff every element in arr is less than or equal to elt. 4170 * 4171 * Meaning (in pseudo-FOL): 4172 * 4173 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 4174 * 4175 */ 4176 @EnsuresNonNullIf(result=true, expression="#1") 4177 @Pure 4178 public static boolean eltsLTE(double @Nullable [] arr, double elt) { 4179 if (arr == null) { 4180 return false; 4181 } 4182 for (int i = 0 ; i < arr.length ; i++) { 4183 if (gt(arr[i], elt)) { 4184 return false; 4185 } 4186 } 4187 return true; 4188 } 4189 4190 @EnsuresNonNullIf(result=true, expression="#1") 4191 @Pure 4192 public static boolean eltsLTE(double @Nullable [] arr, float elt) { 4193 if (arr == null) { 4194 return false; 4195 } 4196 for (int i = 0 ; i < arr.length ; i++) { 4197 if (gt(arr[i], elt)) { 4198 return false; 4199 } 4200 } 4201 return true; 4202 } 4203 4204 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 4205 * 4206 * Meaning (in pseudo-FOL): 4207 * 4208 * /\ seq1.length == se2.length 4209 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 4210 * 4211 */ 4212 4213 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4214 @Pure 4215 public static boolean pairwiseEqual(double @Nullable [] seq1, double @Nullable [] seq2) { 4216 if (!sameLength(seq1, seq2)) { 4217 return false; 4218 } 4219 assert seq1 != null && seq2 != null; // because sameLength() = true 4220 for (int i = 0 ; i < seq1.length ; i++) { 4221 if (Double.isNaN(seq1[i]) && Double.isNaN(seq2[i])) { 4222 continue; 4223 } 4224 if (ne(seq1[i], seq2[i])) { 4225 return false; 4226 } 4227 } 4228 return true; 4229 } 4230 4231 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4232 @Pure 4233 public static boolean pairwiseEqual(double @Nullable [] seq1, float @Nullable [] seq2) { 4234 if (!sameLength(seq1, seq2)) { 4235 return false; 4236 } 4237 assert seq1 != null && seq2 != null; // because sameLength() = true 4238 for (int i = 0 ; i < seq1.length ; i++) { 4239 if (ne(seq1[i], seq2[i])) { 4240 return false; 4241 } 4242 } 4243 return true; 4244 } 4245 4246 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 4247 * 4248 * Meaning (in pseudo-FOL): 4249 * 4250 * /\ seq1.length == se2.length 4251 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 4252 * 4253 */ 4254 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4255 @Pure 4256 public static boolean pairwiseNotEqual(double @Nullable [] seq1, double @Nullable [] seq2) { 4257 if (!sameLength(seq1, seq2)) { 4258 return false; 4259 } 4260 assert seq1 != null && seq2 != null; // because sameLength() = true 4261 for (int i = 0 ; i < seq1.length ; i++) { 4262 if (eq(seq1[i], seq2[i])) { 4263 return false; 4264 } 4265 } 4266 return true; 4267 } 4268 4269 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4270 @Pure 4271 public static boolean pairwiseNotEqual(double @Nullable [] seq1, float @Nullable [] seq2) { 4272 if (!sameLength(seq1, seq2)) { 4273 return false; 4274 } 4275 assert seq1 != null && seq2 != null; // because sameLength() = true 4276 for (int i = 0 ; i < seq1.length ; i++) { 4277 if (eq(seq1[i], seq2[i])) { 4278 return false; 4279 } 4280 } 4281 return true; 4282 } 4283 4284 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 4285 * 4286 * Meaning (in pseudo-FOL): 4287 * 4288 * /\ seq1.length == se2.length 4289 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 4290 * 4291 */ 4292 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4293 @Pure 4294 public static boolean pairwiseLT(double @Nullable [] seq1, double @Nullable [] seq2) { 4295 if (!sameLength(seq1, seq2)) { 4296 return false; 4297 } 4298 assert seq1 != null && seq2 != null; // because sameLength() = true 4299 for (int i = 0 ; i < seq1.length ; i++) { 4300 if (gte(seq1[i], seq2[i])) { 4301 return false; 4302 } 4303 } 4304 return true; 4305 } 4306 4307 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4308 @Pure 4309 public static boolean pairwiseLT(double @Nullable [] seq1, float @Nullable [] seq2) { 4310 if (!sameLength(seq1, seq2)) { 4311 return false; 4312 } 4313 assert seq1 != null && seq2 != null; // because sameLength() = true 4314 for (int i = 0 ; i < seq1.length ; i++) { 4315 if (gte(seq1[i], seq2[i])) { 4316 return false; 4317 } 4318 } 4319 return true; 4320 } 4321 4322 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 4323 * Meaning (in pseudo-FOL): 4324 * 4325 * /\ seq1.length == se2.length 4326 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 4327 * 4328 */ 4329 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4330 @Pure 4331 public static boolean pairwiseLTE(double @Nullable [] seq1, double @Nullable [] seq2) { 4332 if (!sameLength(seq1, seq2)) { 4333 return false; 4334 } 4335 assert seq1 != null && seq2 != null; // because sameLength() = true 4336 for (int i = 0 ; i < seq1.length ; i++) { 4337 if (gt(seq1[i], seq2[i])) { 4338 return false; 4339 } 4340 } 4341 return true; 4342 } 4343 4344 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4345 @Pure 4346 public static boolean pairwiseLTE(double @Nullable [] seq1, float @Nullable [] seq2) { 4347 if (!sameLength(seq1, seq2)) { 4348 return false; 4349 } 4350 assert seq1 != null && seq2 != null; // because sameLength() = true 4351 for (int i = 0 ; i < seq1.length ; i++) { 4352 if (gt(seq1[i], seq2[i])) { 4353 return false; 4354 } 4355 } 4356 return true; 4357 } 4358 4359 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 4360 * Meaning (in pseudo-FOL): 4361 * 4362 * /\ seq1.length == se2.length 4363 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 4364 * 4365 */ 4366 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4367 @Pure 4368 public static boolean pairwiseGT(double @Nullable [] seq1, double @Nullable [] seq2) { 4369 if (!sameLength(seq1, seq2)) { 4370 return false; 4371 } 4372 assert seq1 != null && seq2 != null; // because sameLength() = true 4373 for (int i = 0 ; i < seq1.length ; i++) { 4374 if (lte(seq1[i], seq2[i])) { 4375 return false; 4376 } 4377 } 4378 return true; 4379 } 4380 4381 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4382 @Pure 4383 public static boolean pairwiseGT(double @Nullable [] seq1, float @Nullable [] seq2) { 4384 if (!sameLength(seq1, seq2)) { 4385 return false; 4386 } 4387 assert seq1 != null && seq2 != null; // because sameLength() = true 4388 for (int i = 0 ; i < seq1.length ; i++) { 4389 if (lte(seq1[i], seq2[i])) { 4390 return false; 4391 } 4392 } 4393 return true; 4394 } 4395 4396 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 4397 * Meaning (in pseudo-FOL): 4398 * 4399 * /\ seq1.length == se2.length 4400 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 4401 * 4402 */ 4403 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4404 @Pure 4405 public static boolean pairwiseGTE(double @Nullable [] seq1, double @Nullable [] seq2) { 4406 if (!sameLength(seq1, seq2)) { 4407 return false; 4408 } 4409 assert seq1 != null && seq2 != null; // because sameLength() = true 4410 for (int i = 0 ; i < seq1.length ; i++) { 4411 if (lt(seq1[i], seq2[i])) { 4412 return false; 4413 } 4414 } 4415 return true; 4416 } 4417 4418 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4419 @Pure 4420 public static boolean pairwiseGTE(double @Nullable [] seq1, float @Nullable [] seq2) { 4421 if (!sameLength(seq1, seq2)) { 4422 return false; 4423 } 4424 assert seq1 != null && seq2 != null; // because sameLength() = true 4425 for (int i = 0 ; i < seq1.length ; i++) { 4426 if (lt(seq1[i], seq2[i])) { 4427 return false; 4428 } 4429 } 4430 return true; 4431 } 4432 4433 /** 4434 * Returns true iff seq1 is lexically equal to seq2. 4435 * For equality, "lexically" and "pairwise" are the same. 4436 */ 4437 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4438 @Pure 4439 public static boolean lexEqual(double @Nullable [] seq1, double @Nullable [] seq2) { 4440 if (seq1 == null) { 4441 return false; 4442 } 4443 if (seq2 == null) { 4444 return false; 4445 } 4446 return pairwiseEqual(seq1, seq2); 4447 } 4448 4449 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4450 @Pure 4451 public static boolean lexEqual(double @Nullable [] seq1, float @Nullable [] seq2) { 4452 if (seq1 == null) { 4453 return false; 4454 } 4455 if (seq2 == null) { 4456 return false; 4457 } 4458 return pairwiseEqual(seq1, seq2); 4459 } 4460 4461 /** Returns true iff seq1 is lexically not equal to seq2. */ 4462 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4463 @Pure 4464 public static boolean lexNotEqual(double @Nullable [] seq1, double @Nullable [] seq2) { 4465 if (seq1 == null) { 4466 return false; 4467 } 4468 if (seq2 == null) { 4469 return false; 4470 } 4471 return !lexEqual(seq1, seq2); 4472 } 4473 4474 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4475 @Pure 4476 public static boolean lexNotEqual(double @Nullable [] seq1, float @Nullable [] seq2) { 4477 if (seq1 == null) { 4478 return false; 4479 } 4480 if (seq2 == null) { 4481 return false; 4482 } 4483 return !lexEqual(seq1, seq2); 4484 } 4485 4486 /** Returns true iff seq1 is lexically < seq2. */ 4487 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4488 @Pure 4489 public static boolean lexLT(double @Nullable [] seq1, double @Nullable [] seq2) { 4490 if (seq1 == null) { 4491 return false; 4492 } 4493 if (seq2 == null) { 4494 return false; 4495 } 4496 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4497 for (int i = 0 ; i < minlength ; i++) { 4498 if (gt(seq1[i], seq2[i])) { 4499 return false; 4500 } else if (lt(seq1[i], seq2[i])) { 4501 return true; 4502 } 4503 } 4504 if (seq1.length >= seq2.length) { 4505 return false; 4506 } 4507 return true; 4508 } 4509 4510 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4511 @Pure 4512 public static boolean lexLT(double @Nullable [] seq1, float @Nullable [] seq2) { 4513 if (seq1 == null) { 4514 return false; 4515 } 4516 if (seq2 == null) { 4517 return false; 4518 } 4519 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4520 for (int i = 0 ; i < minlength ; i++) { 4521 if (gt(seq1[i], seq2[i])) { 4522 return false; 4523 } else if (lt(seq1[i], seq2[i])) { 4524 return true; 4525 } 4526 } 4527 if (seq1.length >= seq2.length) { 4528 return false; 4529 } 4530 return true; 4531 } 4532 4533 /** Returns true iff seq1 is lexically ≤ to seq2. */ 4534 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4535 @Pure 4536 public static boolean lexLTE(double @Nullable [] seq1, double @Nullable [] seq2) { 4537 if (seq1 == null) { 4538 return false; 4539 } 4540 if (seq2 == null) { 4541 return false; 4542 } 4543 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4544 for (int i = 0 ; i < minlength ; i++) { 4545 if (gt(seq1[i], seq2[i])) { 4546 return false; 4547 } else if (lt(seq1[i], seq2[i])) { 4548 return true; 4549 } 4550 } 4551 if (seq1.length > seq2.length) { 4552 return false; 4553 } 4554 return true; 4555 } 4556 4557 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4558 @Pure 4559 public static boolean lexLTE(double @Nullable [] seq1, float @Nullable [] seq2) { 4560 if (seq1 == null) { 4561 return false; 4562 } 4563 if (seq2 == null) { 4564 return false; 4565 } 4566 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4567 for (int i = 0 ; i < minlength ; i++) { 4568 if (gt(seq1[i], seq2[i])) { 4569 return false; 4570 } else if (lt(seq1[i], seq2[i])) { 4571 return true; 4572 } 4573 } 4574 if (seq1.length > seq2.length) { 4575 return false; 4576 } 4577 return true; 4578 } 4579 4580 /** Returns true iff seq1 is lexically > to seq2. */ 4581 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4582 @Pure 4583 public static boolean lexGT(double @Nullable [] seq1, double @Nullable [] seq2) { 4584 if (seq1 == null) { 4585 return false; 4586 } 4587 if (seq2 == null) { 4588 return false; 4589 } 4590 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4591 for (int i = 0 ; i < minlength ; i++) { 4592 if (lt(seq1[i], seq2[i])) { 4593 return false; 4594 } else if (gt(seq1[i], seq2[i])) { 4595 return true; 4596 } 4597 } 4598 if (seq1.length <= seq2.length) { 4599 return false; 4600 } 4601 return true; 4602 } 4603 4604 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4605 @Pure 4606 public static boolean lexGT(double @Nullable [] seq1, float @Nullable [] seq2) { 4607 if (seq1 == null) { 4608 return false; 4609 } 4610 if (seq2 == null) { 4611 return false; 4612 } 4613 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4614 for (int i = 0 ; i < minlength ; i++) { 4615 if (lt(seq1[i], seq2[i])) { 4616 return false; 4617 } else if (gt(seq1[i], seq2[i])) { 4618 return true; 4619 } 4620 } 4621 if (seq1.length <= seq2.length) { 4622 return false; 4623 } 4624 return true; 4625 } 4626 4627 /** Returns true iff seq1 is lexically ≥ to seq2. */ 4628 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4629 @Pure 4630 public static boolean lexGTE(double @Nullable [] seq1, double @Nullable [] seq2) { 4631 if (seq1 == null) { 4632 return false; 4633 } 4634 if (seq2 == null) { 4635 return false; 4636 } 4637 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4638 for (int i = 0 ; i < minlength ; i++) { 4639 if (lt(seq1[i], seq2[i])) { 4640 return false; 4641 } else if (gt(seq1[i], seq2[i])) { 4642 return true; 4643 } 4644 } 4645 if (seq1.length < seq2.length) { 4646 return false; 4647 } 4648 return true; 4649 } 4650 4651 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 4652 @Pure 4653 public static boolean lexGTE(double @Nullable [] seq1, float @Nullable [] seq2) { 4654 if (seq1 == null) { 4655 return false; 4656 } 4657 if (seq2 == null) { 4658 return false; 4659 } 4660 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 4661 for (int i = 0 ; i < minlength ; i++) { 4662 if (lt(seq1[i], seq2[i])) { 4663 return false; 4664 } else if (gt(seq1[i], seq2[i])) { 4665 return true; 4666 } 4667 } 4668 if (seq1.length < seq2.length) { 4669 return false; 4670 } 4671 return true; 4672 } 4673 4674 /** True iff for all applicable i, every seq[i] == seq[i+1]. 4675 * 4676 * Meaning (in pseudo-FOL): 4677 * 4678 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 4679 * 4680 */ 4681 @EnsuresNonNullIf(result=true, expression="#1") 4682 @Pure 4683 public static boolean eltwiseEqual(double @Nullable [] seq) { 4684 if (seq == null) { 4685 return false; 4686 } 4687 for (int i = 0 ; i < seq.length ; i++) { 4688 if (i < seq.length - 1) { 4689 if (ne(seq[i], seq[i + 1])) { 4690 return false; 4691 } 4692 } 4693 } 4694 return true; 4695 } 4696 4697 /** True iff for all applicable i, every seq[i] != seq[i+1]. 4698 * 4699 * Meaning (in pseudo-FOL): 4700 * 4701 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 4702 * 4703 */ 4704 @EnsuresNonNullIf(result=true, expression="#1") 4705 @Pure 4706 public static boolean eltwiseNotEqual(double @Nullable [] seq) { 4707 if (seq == null) { 4708 return false; 4709 } 4710 for (int i = 0 ; i < seq.length ; i++) { 4711 if (i < seq.length - 1) { 4712 if (eq(seq[i], seq[i + 1])) { 4713 return false; 4714 } 4715 } 4716 } 4717 return true; 4718 } 4719 4720 /** True iff for all applicable i, every seq[i] < seq[i+1]. 4721 * 4722 * Meaning (in pseudo-FOL): 4723 * 4724 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 4725 * 4726 */ 4727 @EnsuresNonNullIf(result=true, expression="#1") 4728 @Pure 4729 public static boolean eltwiseLT(double @Nullable [] seq) { 4730 if (seq == null) { 4731 return false; 4732 } 4733 for (int i = 0 ; i < seq.length ; i++) { 4734 if (i < seq.length - 1) { 4735 if (gte(seq[i], seq[i + 1])) { 4736 return false; 4737 } 4738 } 4739 } 4740 return true; 4741 } 4742 4743 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 4744 * 4745 * Meaning (in pseudo-FOL): 4746 * 4747 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 4748 * 4749 */ 4750 @EnsuresNonNullIf(result=true, expression="#1") 4751 @Pure 4752 public static boolean eltwiseLTE(double @Nullable [] seq) { 4753 if (seq == null) { 4754 return false; 4755 } 4756 for (int i = 0 ; i < seq.length ; i++) { 4757 if (i < seq.length - 1) { 4758 if (gt(seq[i], seq[i + 1])) { 4759 return false; 4760 } 4761 } 4762 } 4763 return true; 4764 } 4765 4766 /** True iff for all applicable i, every seq[i] > seq[i+1]. 4767 * 4768 * Meaning (in pseudo-FOL): 4769 * 4770 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 4771 * 4772 */ 4773 @EnsuresNonNullIf(result=true, expression="#1") 4774 @Pure 4775 public static boolean eltwiseGT(double @Nullable [] seq) { 4776 if (seq == null) { 4777 return false; 4778 } 4779 for (int i = 0 ; i < seq.length ; i++) { 4780 if (i < seq.length - 1) { 4781 if (lte(seq[i], seq[i + 1])) { 4782 return false; 4783 } 4784 } 4785 } 4786 return true; 4787 } 4788 4789 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 4790 * 4791 * Meaning (in pseudo-FOL): 4792 * 4793 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 4794 * 4795 */ 4796 @EnsuresNonNullIf(result=true, expression="#1") 4797 @Pure 4798 public static boolean eltwiseGTE(double @Nullable [] seq) { 4799 if (seq == null) { 4800 return false; 4801 } 4802 for (int i = 0 ; i < seq.length ; i++) { 4803 if (i < seq.length - 1) { 4804 if (lt(seq[i], seq[i + 1])) { 4805 return false; 4806 } 4807 } 4808 } 4809 return true; 4810 } 4811 4812 /** True iff for all applicable i, every seq[i] == i. 4813 * 4814 * Meaning (in pseudo-FOL): 4815 * 4816 * forall i in { 0..seq.length-1 } : seq[i] == i 4817 * 4818 */ 4819 @EnsuresNonNullIf(result=true, expression="#1") 4820 @Pure 4821 public static boolean eltsEqualIndex(double @Nullable [] seq) { 4822 if (seq == null) { 4823 return false; 4824 } 4825 for (int i = 0 ; i < seq.length ; i++) { 4826 if (ne(seq[i], i)) { 4827 return false; 4828 } 4829 } 4830 return true; 4831 } 4832 4833 /** True iff for all applicable i, every seq[i] != i. 4834 * 4835 * Meaning (in pseudo-FOL): 4836 * 4837 * forall i in { 0..seq.length-1 } : seq[i] != i 4838 * 4839 */ 4840 @EnsuresNonNullIf(result=true, expression="#1") 4841 @Pure 4842 public static boolean eltsNotEqualIndex(double @Nullable [] seq) { 4843 if (seq == null) { 4844 return false; 4845 } 4846 for (int i = 0 ; i < seq.length ; i++) { 4847 if (eq(seq[i], i)) { 4848 return false; 4849 } 4850 } 4851 return true; 4852 } 4853 4854 /** True iff for all applicable i, every seq[i] < i. 4855 * 4856 * Meaning (in pseudo-FOL): 4857 * 4858 * forall i in { 0..seq.length-1 } : seq[i] < i 4859 * 4860 */ 4861 @EnsuresNonNullIf(result=true, expression="#1") 4862 @Pure 4863 public static boolean eltsLtIndex(double @Nullable [] seq) { 4864 if (seq == null) { 4865 return false; 4866 } 4867 for (int i = 0 ; i < seq.length ; i++) { 4868 if (gte(seq[i], i)) { 4869 return false; 4870 } 4871 } 4872 return true; 4873 } 4874 4875 /** True iff for all applicable i, every seq[i] ≤ i. 4876 * 4877 * Meaning (in pseudo-FOL): 4878 * 4879 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 4880 * 4881 */ 4882 @EnsuresNonNullIf(result=true, expression="#1") 4883 @Pure 4884 public static boolean eltsLteIndex(double @Nullable [] seq) { 4885 if (seq == null) { 4886 return false; 4887 } 4888 for (int i = 0 ; i < seq.length ; i++) { 4889 if (gt(seq[i], i)) { 4890 return false; 4891 } 4892 } 4893 return true; 4894 } 4895 4896 /** True iff for all applicable i, every seq[i] > i. 4897 * 4898 * Meaning (in pseudo-FOL): 4899 * 4900 * forall i in { 0..seq.length-1 } : seq[i] > i 4901 * 4902 */ 4903 @EnsuresNonNullIf(result=true, expression="#1") 4904 @Pure 4905 public static boolean eltsGtIndex(double @Nullable [] seq) { 4906 if (seq == null) { 4907 return false; 4908 } 4909 for (int i = 0 ; i < seq.length ; i++) { 4910 if (lte(seq[i], i)) { 4911 return false; 4912 } 4913 } 4914 return true; 4915 } 4916 4917 /** True iff for all applicable i, every seq[i] ≥ i. 4918 * 4919 * Meaning (in pseudo-FOL): 4920 * 4921 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 4922 * 4923 */ 4924 @EnsuresNonNullIf(result=true, expression="#1") 4925 @Pure 4926 public static boolean eltsGteIndex(double @Nullable [] seq) { 4927 if (seq == null) { 4928 return false; 4929 } 4930 for (int i = 0 ; i < seq.length ; i++) { 4931 if (lt(seq[i], i)) { 4932 return false; 4933 } 4934 } 4935 return true; 4936 } 4937 4938 /// Deferencing (accessing) fields 4939 4940 /** 4941 * collectdouble accepts an object and a list of fields (one of which is of array type, and the 4942 * rest of which are not), and produces an array in which the original object has had the given 4943 * fields accessed. 4944 * 4945 * <p>Daikon creates invariants over "variables" such as the following. 4946 * 4947 * <dl> 4948 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 4949 * for all y's in array x.arr.</dd> 4950 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 4951 * for all x's in array arr.</dd> 4952 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 4953 * </dl> 4954 * 4955 * <p>The collectdouble() method does this collecting work. 4956 * 4957 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 4958 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 4959 * elements that result from following the fields, one of which is assumed to be an array. 4960 * 4961 * <p> 4962 * requires: fieldStr.length() > 0 and object != null 4963 * <p> 4964 * requires: fieldStr contains only field names, no "[]" strings. 4965 * <p> 4966 * requires: the method only works for field sequences with exactly one field representing an 4967 * array. For example, the collection a[].b[].c will fail. 4968 * 4969 * @return if the resulting collection is of non-primitive type, then returns an array of type 4970 * Object[]. Returns null if any array or field access causes an exception. 4971 */ 4972 4973 @SideEffectFree 4974 public static double @Nullable [] collectdouble(@Nullable Object object, @Nullable String fieldStr) { 4975 4976 if (object == null) { 4977 return null; 4978 } 4979 if (fieldStr == null) { 4980 return null; 4981 } 4982 4983 // assert fieldStr != null && !"".equals(fieldStr); 4984 String[] fieldNames = fieldStr.split("\\."); 4985 double[] retval = collectdouble(object, fieldNames, 0); 4986 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 4987 return retval; 4988 } 4989 4990 /** Helper method for collectdouble(Object, String). 4991 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 4992 * @see collectdouble(Object, String) 4993 */ 4994 // @PolyNull does not work for return type, because null is returned on error. 4995 @SideEffectFree 4996 private static double @Nullable [] collectdouble(@Nullable Object object, 4997 String[] fields, int fieldsStartIdx) { 4998 4999 if (object == null) { 5000 return null; 5001 } 5002 assert (fields != null); 5003 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 5004 5005 Object fieldObj; 5006 try { 5007 Field field = (object instanceof java.lang.Class<?>) 5008 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 5009 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 5010 field.setAccessible(true); 5011 // Class cls = field.getType(); 5012 fieldObj = field.get(object); 5013 // System.out.println("***fieldObj="+fieldObj); 5014 5015 } catch (Exception e) { 5016 return null; 5017 5018 } 5019 5020 if (fieldObj == null) { 5021 return null; 5022 } 5023 5024 // base case: just accessed the last field 5025 if (fields.length - 1 == fieldsStartIdx) { 5026 5027 if (fieldObj.getClass().isArray()) { 5028 // last field is an array 5029 return (double[])fieldObj; 5030 } else { 5031 // This hack should be removed in favor of, at "oneEltArray = ..." 5032 // below, calling a version of collectdouble_field that throws an 5033 // error. Then, this case becomes a run-time error. -MDE 5034 5035 // Just one element; return a one-element array. 5036 // assert cls.equals(Double.TYPE); 5037 return new double[] { ((Double)fieldObj).doubleValue() }; 5038 } 5039 } else { 5040 // recursive case: more fields to access after this one 5041 5042 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 5043 5044 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 5045 double[] intermediate = new double[collection.size()]; 5046 int index = 0; 5047 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 5048 Object obj = i.next(); 5049 double[] oneEltArray = collectdouble(obj, fields, fieldsStartIdx + 1); 5050 if (oneEltArray == null) { 5051 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 5052 } 5053 // assert oneEltArray.length == 1; 5054 intermediate[index++] = oneEltArray[0]; 5055 } 5056 return intermediate; 5057 } else if (fieldObj.getClass().isArray()) { 5058 5059 // collect elements across array 5060 double[] intermediate = new double[Array.getLength(fieldObj)]; 5061 for (int i = 0 ; i < intermediate.length ; i++) { 5062 Object obj = Array.get(fieldObj, i); 5063 double[] oneEltArray = collectdouble(obj, fields, fieldsStartIdx + 1); 5064 if (oneEltArray == null) { 5065 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 5066 } 5067 // assert oneEltArray.length == 1; 5068 intermediate[i] = oneEltArray[0]; 5069 } 5070 return intermediate; 5071 } else { 5072 5073 return collectdouble(fieldObj, fields, fieldsStartIdx + 1); 5074 } 5075 } 5076 } 5077 5078 /** 5079 * Returns the results of dereferencing the fields for 'object'. For example, the call 5080 * 5081 * <pre>collectdouble_field(x, "f.g.h")</pre> 5082 * 5083 * has the same value as 5084 * 5085 * <pre>x.f.g.h</pre>. 5086 * Returns a default value if any field access causes an exception. 5087 */ 5088 @SideEffectFree 5089 public static double collectdouble_field(Object object, String fieldStr) { 5090 5091 if (object == null) { 5092 return Double.NaN; // return default value 5093 } 5094 if (fieldStr == null) { 5095 return Double.NaN; // return default value 5096 } 5097 5098 String[] fieldNames = fieldStr.split("\\."); 5099 5100 // Holds the intermediate (and final) result 5101 Object fieldObj = object; 5102 5103 for (int i = 0 ; i < fieldNames.length ; i++) { 5104 5105 String fieldName = fieldNames[i]; 5106 5107 try { 5108 Field field = 5109 (fieldObj instanceof java.lang.Class<?>) 5110 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 5111 : fieldObj.getClass().getDeclaredField(fieldName); 5112 field.setAccessible(true); 5113 fieldObj = field.get(fieldObj); 5114 5115 if (fieldObj == null) { 5116 return Double.NaN; // return default value 5117 } 5118 5119 } catch (Exception e) { 5120 return Double.NaN; // return default value 5121 5122 } 5123 5124 } 5125 5126 return ((Double)fieldObj).doubleValue(); 5127 } 5128 5129 /////////////////////////////////////////////////////////////////////////// 5130 /// Methods for "float" (from QuantBody.java.jpp) 5131 /// 5132 5133 /** 5134 * Returns the ith element of the array or collection argument. If the argument is null or not an 5135 * array or collection, returns a default value (Float.NaN). 5136 */ 5137 5138 @Pure 5139 public static float getElement_float(Object o, long i) { 5140 if (o == null) { 5141 return Float.NaN; // return default value 5142 } 5143 java.lang.Class<?> c = o.getClass(); 5144 if (c.isArray()) { 5145 return java.lang.reflect.Array.getFloat(o, (int)i); 5146 } else if (o instanceof java.util.AbstractCollection<?>) { 5147 return java.lang.reflect.Array.getFloat(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 5148 } else { 5149 return Float.NaN; // return default value 5150 } 5151 } 5152 5153 @Pure 5154 public static float getElement_float(float[] arr, long i) { 5155 if (arr == null) { 5156 return Float.NaN; // return default value 5157 } 5158 return arr[(int)i]; 5159 } 5160 5161 private static boolean eq(float x, float y) { 5162 return fuzzy.eq(x,y); 5163 } 5164 5165 private static boolean ne(float x, float y) { 5166 return fuzzy.ne(x,y); 5167 } 5168 5169 private static boolean lt(float x, float y) { 5170 return fuzzy.lt(x,y); 5171 } 5172 5173 private static boolean lte(float x, float y) { 5174 return fuzzy.lte(x,y); 5175 } 5176 5177 private static boolean gt(float x, float y) { 5178 return fuzzy.gt(x,y); 5179 } 5180 5181 private static boolean gte(float x, float y) { 5182 return fuzzy.gte(x,y); 5183 } 5184 5185 /** True iff both sequences are non-null and have the same length. */ 5186 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 5187 @Pure 5188 public static boolean sameLength(float @Nullable [] seq1, float @Nullable [] seq2) { 5189 return ((seq1 != null) 5190 && (seq2 != null) 5191 && seq1.length == seq2.length); 5192 } 5193 5194 /** True iff both sequences are non-null and have the same length. */ 5195 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 5196 @Pure 5197 public static boolean sameLength(float @Nullable [] seq1, double @Nullable [] seq2) { 5198 return ((seq1 != null) 5199 && (seq2 != null) 5200 && seq1.length == seq2.length); 5201 } 5202 5203 /** True iff both sequences have the same length, and all seq2[i] divide seq1[i]. 5204 * 5205 * Meaning (in pseudo-FOL): 5206 * 5207 * <pre> 5208 * /\ seq1.length == seq2.length 5209 * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i] 5210 * </pre> 5211 * 5212 */ 5213 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5214 @Pure 5215 public static boolean pairwiseDivides(float[] seq1, float[] seq2) { 5216 if (!sameLength(seq1, seq2)) { 5217 return false; 5218 } 5219 assert seq1 != null && seq2 != null; // because sameLength() = true 5220 for (int i = 0 ; i < seq1.length ; i++) { 5221 if (ne(seq1[i] % seq2[i], 0)) { 5222 return false; 5223 } 5224 } 5225 return true; 5226 } 5227 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5228 @Pure 5229 public static boolean pairwiseDivides(float[] seq1, double[] seq2) { 5230 if (!sameLength(seq1, seq2)) { 5231 return false; 5232 } 5233 assert seq1 != null && seq2 != null; // because sameLength() = true 5234 for (int i = 0 ; i < seq1.length ; i++) { 5235 if (ne(seq1[i] % seq2[i], 0)) { 5236 return false; 5237 } 5238 } 5239 return true; 5240 } 5241 5242 /** 5243 * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i]. 5244 * 5245 * Meaning (in pseudo-FOL): 5246 * 5247 * <pre> 5248 * /\ seq1.length == seq2.length 5249 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i] 5250 * </pre> 5251 * 5252 */ 5253 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5254 @Pure 5255 public static boolean pairwiseSquare(float[] seq1, float[] seq2) { 5256 if (!sameLength(seq1, seq2)) { 5257 return false; 5258 } 5259 assert seq1 != null && seq2 != null; // because sameLength() = true 5260 for (int i = 0 ; i < seq1.length ; i++) { 5261 if (ne(seq1[i], seq2[i] * seq2[i])) { 5262 return false; 5263 } 5264 } 5265 return true; 5266 } 5267 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5268 @Pure 5269 public static boolean pairwiseSquare(float[] seq1, double[] seq2) { 5270 if (!sameLength(seq1, seq2)) { 5271 return false; 5272 } 5273 assert seq1 != null && seq2 != null; // because sameLength() = true 5274 for (int i = 0 ; i < seq1.length ; i++) { 5275 5276 if (ne(seq1[i], seq2[i] * seq2[i])) { 5277 5278 return false; 5279 } 5280 } 5281 return true; 5282 } 5283 5284 /** 5285 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 5286 * 5287 * <p>If either array is null, returns null. If either array is empty, returns only those 5288 * elements in the other array. If both arrays are empty, returns a new empty array. 5289 */ 5290 @SideEffectFree 5291 public static float @PolyNull [] concat(float @PolyNull [] seq1, float @PolyNull [] seq2) { 5292 if (seq1 == null) { 5293 return null; 5294 } 5295 if (seq2 == null) { 5296 return null; 5297 } 5298 return ArraysPlume.concat(seq1, seq2); 5299 } 5300 5301 @SideEffectFree 5302 public static double @PolyNull [] concat(float @PolyNull [] seq1, double @PolyNull [] seq2) { 5303 if (seq1 == null) { 5304 return null; 5305 } 5306 if (seq2 == null) { 5307 return null; 5308 } 5309 // Cannot just use ArraysPlume.concat because the two arrays 5310 // have different types. This essentially inlines that method. 5311 int newLength = seq1.length + seq2.length; 5312 double[] retval = new double[newLength]; 5313 5314 for (int j = 0 ; j < seq1.length ; j++) { 5315 retval[j] = seq1[j]; 5316 } 5317 System.arraycopy(seq2, 0, retval, seq1.length, seq2.length); 5318 5319 return retval; 5320 } 5321 5322 /** 5323 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 5324 * assurances about the order or repetition of elements: elements may be repeated, and their 5325 * order may be different from the order of elements in seq1 and seq2. 5326 */ 5327 @SideEffectFree 5328 public static float @PolyNull [] union(float @PolyNull [] seq1, float @PolyNull [] seq2) { 5329 if (seq1 == null) { 5330 return null; 5331 } 5332 if (seq2 == null) { 5333 return null; 5334 } 5335 return concat(seq1, seq2); 5336 } 5337 5338 @Pure 5339 public static double @PolyNull [] union(float @PolyNull [] seq1, double @PolyNull [] seq2) { 5340 if (seq1 == null) { 5341 return null; 5342 } 5343 if (seq2 == null) { 5344 return null; 5345 } 5346 return concat(seq1, seq2); 5347 } 5348 5349 /** 5350 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 5351 * gives no assurances about the order or repetition of elements: elements may be repeated, and 5352 * their order may be different from the order of elements in seq1 and seq2. 5353 */ 5354 @Pure 5355 public static float @PolyNull [] intersection(float @PolyNull [] seq1, float @PolyNull [] seq2) { 5356 if (seq1 == null) { 5357 return null; 5358 } 5359 if (seq2 == null) { 5360 return null; 5361 } 5362 float[] intermediate = new float[Math.min(seq1.length, seq2.length)]; 5363 int length = 0; 5364 for (int i = 0 ; i < seq1.length ; i++) { 5365 if (memberOf(seq1[i], seq2) ) { 5366 intermediate[length++] = seq1[i]; 5367 } 5368 } 5369 return ArraysPlume.subarray(intermediate, 0, length); 5370 } 5371 5372 @Pure 5373 public static double @PolyNull [] intersection(float @PolyNull [] seq1, double @PolyNull [] seq2) { 5374 if (seq1 == null) { 5375 return null; 5376 } 5377 if (seq2 == null) { 5378 return null; 5379 } 5380 double[] intermediate = new double[Math.min(seq1.length, seq2.length)]; 5381 int length = 0; 5382 for (int i = 0 ; i < seq1.length ; i++) { 5383 if (memberOf(seq1[i], seq2) ) { 5384 intermediate[length++] = seq1[i]; 5385 } 5386 } 5387 return ArraysPlume.subarray(intermediate, 0, length); 5388 } 5389 5390 /** 5391 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 5392 * no assurances about the order or repetition of elements: elements may be repeated, and their 5393 * order may be different from the order of elements in seq1 and seq2. 5394 */ 5395 @Pure 5396 public static float @PolyNull [] setDiff(float @PolyNull [] seq1, float @PolyNull [] seq2) { 5397 if (seq1 == null) { 5398 return null; 5399 } 5400 if (seq2 == null) { 5401 return null; 5402 } 5403 float[] intermediate = new float[seq1.length]; 5404 int length = 0; 5405 for (int i = 0 ; i < seq1.length ; i++) { 5406 if (!memberOf(seq1[i], seq2)) { 5407 intermediate[length++] = seq1[i]; 5408 } 5409 } 5410 return ArraysPlume.subarray(intermediate, 0, length); 5411 } 5412 5413 @Pure 5414 public static double @PolyNull [] setDiff(float @PolyNull [] seq1, double @PolyNull [] seq2) { 5415 if (seq1 == null) { 5416 return null; 5417 } 5418 if (seq2 == null) { 5419 return null; 5420 } 5421 double[] intermediate = new double[seq1.length]; 5422 int length = 0; 5423 for (int i = 0 ; i < seq1.length ; i++) { 5424 if (!memberOf(seq1[i], seq2)) { 5425 intermediate[length++] = seq1[i]; 5426 } 5427 } 5428 return ArraysPlume.subarray(intermediate, 0, length); 5429 } 5430 5431 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 5432 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5433 @Pure 5434 public static boolean setEqual(float @Nullable [] seq1, float @Nullable [] seq2) { 5435 if (seq1 == null) { 5436 return false; 5437 } 5438 if (seq2 == null) { 5439 return false; 5440 } 5441 for (int i = 0; i < seq1.length ; i++) { 5442 if (!memberOf(seq1[i], seq2) ) { 5443 return false; 5444 } 5445 } 5446 for (int i = 0; i < seq2.length ; i++) { 5447 if (!memberOf(seq2[i], seq1) ) { 5448 return false; 5449 } 5450 } 5451 return true; 5452 } 5453 5454 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5455 @Pure 5456 public static boolean setEqual(float @Nullable [] seq1, double @Nullable [] seq2) { 5457 if (seq1 == null) { 5458 return false; 5459 } 5460 if (seq2 == null) { 5461 return false; 5462 } 5463 for (int i = 0; i < seq1.length ; i++) { 5464 if (!memberOf(seq1[i], seq2) ) { 5465 return false; 5466 } 5467 } 5468 for (int i = 0; i < seq2.length ; i++) { 5469 if (!memberOf(seq2[i], seq1) ) { 5470 return false; 5471 } 5472 } 5473 return true; 5474 } 5475 5476 /** True iff seq1 is the reverse of seq2. 5477 * 5478 * Meaning (in pseudo-FOL): 5479 * 5480 * <pre> 5481 * /\ seq1.length == seq2.length 5482 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 5483 * </pre> 5484 * 5485 */ 5486 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5487 @Pure 5488 public static boolean isReverse(float[] seq1, float[] seq2) { 5489 if (!sameLength(seq1, seq2)) { 5490 return false; 5491 } 5492 assert seq1 != null && seq2 != null; // because sameLength() = true 5493 int length = seq1.length; 5494 for (int i = 0 ; i < length ; i++) { 5495 if (ne(seq1[i], seq2[length - i - 1])) { 5496 return false; 5497 } 5498 } 5499 return true; 5500 } 5501 5502 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5503 @Pure 5504 public static boolean isReverse(float @Nullable [] seq1, double @Nullable [] seq2) { 5505 if (!sameLength(seq1, seq2)) { 5506 return false; 5507 } 5508 assert seq1 != null && seq2 != null; // because sameLength() = true 5509 int length = seq1.length; 5510 for (int i = 0 ; i < length ; i++) { 5511 if (ne(seq1[i], seq2[length - i - 1])) { 5512 return false; 5513 } 5514 } 5515 return true; 5516 } 5517 5518 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 5519 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5520 @Pure 5521 public static boolean subsetOf(float @Nullable [] seq1, float @Nullable [] seq2) { 5522 if (seq1 == null) { 5523 return false; 5524 } 5525 if (seq2 == null) { 5526 return false; 5527 } 5528 for (int i = 0 ; i < seq1.length ; i++) { 5529 if (!memberOf(seq1[i], seq2)) { 5530 return false; 5531 } 5532 } 5533 return true; 5534 } 5535 5536 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5537 @Pure 5538 public static boolean subsetOf(float @Nullable [] seq1, double @Nullable [] seq2) { 5539 if (seq1 == null) { 5540 return false; 5541 } 5542 if (seq2 == null) { 5543 return false; 5544 } 5545 for (int i = 0 ; i < seq1.length ; i++) { 5546 if (!memberOf(seq1[i], seq2)) { 5547 return false; 5548 } 5549 } 5550 return true; 5551 } 5552 5553 /** Returns true iff seq contains no duplicate elements. */ 5554 @EnsuresNonNullIf(result=true, expression="#1") 5555 @Pure 5556 public static boolean noDups(float @Nullable [] seq) { 5557 if (seq == null) { 5558 return false; 5559 } 5560 return ArraysPlume.noDuplicates(seq); 5561 } 5562 5563 /** Returns true iff elt is in array arr. */ 5564 @EnsuresNonNullIf(result=true, expression="#2") 5565 @Pure 5566 public static boolean memberOf(float elt, float @Nullable [] arr) { 5567 if (arr == null) { 5568 return false; 5569 } 5570 for (int i = 0 ; i < arr.length ; i++) { 5571 if (eq(arr[i], elt)) { 5572 return true; 5573 } 5574 } 5575 return false; 5576 } 5577 5578 @EnsuresNonNullIf(result=true, expression="#2") 5579 @Pure 5580 public static boolean memberOf(float elt, double @Nullable [] arr) { 5581 if (arr == null) { 5582 return false; 5583 } 5584 for (int i = 0 ; i < arr.length ; i++) { 5585 if (eq(arr[i], elt)) { 5586 return true; 5587 } 5588 } 5589 return false; 5590 } 5591 5592 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 5593 @Pure 5594 public static float @PolyNull [] slice(float @PolyNull [] seq, int start, int end) { 5595 if (seq == null) { 5596 return null; 5597 } 5598 int sliceStart = start; 5599 int sliceEnd = end; 5600 if (start < 0) { 5601 return new float[] { }; 5602 } 5603 if (end > seq.length - 1) { 5604 return new float[] { }; 5605 } 5606 if (sliceStart > sliceEnd) { 5607 return new float[] { }; 5608 } 5609 int length = sliceEnd - sliceStart + 1; 5610 return ArraysPlume.subarray(seq, sliceStart, length); 5611 } 5612 5613 @Pure 5614 public static float @PolyNull [] slice(float @PolyNull [] seq, long start, int end) { 5615 return slice(seq, (int)start, end); 5616 } 5617 @Pure 5618 public static float @PolyNull [] slice(float @PolyNull [] seq, int start, long end) { 5619 return slice(seq, start, (int)end); 5620 } 5621 @Pure 5622 public static float @PolyNull [] slice(float @PolyNull [] seq, long start, long end) { 5623 return slice(seq, (int)start, (int)end); 5624 } 5625 5626 /** True iff all elements in arr equal elt. 5627 * 5628 * Meaning (in pseudo-FOL): 5629 * 5630 * forall i in { 0..arr.length-1 } : arr[i] == elt 5631 * 5632 */ 5633 @EnsuresNonNullIf(result=true, expression="#1") 5634 @Pure 5635 public static boolean eltsEqual(float @Nullable [] arr, float elt) { 5636 if (arr == null) { 5637 return false; 5638 } 5639 for (int i = 0 ; i < arr.length ; i++) { 5640 if (ne(arr[i], elt)) { 5641 return false; 5642 } 5643 } 5644 return true; 5645 } 5646 5647 @EnsuresNonNullIf(result=true, expression="#1") 5648 @Pure 5649 public static boolean eltsEqual(float @Nullable [] arr, double elt) { 5650 if (arr == null) { 5651 return false; 5652 } 5653 for (int i = 0 ; i < arr.length ; i++) { 5654 if (ne(arr[i], elt)) { 5655 return false; 5656 } 5657 } 5658 return true; 5659 } 5660 5661 /** True iff every element in arr does not equal elt. 5662 * 5663 * Meaning (in pseudo-FOL): 5664 * 5665 * forall i in { 0..arr.length-1 } : arr[i] != elt 5666 * 5667 */ 5668 @EnsuresNonNullIf(result=true, expression="#1") 5669 @Pure 5670 public static boolean eltsNotEqual(float @Nullable [] arr, float elt) { 5671 if (arr == null) { 5672 return false; 5673 } 5674 for (int i = 0 ; i < arr.length ; i++) { 5675 if (eq(arr[i], elt)) { 5676 return false; 5677 } 5678 } 5679 return true; 5680 } 5681 5682 @EnsuresNonNullIf(result=true, expression="#1") 5683 @Pure 5684 public static boolean eltsNotEqual(float @Nullable [] arr, double elt) { 5685 if (arr == null) { 5686 return false; 5687 } 5688 for (int i = 0 ; i < arr.length ; i++) { 5689 if (eq(arr[i], elt)) { 5690 return false; 5691 } 5692 } 5693 return true; 5694 } 5695 5696 /** True iff every element in arr is greater than elt. 5697 * 5698 * Meaning (in pseudo-FOL): 5699 * 5700 * forall i in { 0..arr.length-1 } : arr[i] > elt 5701 * 5702 */ 5703 @EnsuresNonNullIf(result=true, expression="#1") 5704 @Pure 5705 public static boolean eltsGT(float @Nullable [] arr, float elt) { 5706 if (arr == null) { 5707 return false; 5708 } 5709 for (int i = 0 ; i < arr.length ; i++) { 5710 if (lte(arr[i], elt)) { 5711 return false; 5712 } 5713 } 5714 return true; 5715 } 5716 5717 @EnsuresNonNullIf(result=true, expression="#1") 5718 @Pure 5719 public static boolean eltsGT(float @Nullable [] arr, double elt) { 5720 if (arr == null) { 5721 return false; 5722 } 5723 for (int i = 0 ; i < arr.length ; i++) { 5724 if (lte(arr[i], elt)) { 5725 return false; 5726 } 5727 } 5728 return true; 5729 } 5730 5731 /** True iff every element in arr is greater than or equal to elt. 5732 * 5733 * Meaning (in pseudo-FOL): 5734 * 5735 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 5736 * 5737 */ 5738 @EnsuresNonNullIf(result=true, expression="#1") 5739 @Pure 5740 public static boolean eltsGTE(float @Nullable [] arr, float elt) { 5741 if (arr == null) { 5742 return false; 5743 } 5744 for (int i = 0 ; i < arr.length ; i++) { 5745 if (lt(arr[i], elt)) { 5746 return false; 5747 } 5748 } 5749 return true; 5750 } 5751 5752 @EnsuresNonNullIf(result=true, expression="#1") 5753 @Pure 5754 public static boolean eltsGTE(float @Nullable [] arr, double elt) { 5755 if (arr == null) { 5756 return false; 5757 } 5758 for (int i = 0 ; i < arr.length ; i++) { 5759 if (lt(arr[i], elt)) { 5760 return false; 5761 } 5762 } 5763 return true; 5764 } 5765 5766 /** True iff every element in arr is less than elt. 5767 * 5768 * Meaning (in pseudo-FOL): 5769 * 5770 * forall i in { 0..arr.length-1 } : arr[i] < elt 5771 * 5772 */ 5773 @EnsuresNonNullIf(result=true, expression="#1") 5774 @Pure 5775 public static boolean eltsLT(float @Nullable [] arr, float elt) { 5776 if (arr == null) { 5777 return false; 5778 } 5779 for (int i = 0 ; i < arr.length ; i++) { 5780 if (gte(arr[i], elt)) { 5781 return false; 5782 } 5783 } 5784 return true; 5785 } 5786 5787 @EnsuresNonNullIf(result=true, expression="#1") 5788 @Pure 5789 public static boolean eltsLT(float @Nullable [] arr, double elt) { 5790 if (arr == null) { 5791 return false; 5792 } 5793 for (int i = 0 ; i < arr.length ; i++) { 5794 if (gte(arr[i], elt)) { 5795 return false; 5796 } 5797 } 5798 return true; 5799 } 5800 5801 /** True iff every element in arr is less than or equal to elt. 5802 * 5803 * Meaning (in pseudo-FOL): 5804 * 5805 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 5806 * 5807 */ 5808 @EnsuresNonNullIf(result=true, expression="#1") 5809 @Pure 5810 public static boolean eltsLTE(float @Nullable [] arr, float elt) { 5811 if (arr == null) { 5812 return false; 5813 } 5814 for (int i = 0 ; i < arr.length ; i++) { 5815 if (gt(arr[i], elt)) { 5816 return false; 5817 } 5818 } 5819 return true; 5820 } 5821 5822 @EnsuresNonNullIf(result=true, expression="#1") 5823 @Pure 5824 public static boolean eltsLTE(float @Nullable [] arr, double elt) { 5825 if (arr == null) { 5826 return false; 5827 } 5828 for (int i = 0 ; i < arr.length ; i++) { 5829 if (gt(arr[i], elt)) { 5830 return false; 5831 } 5832 } 5833 return true; 5834 } 5835 5836 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 5837 * 5838 * Meaning (in pseudo-FOL): 5839 * 5840 * /\ seq1.length == se2.length 5841 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 5842 * 5843 */ 5844 5845 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5846 @Pure 5847 public static boolean pairwiseEqual(float @Nullable [] seq1, float @Nullable [] seq2) { 5848 if (!sameLength(seq1, seq2)) { 5849 return false; 5850 } 5851 assert seq1 != null && seq2 != null; // because sameLength() = true 5852 for (int i = 0 ; i < seq1.length ; i++) { 5853 if (Float.isNaN(seq1[i]) && Float.isNaN(seq2[i])) { 5854 continue; 5855 } 5856 if (ne(seq1[i], seq2[i])) { 5857 return false; 5858 } 5859 } 5860 return true; 5861 } 5862 5863 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5864 @Pure 5865 public static boolean pairwiseEqual(float @Nullable [] seq1, double @Nullable [] seq2) { 5866 if (!sameLength(seq1, seq2)) { 5867 return false; 5868 } 5869 assert seq1 != null && seq2 != null; // because sameLength() = true 5870 for (int i = 0 ; i < seq1.length ; i++) { 5871 if (ne(seq1[i], seq2[i])) { 5872 return false; 5873 } 5874 } 5875 return true; 5876 } 5877 5878 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 5879 * 5880 * Meaning (in pseudo-FOL): 5881 * 5882 * /\ seq1.length == se2.length 5883 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 5884 * 5885 */ 5886 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5887 @Pure 5888 public static boolean pairwiseNotEqual(float @Nullable [] seq1, float @Nullable [] seq2) { 5889 if (!sameLength(seq1, seq2)) { 5890 return false; 5891 } 5892 assert seq1 != null && seq2 != null; // because sameLength() = true 5893 for (int i = 0 ; i < seq1.length ; i++) { 5894 if (eq(seq1[i], seq2[i])) { 5895 return false; 5896 } 5897 } 5898 return true; 5899 } 5900 5901 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5902 @Pure 5903 public static boolean pairwiseNotEqual(float @Nullable [] seq1, double @Nullable [] seq2) { 5904 if (!sameLength(seq1, seq2)) { 5905 return false; 5906 } 5907 assert seq1 != null && seq2 != null; // because sameLength() = true 5908 for (int i = 0 ; i < seq1.length ; i++) { 5909 if (eq(seq1[i], seq2[i])) { 5910 return false; 5911 } 5912 } 5913 return true; 5914 } 5915 5916 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 5917 * 5918 * Meaning (in pseudo-FOL): 5919 * 5920 * /\ seq1.length == se2.length 5921 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 5922 * 5923 */ 5924 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5925 @Pure 5926 public static boolean pairwiseLT(float @Nullable [] seq1, float @Nullable [] seq2) { 5927 if (!sameLength(seq1, seq2)) { 5928 return false; 5929 } 5930 assert seq1 != null && seq2 != null; // because sameLength() = true 5931 for (int i = 0 ; i < seq1.length ; i++) { 5932 if (gte(seq1[i], seq2[i])) { 5933 return false; 5934 } 5935 } 5936 return true; 5937 } 5938 5939 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5940 @Pure 5941 public static boolean pairwiseLT(float @Nullable [] seq1, double @Nullable [] seq2) { 5942 if (!sameLength(seq1, seq2)) { 5943 return false; 5944 } 5945 assert seq1 != null && seq2 != null; // because sameLength() = true 5946 for (int i = 0 ; i < seq1.length ; i++) { 5947 if (gte(seq1[i], seq2[i])) { 5948 return false; 5949 } 5950 } 5951 return true; 5952 } 5953 5954 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 5955 * Meaning (in pseudo-FOL): 5956 * 5957 * /\ seq1.length == se2.length 5958 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 5959 * 5960 */ 5961 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5962 @Pure 5963 public static boolean pairwiseLTE(float @Nullable [] seq1, float @Nullable [] seq2) { 5964 if (!sameLength(seq1, seq2)) { 5965 return false; 5966 } 5967 assert seq1 != null && seq2 != null; // because sameLength() = true 5968 for (int i = 0 ; i < seq1.length ; i++) { 5969 if (gt(seq1[i], seq2[i])) { 5970 return false; 5971 } 5972 } 5973 return true; 5974 } 5975 5976 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5977 @Pure 5978 public static boolean pairwiseLTE(float @Nullable [] seq1, double @Nullable [] seq2) { 5979 if (!sameLength(seq1, seq2)) { 5980 return false; 5981 } 5982 assert seq1 != null && seq2 != null; // because sameLength() = true 5983 for (int i = 0 ; i < seq1.length ; i++) { 5984 if (gt(seq1[i], seq2[i])) { 5985 return false; 5986 } 5987 } 5988 return true; 5989 } 5990 5991 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 5992 * Meaning (in pseudo-FOL): 5993 * 5994 * /\ seq1.length == se2.length 5995 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 5996 * 5997 */ 5998 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 5999 @Pure 6000 public static boolean pairwiseGT(float @Nullable [] seq1, float @Nullable [] seq2) { 6001 if (!sameLength(seq1, seq2)) { 6002 return false; 6003 } 6004 assert seq1 != null && seq2 != null; // because sameLength() = true 6005 for (int i = 0 ; i < seq1.length ; i++) { 6006 if (lte(seq1[i], seq2[i])) { 6007 return false; 6008 } 6009 } 6010 return true; 6011 } 6012 6013 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6014 @Pure 6015 public static boolean pairwiseGT(float @Nullable [] seq1, double @Nullable [] seq2) { 6016 if (!sameLength(seq1, seq2)) { 6017 return false; 6018 } 6019 assert seq1 != null && seq2 != null; // because sameLength() = true 6020 for (int i = 0 ; i < seq1.length ; i++) { 6021 if (lte(seq1[i], seq2[i])) { 6022 return false; 6023 } 6024 } 6025 return true; 6026 } 6027 6028 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 6029 * Meaning (in pseudo-FOL): 6030 * 6031 * /\ seq1.length == se2.length 6032 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 6033 * 6034 */ 6035 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6036 @Pure 6037 public static boolean pairwiseGTE(float @Nullable [] seq1, float @Nullable [] seq2) { 6038 if (!sameLength(seq1, seq2)) { 6039 return false; 6040 } 6041 assert seq1 != null && seq2 != null; // because sameLength() = true 6042 for (int i = 0 ; i < seq1.length ; i++) { 6043 if (lt(seq1[i], seq2[i])) { 6044 return false; 6045 } 6046 } 6047 return true; 6048 } 6049 6050 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6051 @Pure 6052 public static boolean pairwiseGTE(float @Nullable [] seq1, double @Nullable [] seq2) { 6053 if (!sameLength(seq1, seq2)) { 6054 return false; 6055 } 6056 assert seq1 != null && seq2 != null; // because sameLength() = true 6057 for (int i = 0 ; i < seq1.length ; i++) { 6058 if (lt(seq1[i], seq2[i])) { 6059 return false; 6060 } 6061 } 6062 return true; 6063 } 6064 6065 /** 6066 * Returns true iff seq1 is lexically equal to seq2. 6067 * For equality, "lexically" and "pairwise" are the same. 6068 */ 6069 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6070 @Pure 6071 public static boolean lexEqual(float @Nullable [] seq1, float @Nullable [] seq2) { 6072 if (seq1 == null) { 6073 return false; 6074 } 6075 if (seq2 == null) { 6076 return false; 6077 } 6078 return pairwiseEqual(seq1, seq2); 6079 } 6080 6081 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6082 @Pure 6083 public static boolean lexEqual(float @Nullable [] seq1, double @Nullable [] seq2) { 6084 if (seq1 == null) { 6085 return false; 6086 } 6087 if (seq2 == null) { 6088 return false; 6089 } 6090 return pairwiseEqual(seq1, seq2); 6091 } 6092 6093 /** Returns true iff seq1 is lexically not equal to seq2. */ 6094 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6095 @Pure 6096 public static boolean lexNotEqual(float @Nullable [] seq1, float @Nullable [] seq2) { 6097 if (seq1 == null) { 6098 return false; 6099 } 6100 if (seq2 == null) { 6101 return false; 6102 } 6103 return !lexEqual(seq1, seq2); 6104 } 6105 6106 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6107 @Pure 6108 public static boolean lexNotEqual(float @Nullable [] seq1, double @Nullable [] seq2) { 6109 if (seq1 == null) { 6110 return false; 6111 } 6112 if (seq2 == null) { 6113 return false; 6114 } 6115 return !lexEqual(seq1, seq2); 6116 } 6117 6118 /** Returns true iff seq1 is lexically < seq2. */ 6119 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6120 @Pure 6121 public static boolean lexLT(float @Nullable [] seq1, float @Nullable [] seq2) { 6122 if (seq1 == null) { 6123 return false; 6124 } 6125 if (seq2 == null) { 6126 return false; 6127 } 6128 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6129 for (int i = 0 ; i < minlength ; i++) { 6130 if (gt(seq1[i], seq2[i])) { 6131 return false; 6132 } else if (lt(seq1[i], seq2[i])) { 6133 return true; 6134 } 6135 } 6136 if (seq1.length >= seq2.length) { 6137 return false; 6138 } 6139 return true; 6140 } 6141 6142 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6143 @Pure 6144 public static boolean lexLT(float @Nullable [] seq1, double @Nullable [] seq2) { 6145 if (seq1 == null) { 6146 return false; 6147 } 6148 if (seq2 == null) { 6149 return false; 6150 } 6151 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6152 for (int i = 0 ; i < minlength ; i++) { 6153 if (gt(seq1[i], seq2[i])) { 6154 return false; 6155 } else if (lt(seq1[i], seq2[i])) { 6156 return true; 6157 } 6158 } 6159 if (seq1.length >= seq2.length) { 6160 return false; 6161 } 6162 return true; 6163 } 6164 6165 /** Returns true iff seq1 is lexically ≤ to seq2. */ 6166 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6167 @Pure 6168 public static boolean lexLTE(float @Nullable [] seq1, float @Nullable [] seq2) { 6169 if (seq1 == null) { 6170 return false; 6171 } 6172 if (seq2 == null) { 6173 return false; 6174 } 6175 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6176 for (int i = 0 ; i < minlength ; i++) { 6177 if (gt(seq1[i], seq2[i])) { 6178 return false; 6179 } else if (lt(seq1[i], seq2[i])) { 6180 return true; 6181 } 6182 } 6183 if (seq1.length > seq2.length) { 6184 return false; 6185 } 6186 return true; 6187 } 6188 6189 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6190 @Pure 6191 public static boolean lexLTE(float @Nullable [] seq1, double @Nullable [] seq2) { 6192 if (seq1 == null) { 6193 return false; 6194 } 6195 if (seq2 == null) { 6196 return false; 6197 } 6198 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6199 for (int i = 0 ; i < minlength ; i++) { 6200 if (gt(seq1[i], seq2[i])) { 6201 return false; 6202 } else if (lt(seq1[i], seq2[i])) { 6203 return true; 6204 } 6205 } 6206 if (seq1.length > seq2.length) { 6207 return false; 6208 } 6209 return true; 6210 } 6211 6212 /** Returns true iff seq1 is lexically > to seq2. */ 6213 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6214 @Pure 6215 public static boolean lexGT(float @Nullable [] seq1, float @Nullable [] seq2) { 6216 if (seq1 == null) { 6217 return false; 6218 } 6219 if (seq2 == null) { 6220 return false; 6221 } 6222 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6223 for (int i = 0 ; i < minlength ; i++) { 6224 if (lt(seq1[i], seq2[i])) { 6225 return false; 6226 } else if (gt(seq1[i], seq2[i])) { 6227 return true; 6228 } 6229 } 6230 if (seq1.length <= seq2.length) { 6231 return false; 6232 } 6233 return true; 6234 } 6235 6236 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6237 @Pure 6238 public static boolean lexGT(float @Nullable [] seq1, double @Nullable [] seq2) { 6239 if (seq1 == null) { 6240 return false; 6241 } 6242 if (seq2 == null) { 6243 return false; 6244 } 6245 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6246 for (int i = 0 ; i < minlength ; i++) { 6247 if (lt(seq1[i], seq2[i])) { 6248 return false; 6249 } else if (gt(seq1[i], seq2[i])) { 6250 return true; 6251 } 6252 } 6253 if (seq1.length <= seq2.length) { 6254 return false; 6255 } 6256 return true; 6257 } 6258 6259 /** Returns true iff seq1 is lexically ≥ to seq2. */ 6260 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6261 @Pure 6262 public static boolean lexGTE(float @Nullable [] seq1, float @Nullable [] seq2) { 6263 if (seq1 == null) { 6264 return false; 6265 } 6266 if (seq2 == null) { 6267 return false; 6268 } 6269 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6270 for (int i = 0 ; i < minlength ; i++) { 6271 if (lt(seq1[i], seq2[i])) { 6272 return false; 6273 } else if (gt(seq1[i], seq2[i])) { 6274 return true; 6275 } 6276 } 6277 if (seq1.length < seq2.length) { 6278 return false; 6279 } 6280 return true; 6281 } 6282 6283 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6284 @Pure 6285 public static boolean lexGTE(float @Nullable [] seq1, double @Nullable [] seq2) { 6286 if (seq1 == null) { 6287 return false; 6288 } 6289 if (seq2 == null) { 6290 return false; 6291 } 6292 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 6293 for (int i = 0 ; i < minlength ; i++) { 6294 if (lt(seq1[i], seq2[i])) { 6295 return false; 6296 } else if (gt(seq1[i], seq2[i])) { 6297 return true; 6298 } 6299 } 6300 if (seq1.length < seq2.length) { 6301 return false; 6302 } 6303 return true; 6304 } 6305 6306 /** True iff for all applicable i, every seq[i] == seq[i+1]. 6307 * 6308 * Meaning (in pseudo-FOL): 6309 * 6310 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 6311 * 6312 */ 6313 @EnsuresNonNullIf(result=true, expression="#1") 6314 @Pure 6315 public static boolean eltwiseEqual(float @Nullable [] seq) { 6316 if (seq == null) { 6317 return false; 6318 } 6319 for (int i = 0 ; i < seq.length ; i++) { 6320 if (i < seq.length - 1) { 6321 if (ne(seq[i], seq[i + 1])) { 6322 return false; 6323 } 6324 } 6325 } 6326 return true; 6327 } 6328 6329 /** True iff for all applicable i, every seq[i] != seq[i+1]. 6330 * 6331 * Meaning (in pseudo-FOL): 6332 * 6333 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 6334 * 6335 */ 6336 @EnsuresNonNullIf(result=true, expression="#1") 6337 @Pure 6338 public static boolean eltwiseNotEqual(float @Nullable [] seq) { 6339 if (seq == null) { 6340 return false; 6341 } 6342 for (int i = 0 ; i < seq.length ; i++) { 6343 if (i < seq.length - 1) { 6344 if (eq(seq[i], seq[i + 1])) { 6345 return false; 6346 } 6347 } 6348 } 6349 return true; 6350 } 6351 6352 /** True iff for all applicable i, every seq[i] < seq[i+1]. 6353 * 6354 * Meaning (in pseudo-FOL): 6355 * 6356 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 6357 * 6358 */ 6359 @EnsuresNonNullIf(result=true, expression="#1") 6360 @Pure 6361 public static boolean eltwiseLT(float @Nullable [] seq) { 6362 if (seq == null) { 6363 return false; 6364 } 6365 for (int i = 0 ; i < seq.length ; i++) { 6366 if (i < seq.length - 1) { 6367 if (gte(seq[i], seq[i + 1])) { 6368 return false; 6369 } 6370 } 6371 } 6372 return true; 6373 } 6374 6375 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 6376 * 6377 * Meaning (in pseudo-FOL): 6378 * 6379 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 6380 * 6381 */ 6382 @EnsuresNonNullIf(result=true, expression="#1") 6383 @Pure 6384 public static boolean eltwiseLTE(float @Nullable [] seq) { 6385 if (seq == null) { 6386 return false; 6387 } 6388 for (int i = 0 ; i < seq.length ; i++) { 6389 if (i < seq.length - 1) { 6390 if (gt(seq[i], seq[i + 1])) { 6391 return false; 6392 } 6393 } 6394 } 6395 return true; 6396 } 6397 6398 /** True iff for all applicable i, every seq[i] > seq[i+1]. 6399 * 6400 * Meaning (in pseudo-FOL): 6401 * 6402 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 6403 * 6404 */ 6405 @EnsuresNonNullIf(result=true, expression="#1") 6406 @Pure 6407 public static boolean eltwiseGT(float @Nullable [] seq) { 6408 if (seq == null) { 6409 return false; 6410 } 6411 for (int i = 0 ; i < seq.length ; i++) { 6412 if (i < seq.length - 1) { 6413 if (lte(seq[i], seq[i + 1])) { 6414 return false; 6415 } 6416 } 6417 } 6418 return true; 6419 } 6420 6421 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 6422 * 6423 * Meaning (in pseudo-FOL): 6424 * 6425 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 6426 * 6427 */ 6428 @EnsuresNonNullIf(result=true, expression="#1") 6429 @Pure 6430 public static boolean eltwiseGTE(float @Nullable [] seq) { 6431 if (seq == null) { 6432 return false; 6433 } 6434 for (int i = 0 ; i < seq.length ; i++) { 6435 if (i < seq.length - 1) { 6436 if (lt(seq[i], seq[i + 1])) { 6437 return false; 6438 } 6439 } 6440 } 6441 return true; 6442 } 6443 6444 /** True iff for all applicable i, every seq[i] == i. 6445 * 6446 * Meaning (in pseudo-FOL): 6447 * 6448 * forall i in { 0..seq.length-1 } : seq[i] == i 6449 * 6450 */ 6451 @EnsuresNonNullIf(result=true, expression="#1") 6452 @Pure 6453 public static boolean eltsEqualIndex(float @Nullable [] seq) { 6454 if (seq == null) { 6455 return false; 6456 } 6457 for (int i = 0 ; i < seq.length ; i++) { 6458 if (ne(seq[i], i)) { 6459 return false; 6460 } 6461 } 6462 return true; 6463 } 6464 6465 /** True iff for all applicable i, every seq[i] != i. 6466 * 6467 * Meaning (in pseudo-FOL): 6468 * 6469 * forall i in { 0..seq.length-1 } : seq[i] != i 6470 * 6471 */ 6472 @EnsuresNonNullIf(result=true, expression="#1") 6473 @Pure 6474 public static boolean eltsNotEqualIndex(float @Nullable [] seq) { 6475 if (seq == null) { 6476 return false; 6477 } 6478 for (int i = 0 ; i < seq.length ; i++) { 6479 if (eq(seq[i], i)) { 6480 return false; 6481 } 6482 } 6483 return true; 6484 } 6485 6486 /** True iff for all applicable i, every seq[i] < i. 6487 * 6488 * Meaning (in pseudo-FOL): 6489 * 6490 * forall i in { 0..seq.length-1 } : seq[i] < i 6491 * 6492 */ 6493 @EnsuresNonNullIf(result=true, expression="#1") 6494 @Pure 6495 public static boolean eltsLtIndex(float @Nullable [] seq) { 6496 if (seq == null) { 6497 return false; 6498 } 6499 for (int i = 0 ; i < seq.length ; i++) { 6500 if (gte(seq[i], i)) { 6501 return false; 6502 } 6503 } 6504 return true; 6505 } 6506 6507 /** True iff for all applicable i, every seq[i] ≤ i. 6508 * 6509 * Meaning (in pseudo-FOL): 6510 * 6511 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 6512 * 6513 */ 6514 @EnsuresNonNullIf(result=true, expression="#1") 6515 @Pure 6516 public static boolean eltsLteIndex(float @Nullable [] seq) { 6517 if (seq == null) { 6518 return false; 6519 } 6520 for (int i = 0 ; i < seq.length ; i++) { 6521 if (gt(seq[i], i)) { 6522 return false; 6523 } 6524 } 6525 return true; 6526 } 6527 6528 /** True iff for all applicable i, every seq[i] > i. 6529 * 6530 * Meaning (in pseudo-FOL): 6531 * 6532 * forall i in { 0..seq.length-1 } : seq[i] > i 6533 * 6534 */ 6535 @EnsuresNonNullIf(result=true, expression="#1") 6536 @Pure 6537 public static boolean eltsGtIndex(float @Nullable [] seq) { 6538 if (seq == null) { 6539 return false; 6540 } 6541 for (int i = 0 ; i < seq.length ; i++) { 6542 if (lte(seq[i], i)) { 6543 return false; 6544 } 6545 } 6546 return true; 6547 } 6548 6549 /** True iff for all applicable i, every seq[i] ≥ i. 6550 * 6551 * Meaning (in pseudo-FOL): 6552 * 6553 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 6554 * 6555 */ 6556 @EnsuresNonNullIf(result=true, expression="#1") 6557 @Pure 6558 public static boolean eltsGteIndex(float @Nullable [] seq) { 6559 if (seq == null) { 6560 return false; 6561 } 6562 for (int i = 0 ; i < seq.length ; i++) { 6563 if (lt(seq[i], i)) { 6564 return false; 6565 } 6566 } 6567 return true; 6568 } 6569 6570 /// Deferencing (accessing) fields 6571 6572 /** 6573 * collectfloat accepts an object and a list of fields (one of which is of array type, and the 6574 * rest of which are not), and produces an array in which the original object has had the given 6575 * fields accessed. 6576 * 6577 * <p>Daikon creates invariants over "variables" such as the following. 6578 * 6579 * <dl> 6580 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 6581 * for all y's in array x.arr.</dd> 6582 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 6583 * for all x's in array arr.</dd> 6584 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 6585 * </dl> 6586 * 6587 * <p>The collectfloat() method does this collecting work. 6588 * 6589 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 6590 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 6591 * elements that result from following the fields, one of which is assumed to be an array. 6592 * 6593 * <p> 6594 * requires: fieldStr.length() > 0 and object != null 6595 * <p> 6596 * requires: fieldStr contains only field names, no "[]" strings. 6597 * <p> 6598 * requires: the method only works for field sequences with exactly one field representing an 6599 * array. For example, the collection a[].b[].c will fail. 6600 * 6601 * @return if the resulting collection is of non-primitive type, then returns an array of type 6602 * Object[]. Returns null if any array or field access causes an exception. 6603 */ 6604 6605 @SideEffectFree 6606 public static float @Nullable [] collectfloat(@Nullable Object object, @Nullable String fieldStr) { 6607 6608 if (object == null) { 6609 return null; 6610 } 6611 if (fieldStr == null) { 6612 return null; 6613 } 6614 6615 // assert fieldStr != null && !"".equals(fieldStr); 6616 String[] fieldNames = fieldStr.split("\\."); 6617 float[] retval = collectfloat(object, fieldNames, 0); 6618 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 6619 return retval; 6620 } 6621 6622 /** Helper method for collectfloat(Object, String). 6623 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 6624 * @see collectfloat(Object, String) 6625 */ 6626 // @PolyNull does not work for return type, because null is returned on error. 6627 @SideEffectFree 6628 private static float @Nullable [] collectfloat(@Nullable Object object, 6629 String[] fields, int fieldsStartIdx) { 6630 6631 if (object == null) { 6632 return null; 6633 } 6634 assert (fields != null); 6635 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 6636 6637 Object fieldObj; 6638 try { 6639 Field field = (object instanceof java.lang.Class<?>) 6640 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 6641 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 6642 field.setAccessible(true); 6643 // Class cls = field.getType(); 6644 fieldObj = field.get(object); 6645 // System.out.println("***fieldObj="+fieldObj); 6646 6647 } catch (Exception e) { 6648 return null; 6649 6650 } 6651 6652 if (fieldObj == null) { 6653 return null; 6654 } 6655 6656 // base case: just accessed the last field 6657 if (fields.length - 1 == fieldsStartIdx) { 6658 6659 if (fieldObj.getClass().isArray()) { 6660 // last field is an array 6661 return (float[])fieldObj; 6662 } else { 6663 // This hack should be removed in favor of, at "oneEltArray = ..." 6664 // below, calling a version of collectfloat_field that throws an 6665 // error. Then, this case becomes a run-time error. -MDE 6666 6667 // Just one element; return a one-element array. 6668 // assert cls.equals(Float.TYPE); 6669 return new float[] { ((Float)fieldObj).floatValue() }; 6670 } 6671 } else { 6672 // recursive case: more fields to access after this one 6673 6674 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 6675 6676 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 6677 float[] intermediate = new float[collection.size()]; 6678 int index = 0; 6679 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 6680 Object obj = i.next(); 6681 float[] oneEltArray = collectfloat(obj, fields, fieldsStartIdx + 1); 6682 if (oneEltArray == null) { 6683 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 6684 } 6685 // assert oneEltArray.length == 1; 6686 intermediate[index++] = oneEltArray[0]; 6687 } 6688 return intermediate; 6689 } else if (fieldObj.getClass().isArray()) { 6690 6691 // collect elements across array 6692 float[] intermediate = new float[Array.getLength(fieldObj)]; 6693 for (int i = 0 ; i < intermediate.length ; i++) { 6694 Object obj = Array.get(fieldObj, i); 6695 float[] oneEltArray = collectfloat(obj, fields, fieldsStartIdx + 1); 6696 if (oneEltArray == null) { 6697 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 6698 } 6699 // assert oneEltArray.length == 1; 6700 intermediate[i] = oneEltArray[0]; 6701 } 6702 return intermediate; 6703 } else { 6704 6705 return collectfloat(fieldObj, fields, fieldsStartIdx + 1); 6706 } 6707 } 6708 } 6709 6710 /** 6711 * Returns the results of dereferencing the fields for 'object'. For example, the call 6712 * 6713 * <pre>collectfloat_field(x, "f.g.h")</pre> 6714 * 6715 * has the same value as 6716 * 6717 * <pre>x.f.g.h</pre>. 6718 * Returns a default value if any field access causes an exception. 6719 */ 6720 @SideEffectFree 6721 public static float collectfloat_field(Object object, String fieldStr) { 6722 6723 if (object == null) { 6724 return Float.NaN; // return default value 6725 } 6726 if (fieldStr == null) { 6727 return Float.NaN; // return default value 6728 } 6729 6730 String[] fieldNames = fieldStr.split("\\."); 6731 6732 // Holds the intermediate (and final) result 6733 Object fieldObj = object; 6734 6735 for (int i = 0 ; i < fieldNames.length ; i++) { 6736 6737 String fieldName = fieldNames[i]; 6738 6739 try { 6740 Field field = 6741 (fieldObj instanceof java.lang.Class<?>) 6742 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 6743 : fieldObj.getClass().getDeclaredField(fieldName); 6744 field.setAccessible(true); 6745 fieldObj = field.get(fieldObj); 6746 6747 if (fieldObj == null) { 6748 return Float.NaN; // return default value 6749 } 6750 6751 } catch (Exception e) { 6752 return Float.NaN; // return default value 6753 6754 } 6755 6756 } 6757 6758 return ((Float)fieldObj).floatValue(); 6759 } 6760 6761 /////////////////////////////////////////////////////////////////////////// 6762 /// Methods for "int" (from QuantBody.java.jpp) 6763 /// 6764 6765 /** 6766 * Returns the ith element of the array or collection argument. If the argument is null or not an 6767 * array or collection, returns a default value (Integer.MAX_VALUE). 6768 */ 6769 6770 @Pure 6771 public static int getElement_int(Object o, long i) { 6772 if (o == null) { 6773 return Integer.MAX_VALUE; // return default value 6774 } 6775 java.lang.Class<?> c = o.getClass(); 6776 if (c.isArray()) { 6777 return java.lang.reflect.Array.getInt(o, (int)i); 6778 } else if (o instanceof java.util.AbstractCollection<?>) { 6779 return java.lang.reflect.Array.getInt(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 6780 } else { 6781 return Integer.MAX_VALUE; // return default value 6782 } 6783 } 6784 6785 @Pure 6786 public static int getElement_int(int[] arr, long i) { 6787 if (arr == null) { 6788 return Integer.MAX_VALUE; // return default value 6789 } 6790 return arr[(int)i]; 6791 } 6792 6793 private static boolean eq(int x, int y) { 6794 return x == y; 6795 } 6796 6797 private static boolean ne(int x, int y) { 6798 return x != y; 6799 } 6800 6801 private static boolean lt(int x, int y) { 6802 return x < y; 6803 } 6804 6805 private static boolean lte(int x, int y) { 6806 return x <= y; 6807 } 6808 6809 private static boolean gt(int x, int y) { 6810 return x > y; 6811 } 6812 6813 private static boolean gte(int x, int y) { 6814 return x >= y; 6815 } 6816 6817 /** True iff both sequences are non-null and have the same length. */ 6818 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 6819 @Pure 6820 public static boolean sameLength(int @Nullable [] seq1, int @Nullable [] seq2) { 6821 return ((seq1 != null) 6822 && (seq2 != null) 6823 && seq1.length == seq2.length); 6824 } 6825 6826 /** True iff both sequences are non-null and have the same length. */ 6827 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 6828 @Pure 6829 public static boolean sameLength(int @Nullable [] seq1, long @Nullable [] seq2) { 6830 return ((seq1 != null) 6831 && (seq2 != null) 6832 && seq1.length == seq2.length); 6833 } 6834 6835 /** True iff both sequences have the same length, and all seq2[i] divide seq1[i]. 6836 * 6837 * Meaning (in pseudo-FOL): 6838 * 6839 * <pre> 6840 * /\ seq1.length == seq2.length 6841 * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i] 6842 * </pre> 6843 * 6844 */ 6845 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6846 @Pure 6847 public static boolean pairwiseDivides(int[] seq1, int[] seq2) { 6848 if (!sameLength(seq1, seq2)) { 6849 return false; 6850 } 6851 assert seq1 != null && seq2 != null; // because sameLength() = true 6852 for (int i = 0 ; i < seq1.length ; i++) { 6853 if (ne(seq1[i] % seq2[i], 0)) { 6854 return false; 6855 } 6856 } 6857 return true; 6858 } 6859 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6860 @Pure 6861 public static boolean pairwiseDivides(int[] seq1, long[] seq2) { 6862 if (!sameLength(seq1, seq2)) { 6863 return false; 6864 } 6865 assert seq1 != null && seq2 != null; // because sameLength() = true 6866 for (int i = 0 ; i < seq1.length ; i++) { 6867 if (ne(seq1[i] % seq2[i], 0)) { 6868 return false; 6869 } 6870 } 6871 return true; 6872 } 6873 6874 /** 6875 * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i]. 6876 * 6877 * Meaning (in pseudo-FOL): 6878 * 6879 * <pre> 6880 * /\ seq1.length == seq2.length 6881 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i] 6882 * </pre> 6883 * 6884 */ 6885 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6886 @Pure 6887 public static boolean pairwiseSquare(int[] seq1, int[] seq2) { 6888 if (!sameLength(seq1, seq2)) { 6889 return false; 6890 } 6891 assert seq1 != null && seq2 != null; // because sameLength() = true 6892 for (int i = 0 ; i < seq1.length ; i++) { 6893 if (ne(seq1[i], seq2[i] * seq2[i])) { 6894 return false; 6895 } 6896 } 6897 return true; 6898 } 6899 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6900 @Pure 6901 public static boolean pairwiseSquare(int[] seq1, long[] seq2) { 6902 if (!sameLength(seq1, seq2)) { 6903 return false; 6904 } 6905 assert seq1 != null && seq2 != null; // because sameLength() = true 6906 for (int i = 0 ; i < seq1.length ; i++) { 6907 6908 if (ne(seq1[i], seq2[i] * seq2[i])) { 6909 6910 return false; 6911 } 6912 } 6913 return true; 6914 } 6915 6916 /** True iff both sequences have the same length, and all seq1[i] == ~ seq2[i]. 6917 * 6918 * Meaning (in pseudo-FOL): 6919 * 6920 * <pre> 6921 * /\ seq1.length == seq2.length 6922 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == ~ seq2[i] 6923 * </pre> 6924 * 6925 */ 6926 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6927 @Pure 6928 public static boolean pairwiseBitwiseComplement(int[] seq1, int[] seq2) { 6929 if (!sameLength(seq1, seq2)) { 6930 return false; 6931 } 6932 assert seq1 != null && seq2 != null; // because sameLength() = true 6933 for (int i = 0 ; i < seq1.length ; i++) { 6934 if (seq1[i] != ~seq2[i]) { 6935 return false; 6936 } 6937 } 6938 return true; 6939 } 6940 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6941 @Pure 6942 public static boolean pairwiseBitwiseComplement(int[] seq1, long[] seq2) { 6943 if (!sameLength(seq1, seq2)) { 6944 return false; 6945 } 6946 assert seq1 != null && seq2 != null; // because sameLength() = true 6947 for (int i = 0 ; i < seq1.length ; i++) { 6948 if (seq1[i] != ~seq2[i]) { 6949 return false; 6950 } 6951 } 6952 return true; 6953 } 6954 6955 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6956 @Pure 6957 public static boolean pairwiseBitwiseComplement(Object[] seq1, Object[] seq2) { 6958 if (!sameLength(seq1, seq2)) { 6959 return false; 6960 } 6961 assert seq1 != null && seq2 != null; // because sameLength() = true 6962 if (!eltsNonNull(seq1)) { 6963 return false; 6964 } 6965 if (!eltsNonNull(seq2)) { 6966 return false; 6967 } 6968 int[] hashArr1 = new int[seq1.length]; 6969 for (int i = 0 ; i < seq1.length ; i++) { 6970 hashArr1[i] = seq1[i].hashCode(); 6971 } 6972 int[] hashArr2 = new int[seq2.length]; 6973 for (int i = 0 ; i < seq2.length ; i++) { 6974 hashArr2[i] = seq2[i].hashCode(); 6975 } 6976 return pairwiseBitwiseComplement(hashArr1, hashArr2); 6977 } 6978 6979 /** True iff both sequences have the same length, and all seq1[i] == (seq2[i] | seq1[i]). 6980 * 6981 * Meaning (in pseudo-FOL): 6982 * 6983 * <pre> 6984 * /\ seq1.length == seq2.length 6985 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == (seq2[i] | seq1[i]) 6986 * </pre> 6987 * 6988 */ 6989 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 6990 @Pure 6991 public static boolean pairwiseBitwiseSubset(int[] seq1, int[] seq2) { 6992 if (seq1 == null) { 6993 return false; 6994 } 6995 if (seq2 == null) { 6996 return false; 6997 } 6998 if (seq1.length != seq2.length) { 6999 return false; 7000 } 7001 for (int i = 0 ; i < seq1.length ; i++) { 7002 if (ne(seq1[i], (seq2[i] | seq1[i]))) { 7003 return false; 7004 } 7005 } 7006 return true; 7007 } 7008 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7009 @Pure 7010 public static boolean pairwiseBitwiseSubset(int[] seq1, long[] seq2) { 7011 if (!sameLength(seq1, seq2)) { 7012 return false; 7013 } 7014 assert seq1 != null && seq2 != null; // because sameLength() = true 7015 for (int i = 0 ; i < seq1.length ; i++) { 7016 if (ne(seq1[i], (seq2[i] | seq1[i]))) { 7017 return false; 7018 } 7019 } 7020 return true; 7021 } 7022 7023 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7024 @Pure 7025 public static boolean pairwiseBitwiseSubset(Object[] seq1, Object[] seq2) { 7026 if (!sameLength(seq1, seq2)) { 7027 return false; 7028 } 7029 assert seq1 != null && seq2 != null; // because sameLength() = true 7030 if (!eltsNonNull(seq1)) { 7031 return false; 7032 } 7033 if (!eltsNonNull(seq2)) { 7034 return false; 7035 } 7036 int[] hashArr1 = new int[seq1.length]; 7037 for (int i = 0 ; i < seq1.length ; i++) { 7038 hashArr1[i] = seq1[i].hashCode(); 7039 } 7040 int[] hashArr2 = new int[seq2.length]; 7041 for (int i = 0 ; i < seq2.length ; i++) { 7042 hashArr2[i] = seq2[i].hashCode(); 7043 } 7044 return pairwiseBitwiseSubset(hashArr1, hashArr2); 7045 } 7046 7047 /** 7048 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 7049 * 7050 * <p>If either array is null, returns null. If either array is empty, returns only those 7051 * elements in the other array. If both arrays are empty, returns a new empty array. 7052 */ 7053 @SideEffectFree 7054 public static int @PolyNull [] concat(int @PolyNull [] seq1, int @PolyNull [] seq2) { 7055 if (seq1 == null) { 7056 return null; 7057 } 7058 if (seq2 == null) { 7059 return null; 7060 } 7061 return ArraysPlume.concat(seq1, seq2); 7062 } 7063 7064 @SideEffectFree 7065 public static long @PolyNull [] concat(int @PolyNull [] seq1, long @PolyNull [] seq2) { 7066 if (seq1 == null) { 7067 return null; 7068 } 7069 if (seq2 == null) { 7070 return null; 7071 } 7072 // Cannot just use ArraysPlume.concat because the two arrays 7073 // have different types. This essentially inlines that method. 7074 int newLength = seq1.length + seq2.length; 7075 long[] retval = new long[newLength]; 7076 7077 for (int j = 0 ; j < seq1.length ; j++) { 7078 retval[j] = seq1[j]; 7079 } 7080 System.arraycopy(seq2, 0, retval, seq1.length, seq2.length); 7081 7082 return retval; 7083 } 7084 7085 /** 7086 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 7087 * assurances about the order or repetition of elements: elements may be repeated, and their 7088 * order may be different from the order of elements in seq1 and seq2. 7089 */ 7090 @SideEffectFree 7091 public static int @PolyNull [] union(int @PolyNull [] seq1, int @PolyNull [] seq2) { 7092 if (seq1 == null) { 7093 return null; 7094 } 7095 if (seq2 == null) { 7096 return null; 7097 } 7098 return concat(seq1, seq2); 7099 } 7100 7101 @Pure 7102 public static long @PolyNull [] union(int @PolyNull [] seq1, long @PolyNull [] seq2) { 7103 if (seq1 == null) { 7104 return null; 7105 } 7106 if (seq2 == null) { 7107 return null; 7108 } 7109 return concat(seq1, seq2); 7110 } 7111 7112 /** 7113 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 7114 * gives no assurances about the order or repetition of elements: elements may be repeated, and 7115 * their order may be different from the order of elements in seq1 and seq2. 7116 */ 7117 @Pure 7118 public static int @PolyNull [] intersection(int @PolyNull [] seq1, int @PolyNull [] seq2) { 7119 if (seq1 == null) { 7120 return null; 7121 } 7122 if (seq2 == null) { 7123 return null; 7124 } 7125 int[] intermediate = new int[Math.min(seq1.length, seq2.length)]; 7126 int length = 0; 7127 for (int i = 0 ; i < seq1.length ; i++) { 7128 if (memberOf(seq1[i], seq2) ) { 7129 intermediate[length++] = seq1[i]; 7130 } 7131 } 7132 return ArraysPlume.subarray(intermediate, 0, length); 7133 } 7134 7135 @Pure 7136 public static long @PolyNull [] intersection(int @PolyNull [] seq1, long @PolyNull [] seq2) { 7137 if (seq1 == null) { 7138 return null; 7139 } 7140 if (seq2 == null) { 7141 return null; 7142 } 7143 long[] intermediate = new long[Math.min(seq1.length, seq2.length)]; 7144 int length = 0; 7145 for (int i = 0 ; i < seq1.length ; i++) { 7146 if (memberOf(seq1[i], seq2) ) { 7147 intermediate[length++] = seq1[i]; 7148 } 7149 } 7150 return ArraysPlume.subarray(intermediate, 0, length); 7151 } 7152 7153 /** 7154 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 7155 * no assurances about the order or repetition of elements: elements may be repeated, and their 7156 * order may be different from the order of elements in seq1 and seq2. 7157 */ 7158 @Pure 7159 public static int @PolyNull [] setDiff(int @PolyNull [] seq1, int @PolyNull [] seq2) { 7160 if (seq1 == null) { 7161 return null; 7162 } 7163 if (seq2 == null) { 7164 return null; 7165 } 7166 int[] intermediate = new int[seq1.length]; 7167 int length = 0; 7168 for (int i = 0 ; i < seq1.length ; i++) { 7169 if (!memberOf(seq1[i], seq2)) { 7170 intermediate[length++] = seq1[i]; 7171 } 7172 } 7173 return ArraysPlume.subarray(intermediate, 0, length); 7174 } 7175 7176 @Pure 7177 public static long @PolyNull [] setDiff(int @PolyNull [] seq1, long @PolyNull [] seq2) { 7178 if (seq1 == null) { 7179 return null; 7180 } 7181 if (seq2 == null) { 7182 return null; 7183 } 7184 long[] intermediate = new long[seq1.length]; 7185 int length = 0; 7186 for (int i = 0 ; i < seq1.length ; i++) { 7187 if (!memberOf(seq1[i], seq2)) { 7188 intermediate[length++] = seq1[i]; 7189 } 7190 } 7191 return ArraysPlume.subarray(intermediate, 0, length); 7192 } 7193 7194 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 7195 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7196 @Pure 7197 public static boolean setEqual(int @Nullable [] seq1, int @Nullable [] seq2) { 7198 if (seq1 == null) { 7199 return false; 7200 } 7201 if (seq2 == null) { 7202 return false; 7203 } 7204 for (int i = 0; i < seq1.length ; i++) { 7205 if (!memberOf(seq1[i], seq2) ) { 7206 return false; 7207 } 7208 } 7209 for (int i = 0; i < seq2.length ; i++) { 7210 if (!memberOf(seq2[i], seq1) ) { 7211 return false; 7212 } 7213 } 7214 return true; 7215 } 7216 7217 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7218 @Pure 7219 public static boolean setEqual(int @Nullable [] seq1, long @Nullable [] seq2) { 7220 if (seq1 == null) { 7221 return false; 7222 } 7223 if (seq2 == null) { 7224 return false; 7225 } 7226 for (int i = 0; i < seq1.length ; i++) { 7227 if (!memberOf(seq1[i], seq2) ) { 7228 return false; 7229 } 7230 } 7231 for (int i = 0; i < seq2.length ; i++) { 7232 if (!memberOf(seq2[i], seq1) ) { 7233 return false; 7234 } 7235 } 7236 return true; 7237 } 7238 7239 /** True iff seq1 is the reverse of seq2. 7240 * 7241 * Meaning (in pseudo-FOL): 7242 * 7243 * <pre> 7244 * /\ seq1.length == seq2.length 7245 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 7246 * </pre> 7247 * 7248 */ 7249 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7250 @Pure 7251 public static boolean isReverse(int[] seq1, int[] seq2) { 7252 if (!sameLength(seq1, seq2)) { 7253 return false; 7254 } 7255 assert seq1 != null && seq2 != null; // because sameLength() = true 7256 int length = seq1.length; 7257 for (int i = 0 ; i < length ; i++) { 7258 if (ne(seq1[i], seq2[length - i - 1])) { 7259 return false; 7260 } 7261 } 7262 return true; 7263 } 7264 7265 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7266 @Pure 7267 public static boolean isReverse(int @Nullable [] seq1, long @Nullable [] seq2) { 7268 if (!sameLength(seq1, seq2)) { 7269 return false; 7270 } 7271 assert seq1 != null && seq2 != null; // because sameLength() = true 7272 int length = seq1.length; 7273 for (int i = 0 ; i < length ; i++) { 7274 if (ne(seq1[i], seq2[length - i - 1])) { 7275 return false; 7276 } 7277 } 7278 return true; 7279 } 7280 7281 /** True iff all elements in elts occur once or more in arr; 7282 * that is, elts is a subset of arr. 7283 * 7284 * Meaning (in pseudo-FOL): 7285 * 7286 * forall i in { 0..elt.length-1 } : elt[i] element_of arr 7287 * 7288 */ 7289 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7290 @Pure 7291 public static boolean subsetOf(@Nullable Object elts, @Nullable Object arr) { 7292 if (elts == null) { 7293 return false; 7294 } 7295 if (arr == null) { 7296 return false; 7297 } 7298 if (!(elts.getClass().isArray() && arr.getClass().isArray())) { 7299 // throw new IllegalArgumentException("both arguments must be arrays."); 7300 return false; 7301 } 7302 // We know that the two arguments are arrays of different types; if 7303 // they had been of the same type, then one of the more specific 7304 // overriding versions of this method would have been called. 7305 7306 // This implementation simply calls either subsetOf(long[], long[]) or 7307 // subsetOf(double[], double[]). 7308 7309 Class<?> eltsType = elts.getClass().getComponentType(); 7310 Class<?> arrType = arr.getClass().getComponentType(); 7311 if (isIntegralType(eltsType) && isIntegralType(arrType)) { 7312 // Both arrays are int/long. 7313 // Cast both arrays to long and call subsetOf(long[],long[]). 7314 long[] elts_long; 7315 if (eltsType == Long.class) { 7316 elts_long = (long[]) elts; 7317 } else { 7318 elts_long = new long[Array.getLength(elts)]; 7319 for (int i = 0 ; i < elts_long.length ; i++) { 7320 elts_long[i] = Array.getLong(elts, i); 7321 } 7322 } 7323 long[] arr_long; 7324 if (arrType == Long.class) { 7325 arr_long = (long[]) arr; 7326 } else { 7327 arr_long = new long[Array.getLength(arr)]; 7328 for (int i = 0 ; i < arr_long.length ; i++) { 7329 arr_long[i] = Array.getLong(arr, i); 7330 } 7331 } 7332 return subsetOf(elts_long, arr_long); 7333 } else if (isNumericType(eltsType) && isNumericType(arrType)) { 7334 // At least one array is float/double. 7335 // Cast both arrays to double and call subsetOf(double[],double[]) 7336 double[] elts_double = new double[Array.getLength(elts)]; 7337 for (int i = 0 ; i < elts_double.length ; i++) { 7338 elts_double[i] = Array.getDouble(elts, i); 7339 } 7340 double[] arr_double = new double[Array.getLength(arr)]; 7341 for (int i = 0 ; i < arr_double.length ; i++) { 7342 arr_double[i] = Array.getDouble(arr, i); 7343 } 7344 return subsetOf(elts_double, arr_double); 7345 } else { 7346 // throw new IllegalArgumentException("both arguments must be arrays of numeric types."); 7347 return false; 7348 } 7349 7350 } 7351 7352 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 7353 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7354 @Pure 7355 public static boolean subsetOf(int @Nullable [] seq1, int @Nullable [] seq2) { 7356 if (seq1 == null) { 7357 return false; 7358 } 7359 if (seq2 == null) { 7360 return false; 7361 } 7362 for (int i = 0 ; i < seq1.length ; i++) { 7363 if (!memberOf(seq1[i], seq2)) { 7364 return false; 7365 } 7366 } 7367 return true; 7368 } 7369 7370 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7371 @Pure 7372 public static boolean subsetOf(int @Nullable [] seq1, long @Nullable [] seq2) { 7373 if (seq1 == null) { 7374 return false; 7375 } 7376 if (seq2 == null) { 7377 return false; 7378 } 7379 for (int i = 0 ; i < seq1.length ; i++) { 7380 if (!memberOf(seq1[i], seq2)) { 7381 return false; 7382 } 7383 } 7384 return true; 7385 } 7386 7387 /** Returns true iff seq contains no duplicate elements. */ 7388 @EnsuresNonNullIf(result=true, expression="#1") 7389 @Pure 7390 public static boolean noDups(int @Nullable [] seq) { 7391 if (seq == null) { 7392 return false; 7393 } 7394 return ArraysPlume.noDuplicates(seq); 7395 } 7396 7397 /** Returns true iff elt is in array arr. */ 7398 @EnsuresNonNullIf(result=true, expression="#2") 7399 @Pure 7400 public static boolean memberOf(int elt, int @Nullable [] arr) { 7401 if (arr == null) { 7402 return false; 7403 } 7404 for (int i = 0 ; i < arr.length ; i++) { 7405 if (eq(arr[i], elt)) { 7406 return true; 7407 } 7408 } 7409 return false; 7410 } 7411 7412 @EnsuresNonNullIf(result=true, expression="#2") 7413 @Pure 7414 public static boolean memberOf(int elt, long @Nullable [] arr) { 7415 if (arr == null) { 7416 return false; 7417 } 7418 for (int i = 0 ; i < arr.length ; i++) { 7419 if (eq(arr[i], elt)) { 7420 return true; 7421 } 7422 } 7423 return false; 7424 } 7425 7426 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 7427 @Pure 7428 public static int @PolyNull [] slice(int @PolyNull [] seq, int start, int end) { 7429 if (seq == null) { 7430 return null; 7431 } 7432 int sliceStart = start; 7433 int sliceEnd = end; 7434 if (start < 0) { 7435 return new int[] { }; 7436 } 7437 if (end > seq.length - 1) { 7438 return new int[] { }; 7439 } 7440 if (sliceStart > sliceEnd) { 7441 return new int[] { }; 7442 } 7443 int length = sliceEnd - sliceStart + 1; 7444 return ArraysPlume.subarray(seq, sliceStart, length); 7445 } 7446 7447 @Pure 7448 public static int @PolyNull [] slice(int @PolyNull [] seq, long start, int end) { 7449 return slice(seq, (int)start, end); 7450 } 7451 @Pure 7452 public static int @PolyNull [] slice(int @PolyNull [] seq, int start, long end) { 7453 return slice(seq, start, (int)end); 7454 } 7455 @Pure 7456 public static int @PolyNull [] slice(int @PolyNull [] seq, long start, long end) { 7457 return slice(seq, (int)start, (int)end); 7458 } 7459 7460 /** True iff all elements in arr equal elt. 7461 * 7462 * Meaning (in pseudo-FOL): 7463 * 7464 * forall i in { 0..arr.length-1 } : arr[i] == elt 7465 * 7466 */ 7467 @EnsuresNonNullIf(result=true, expression="#1") 7468 @Pure 7469 public static boolean eltsEqual(int @Nullable [] arr, int elt) { 7470 if (arr == null) { 7471 return false; 7472 } 7473 for (int i = 0 ; i < arr.length ; i++) { 7474 if (ne(arr[i], elt)) { 7475 return false; 7476 } 7477 } 7478 return true; 7479 } 7480 7481 @EnsuresNonNullIf(result=true, expression="#1") 7482 @Pure 7483 public static boolean eltsEqual(int @Nullable [] arr, long elt) { 7484 if (arr == null) { 7485 return false; 7486 } 7487 for (int i = 0 ; i < arr.length ; i++) { 7488 if (ne(arr[i], elt)) { 7489 return false; 7490 } 7491 } 7492 return true; 7493 } 7494 7495 /** True iff every element in arr does not equal elt. 7496 * 7497 * Meaning (in pseudo-FOL): 7498 * 7499 * forall i in { 0..arr.length-1 } : arr[i] != elt 7500 * 7501 */ 7502 @EnsuresNonNullIf(result=true, expression="#1") 7503 @Pure 7504 public static boolean eltsNotEqual(int @Nullable [] arr, int elt) { 7505 if (arr == null) { 7506 return false; 7507 } 7508 for (int i = 0 ; i < arr.length ; i++) { 7509 if (eq(arr[i], elt)) { 7510 return false; 7511 } 7512 } 7513 return true; 7514 } 7515 7516 @EnsuresNonNullIf(result=true, expression="#1") 7517 @Pure 7518 public static boolean eltsNotEqual(int @Nullable [] arr, long elt) { 7519 if (arr == null) { 7520 return false; 7521 } 7522 for (int i = 0 ; i < arr.length ; i++) { 7523 if (eq(arr[i], elt)) { 7524 return false; 7525 } 7526 } 7527 return true; 7528 } 7529 7530 /** True iff every element in arr is greater than elt. 7531 * 7532 * Meaning (in pseudo-FOL): 7533 * 7534 * forall i in { 0..arr.length-1 } : arr[i] > elt 7535 * 7536 */ 7537 @EnsuresNonNullIf(result=true, expression="#1") 7538 @Pure 7539 public static boolean eltsGT(int @Nullable [] arr, int elt) { 7540 if (arr == null) { 7541 return false; 7542 } 7543 for (int i = 0 ; i < arr.length ; i++) { 7544 if (lte(arr[i], elt)) { 7545 return false; 7546 } 7547 } 7548 return true; 7549 } 7550 7551 @EnsuresNonNullIf(result=true, expression="#1") 7552 @Pure 7553 public static boolean eltsGT(int @Nullable [] arr, long elt) { 7554 if (arr == null) { 7555 return false; 7556 } 7557 for (int i = 0 ; i < arr.length ; i++) { 7558 if (lte(arr[i], elt)) { 7559 return false; 7560 } 7561 } 7562 return true; 7563 } 7564 7565 /** True iff every element in arr is greater than or equal to elt. 7566 * 7567 * Meaning (in pseudo-FOL): 7568 * 7569 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 7570 * 7571 */ 7572 @EnsuresNonNullIf(result=true, expression="#1") 7573 @Pure 7574 public static boolean eltsGTE(int @Nullable [] arr, int elt) { 7575 if (arr == null) { 7576 return false; 7577 } 7578 for (int i = 0 ; i < arr.length ; i++) { 7579 if (lt(arr[i], elt)) { 7580 return false; 7581 } 7582 } 7583 return true; 7584 } 7585 7586 @EnsuresNonNullIf(result=true, expression="#1") 7587 @Pure 7588 public static boolean eltsGTE(int @Nullable [] arr, long elt) { 7589 if (arr == null) { 7590 return false; 7591 } 7592 for (int i = 0 ; i < arr.length ; i++) { 7593 if (lt(arr[i], elt)) { 7594 return false; 7595 } 7596 } 7597 return true; 7598 } 7599 7600 /** True iff every element in arr is less than elt. 7601 * 7602 * Meaning (in pseudo-FOL): 7603 * 7604 * forall i in { 0..arr.length-1 } : arr[i] < elt 7605 * 7606 */ 7607 @EnsuresNonNullIf(result=true, expression="#1") 7608 @Pure 7609 public static boolean eltsLT(int @Nullable [] arr, int elt) { 7610 if (arr == null) { 7611 return false; 7612 } 7613 for (int i = 0 ; i < arr.length ; i++) { 7614 if (gte(arr[i], elt)) { 7615 return false; 7616 } 7617 } 7618 return true; 7619 } 7620 7621 @EnsuresNonNullIf(result=true, expression="#1") 7622 @Pure 7623 public static boolean eltsLT(int @Nullable [] arr, long elt) { 7624 if (arr == null) { 7625 return false; 7626 } 7627 for (int i = 0 ; i < arr.length ; i++) { 7628 if (gte(arr[i], elt)) { 7629 return false; 7630 } 7631 } 7632 return true; 7633 } 7634 7635 /** True iff every element in arr is less than or equal to elt. 7636 * 7637 * Meaning (in pseudo-FOL): 7638 * 7639 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 7640 * 7641 */ 7642 @EnsuresNonNullIf(result=true, expression="#1") 7643 @Pure 7644 public static boolean eltsLTE(int @Nullable [] arr, int elt) { 7645 if (arr == null) { 7646 return false; 7647 } 7648 for (int i = 0 ; i < arr.length ; i++) { 7649 if (gt(arr[i], elt)) { 7650 return false; 7651 } 7652 } 7653 return true; 7654 } 7655 7656 @EnsuresNonNullIf(result=true, expression="#1") 7657 @Pure 7658 public static boolean eltsLTE(int @Nullable [] arr, long elt) { 7659 if (arr == null) { 7660 return false; 7661 } 7662 for (int i = 0 ; i < arr.length ; i++) { 7663 if (gt(arr[i], elt)) { 7664 return false; 7665 } 7666 } 7667 return true; 7668 } 7669 7670 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 7671 * 7672 * Meaning (in pseudo-FOL): 7673 * 7674 * /\ seq1.length == se2.length 7675 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 7676 * 7677 */ 7678 7679 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7680 @Pure 7681 public static boolean pairwiseEqual(int @Nullable [] seq1, int @Nullable [] seq2) { 7682 if (!sameLength(seq1, seq2)) { 7683 return false; 7684 } 7685 assert seq1 != null && seq2 != null; // because sameLength() = true 7686 for (int i = 0 ; i < seq1.length ; i++) { 7687 if (ne(seq1[i], seq2[i])) { 7688 return false; 7689 } 7690 } 7691 return true; 7692 } 7693 7694 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7695 @Pure 7696 public static boolean pairwiseEqual(int @Nullable [] seq1, long @Nullable [] seq2) { 7697 if (!sameLength(seq1, seq2)) { 7698 return false; 7699 } 7700 assert seq1 != null && seq2 != null; // because sameLength() = true 7701 for (int i = 0 ; i < seq1.length ; i++) { 7702 if (ne(seq1[i], seq2[i])) { 7703 return false; 7704 } 7705 } 7706 return true; 7707 } 7708 7709 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 7710 * 7711 * Meaning (in pseudo-FOL): 7712 * 7713 * /\ seq1.length == se2.length 7714 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 7715 * 7716 */ 7717 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7718 @Pure 7719 public static boolean pairwiseNotEqual(int @Nullable [] seq1, int @Nullable [] seq2) { 7720 if (!sameLength(seq1, seq2)) { 7721 return false; 7722 } 7723 assert seq1 != null && seq2 != null; // because sameLength() = true 7724 for (int i = 0 ; i < seq1.length ; i++) { 7725 if (eq(seq1[i], seq2[i])) { 7726 return false; 7727 } 7728 } 7729 return true; 7730 } 7731 7732 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7733 @Pure 7734 public static boolean pairwiseNotEqual(int @Nullable [] seq1, long @Nullable [] seq2) { 7735 if (!sameLength(seq1, seq2)) { 7736 return false; 7737 } 7738 assert seq1 != null && seq2 != null; // because sameLength() = true 7739 for (int i = 0 ; i < seq1.length ; i++) { 7740 if (eq(seq1[i], seq2[i])) { 7741 return false; 7742 } 7743 } 7744 return true; 7745 } 7746 7747 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 7748 * 7749 * Meaning (in pseudo-FOL): 7750 * 7751 * /\ seq1.length == se2.length 7752 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 7753 * 7754 */ 7755 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7756 @Pure 7757 public static boolean pairwiseLT(int @Nullable [] seq1, int @Nullable [] seq2) { 7758 if (!sameLength(seq1, seq2)) { 7759 return false; 7760 } 7761 assert seq1 != null && seq2 != null; // because sameLength() = true 7762 for (int i = 0 ; i < seq1.length ; i++) { 7763 if (gte(seq1[i], seq2[i])) { 7764 return false; 7765 } 7766 } 7767 return true; 7768 } 7769 7770 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7771 @Pure 7772 public static boolean pairwiseLT(int @Nullable [] seq1, long @Nullable [] seq2) { 7773 if (!sameLength(seq1, seq2)) { 7774 return false; 7775 } 7776 assert seq1 != null && seq2 != null; // because sameLength() = true 7777 for (int i = 0 ; i < seq1.length ; i++) { 7778 if (gte(seq1[i], seq2[i])) { 7779 return false; 7780 } 7781 } 7782 return true; 7783 } 7784 7785 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 7786 * Meaning (in pseudo-FOL): 7787 * 7788 * /\ seq1.length == se2.length 7789 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 7790 * 7791 */ 7792 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7793 @Pure 7794 public static boolean pairwiseLTE(int @Nullable [] seq1, int @Nullable [] seq2) { 7795 if (!sameLength(seq1, seq2)) { 7796 return false; 7797 } 7798 assert seq1 != null && seq2 != null; // because sameLength() = true 7799 for (int i = 0 ; i < seq1.length ; i++) { 7800 if (gt(seq1[i], seq2[i])) { 7801 return false; 7802 } 7803 } 7804 return true; 7805 } 7806 7807 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7808 @Pure 7809 public static boolean pairwiseLTE(int @Nullable [] seq1, long @Nullable [] seq2) { 7810 if (!sameLength(seq1, seq2)) { 7811 return false; 7812 } 7813 assert seq1 != null && seq2 != null; // because sameLength() = true 7814 for (int i = 0 ; i < seq1.length ; i++) { 7815 if (gt(seq1[i], seq2[i])) { 7816 return false; 7817 } 7818 } 7819 return true; 7820 } 7821 7822 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 7823 * Meaning (in pseudo-FOL): 7824 * 7825 * /\ seq1.length == se2.length 7826 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 7827 * 7828 */ 7829 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7830 @Pure 7831 public static boolean pairwiseGT(int @Nullable [] seq1, int @Nullable [] seq2) { 7832 if (!sameLength(seq1, seq2)) { 7833 return false; 7834 } 7835 assert seq1 != null && seq2 != null; // because sameLength() = true 7836 for (int i = 0 ; i < seq1.length ; i++) { 7837 if (lte(seq1[i], seq2[i])) { 7838 return false; 7839 } 7840 } 7841 return true; 7842 } 7843 7844 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7845 @Pure 7846 public static boolean pairwiseGT(int @Nullable [] seq1, long @Nullable [] seq2) { 7847 if (!sameLength(seq1, seq2)) { 7848 return false; 7849 } 7850 assert seq1 != null && seq2 != null; // because sameLength() = true 7851 for (int i = 0 ; i < seq1.length ; i++) { 7852 if (lte(seq1[i], seq2[i])) { 7853 return false; 7854 } 7855 } 7856 return true; 7857 } 7858 7859 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 7860 * Meaning (in pseudo-FOL): 7861 * 7862 * /\ seq1.length == se2.length 7863 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 7864 * 7865 */ 7866 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7867 @Pure 7868 public static boolean pairwiseGTE(int @Nullable [] seq1, int @Nullable [] seq2) { 7869 if (!sameLength(seq1, seq2)) { 7870 return false; 7871 } 7872 assert seq1 != null && seq2 != null; // because sameLength() = true 7873 for (int i = 0 ; i < seq1.length ; i++) { 7874 if (lt(seq1[i], seq2[i])) { 7875 return false; 7876 } 7877 } 7878 return true; 7879 } 7880 7881 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7882 @Pure 7883 public static boolean pairwiseGTE(int @Nullable [] seq1, long @Nullable [] seq2) { 7884 if (!sameLength(seq1, seq2)) { 7885 return false; 7886 } 7887 assert seq1 != null && seq2 != null; // because sameLength() = true 7888 for (int i = 0 ; i < seq1.length ; i++) { 7889 if (lt(seq1[i], seq2[i])) { 7890 return false; 7891 } 7892 } 7893 return true; 7894 } 7895 7896 /** 7897 * Returns true iff seq1 is lexically equal to seq2. 7898 * For equality, "lexically" and "pairwise" are the same. 7899 */ 7900 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7901 @Pure 7902 public static boolean lexEqual(int @Nullable [] seq1, int @Nullable [] seq2) { 7903 if (seq1 == null) { 7904 return false; 7905 } 7906 if (seq2 == null) { 7907 return false; 7908 } 7909 return pairwiseEqual(seq1, seq2); 7910 } 7911 7912 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7913 @Pure 7914 public static boolean lexEqual(int @Nullable [] seq1, long @Nullable [] seq2) { 7915 if (seq1 == null) { 7916 return false; 7917 } 7918 if (seq2 == null) { 7919 return false; 7920 } 7921 return pairwiseEqual(seq1, seq2); 7922 } 7923 7924 /** Returns true iff seq1 is lexically not equal to seq2. */ 7925 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7926 @Pure 7927 public static boolean lexNotEqual(int @Nullable [] seq1, int @Nullable [] seq2) { 7928 if (seq1 == null) { 7929 return false; 7930 } 7931 if (seq2 == null) { 7932 return false; 7933 } 7934 return !lexEqual(seq1, seq2); 7935 } 7936 7937 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7938 @Pure 7939 public static boolean lexNotEqual(int @Nullable [] seq1, long @Nullable [] seq2) { 7940 if (seq1 == null) { 7941 return false; 7942 } 7943 if (seq2 == null) { 7944 return false; 7945 } 7946 return !lexEqual(seq1, seq2); 7947 } 7948 7949 /** Returns true iff seq1 is lexically < seq2. */ 7950 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7951 @Pure 7952 public static boolean lexLT(int @Nullable [] seq1, int @Nullable [] seq2) { 7953 if (seq1 == null) { 7954 return false; 7955 } 7956 if (seq2 == null) { 7957 return false; 7958 } 7959 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 7960 for (int i = 0 ; i < minlength ; i++) { 7961 if (gt(seq1[i], seq2[i])) { 7962 return false; 7963 } else if (lt(seq1[i], seq2[i])) { 7964 return true; 7965 } 7966 } 7967 if (seq1.length >= seq2.length) { 7968 return false; 7969 } 7970 return true; 7971 } 7972 7973 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7974 @Pure 7975 public static boolean lexLT(int @Nullable [] seq1, long @Nullable [] seq2) { 7976 if (seq1 == null) { 7977 return false; 7978 } 7979 if (seq2 == null) { 7980 return false; 7981 } 7982 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 7983 for (int i = 0 ; i < minlength ; i++) { 7984 if (gt(seq1[i], seq2[i])) { 7985 return false; 7986 } else if (lt(seq1[i], seq2[i])) { 7987 return true; 7988 } 7989 } 7990 if (seq1.length >= seq2.length) { 7991 return false; 7992 } 7993 return true; 7994 } 7995 7996 /** Returns true iff seq1 is lexically ≤ to seq2. */ 7997 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 7998 @Pure 7999 public static boolean lexLTE(int @Nullable [] seq1, int @Nullable [] seq2) { 8000 if (seq1 == null) { 8001 return false; 8002 } 8003 if (seq2 == null) { 8004 return false; 8005 } 8006 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 8007 for (int i = 0 ; i < minlength ; i++) { 8008 if (gt(seq1[i], seq2[i])) { 8009 return false; 8010 } else if (lt(seq1[i], seq2[i])) { 8011 return true; 8012 } 8013 } 8014 if (seq1.length > seq2.length) { 8015 return false; 8016 } 8017 return true; 8018 } 8019 8020 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8021 @Pure 8022 public static boolean lexLTE(int @Nullable [] seq1, long @Nullable [] seq2) { 8023 if (seq1 == null) { 8024 return false; 8025 } 8026 if (seq2 == null) { 8027 return false; 8028 } 8029 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 8030 for (int i = 0 ; i < minlength ; i++) { 8031 if (gt(seq1[i], seq2[i])) { 8032 return false; 8033 } else if (lt(seq1[i], seq2[i])) { 8034 return true; 8035 } 8036 } 8037 if (seq1.length > seq2.length) { 8038 return false; 8039 } 8040 return true; 8041 } 8042 8043 /** Returns true iff seq1 is lexically > to seq2. */ 8044 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8045 @Pure 8046 public static boolean lexGT(int @Nullable [] seq1, int @Nullable [] seq2) { 8047 if (seq1 == null) { 8048 return false; 8049 } 8050 if (seq2 == null) { 8051 return false; 8052 } 8053 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 8054 for (int i = 0 ; i < minlength ; i++) { 8055 if (lt(seq1[i], seq2[i])) { 8056 return false; 8057 } else if (gt(seq1[i], seq2[i])) { 8058 return true; 8059 } 8060 } 8061 if (seq1.length <= seq2.length) { 8062 return false; 8063 } 8064 return true; 8065 } 8066 8067 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8068 @Pure 8069 public static boolean lexGT(int @Nullable [] seq1, long @Nullable [] seq2) { 8070 if (seq1 == null) { 8071 return false; 8072 } 8073 if (seq2 == null) { 8074 return false; 8075 } 8076 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 8077 for (int i = 0 ; i < minlength ; i++) { 8078 if (lt(seq1[i], seq2[i])) { 8079 return false; 8080 } else if (gt(seq1[i], seq2[i])) { 8081 return true; 8082 } 8083 } 8084 if (seq1.length <= seq2.length) { 8085 return false; 8086 } 8087 return true; 8088 } 8089 8090 /** Returns true iff seq1 is lexically ≥ to seq2. */ 8091 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8092 @Pure 8093 public static boolean lexGTE(int @Nullable [] seq1, int @Nullable [] seq2) { 8094 if (seq1 == null) { 8095 return false; 8096 } 8097 if (seq2 == null) { 8098 return false; 8099 } 8100 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 8101 for (int i = 0 ; i < minlength ; i++) { 8102 if (lt(seq1[i], seq2[i])) { 8103 return false; 8104 } else if (gt(seq1[i], seq2[i])) { 8105 return true; 8106 } 8107 } 8108 if (seq1.length < seq2.length) { 8109 return false; 8110 } 8111 return true; 8112 } 8113 8114 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8115 @Pure 8116 public static boolean lexGTE(int @Nullable [] seq1, long @Nullable [] seq2) { 8117 if (seq1 == null) { 8118 return false; 8119 } 8120 if (seq2 == null) { 8121 return false; 8122 } 8123 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 8124 for (int i = 0 ; i < minlength ; i++) { 8125 if (lt(seq1[i], seq2[i])) { 8126 return false; 8127 } else if (gt(seq1[i], seq2[i])) { 8128 return true; 8129 } 8130 } 8131 if (seq1.length < seq2.length) { 8132 return false; 8133 } 8134 return true; 8135 } 8136 8137 /** True iff for all applicable i, every seq[i] == seq[i+1]. 8138 * 8139 * Meaning (in pseudo-FOL): 8140 * 8141 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 8142 * 8143 */ 8144 @EnsuresNonNullIf(result=true, expression="#1") 8145 @Pure 8146 public static boolean eltwiseEqual(int @Nullable [] seq) { 8147 if (seq == null) { 8148 return false; 8149 } 8150 for (int i = 0 ; i < seq.length ; i++) { 8151 if (i < seq.length - 1) { 8152 if (ne(seq[i], seq[i + 1])) { 8153 return false; 8154 } 8155 } 8156 } 8157 return true; 8158 } 8159 8160 /** True iff for all applicable i, every seq[i] != seq[i+1]. 8161 * 8162 * Meaning (in pseudo-FOL): 8163 * 8164 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 8165 * 8166 */ 8167 @EnsuresNonNullIf(result=true, expression="#1") 8168 @Pure 8169 public static boolean eltwiseNotEqual(int @Nullable [] seq) { 8170 if (seq == null) { 8171 return false; 8172 } 8173 for (int i = 0 ; i < seq.length ; i++) { 8174 if (i < seq.length - 1) { 8175 if (eq(seq[i], seq[i + 1])) { 8176 return false; 8177 } 8178 } 8179 } 8180 return true; 8181 } 8182 8183 /** True iff for all applicable i, every seq[i] < seq[i+1]. 8184 * 8185 * Meaning (in pseudo-FOL): 8186 * 8187 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 8188 * 8189 */ 8190 @EnsuresNonNullIf(result=true, expression="#1") 8191 @Pure 8192 public static boolean eltwiseLT(int @Nullable [] seq) { 8193 if (seq == null) { 8194 return false; 8195 } 8196 for (int i = 0 ; i < seq.length ; i++) { 8197 if (i < seq.length - 1) { 8198 if (gte(seq[i], seq[i + 1])) { 8199 return false; 8200 } 8201 } 8202 } 8203 return true; 8204 } 8205 8206 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 8207 * 8208 * Meaning (in pseudo-FOL): 8209 * 8210 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 8211 * 8212 */ 8213 @EnsuresNonNullIf(result=true, expression="#1") 8214 @Pure 8215 public static boolean eltwiseLTE(int @Nullable [] seq) { 8216 if (seq == null) { 8217 return false; 8218 } 8219 for (int i = 0 ; i < seq.length ; i++) { 8220 if (i < seq.length - 1) { 8221 if (gt(seq[i], seq[i + 1])) { 8222 return false; 8223 } 8224 } 8225 } 8226 return true; 8227 } 8228 8229 /** True iff for all applicable i, every seq[i] > seq[i+1]. 8230 * 8231 * Meaning (in pseudo-FOL): 8232 * 8233 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 8234 * 8235 */ 8236 @EnsuresNonNullIf(result=true, expression="#1") 8237 @Pure 8238 public static boolean eltwiseGT(int @Nullable [] seq) { 8239 if (seq == null) { 8240 return false; 8241 } 8242 for (int i = 0 ; i < seq.length ; i++) { 8243 if (i < seq.length - 1) { 8244 if (lte(seq[i], seq[i + 1])) { 8245 return false; 8246 } 8247 } 8248 } 8249 return true; 8250 } 8251 8252 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 8253 * 8254 * Meaning (in pseudo-FOL): 8255 * 8256 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 8257 * 8258 */ 8259 @EnsuresNonNullIf(result=true, expression="#1") 8260 @Pure 8261 public static boolean eltwiseGTE(int @Nullable [] seq) { 8262 if (seq == null) { 8263 return false; 8264 } 8265 for (int i = 0 ; i < seq.length ; i++) { 8266 if (i < seq.length - 1) { 8267 if (lt(seq[i], seq[i + 1])) { 8268 return false; 8269 } 8270 } 8271 } 8272 return true; 8273 } 8274 8275 /** True iff for all applicable i, every seq[i] == i. 8276 * 8277 * Meaning (in pseudo-FOL): 8278 * 8279 * forall i in { 0..seq.length-1 } : seq[i] == i 8280 * 8281 */ 8282 @EnsuresNonNullIf(result=true, expression="#1") 8283 @Pure 8284 public static boolean eltsEqualIndex(int @Nullable [] seq) { 8285 if (seq == null) { 8286 return false; 8287 } 8288 for (int i = 0 ; i < seq.length ; i++) { 8289 if (ne(seq[i], i)) { 8290 return false; 8291 } 8292 } 8293 return true; 8294 } 8295 8296 /** True iff for all applicable i, every seq[i] != i. 8297 * 8298 * Meaning (in pseudo-FOL): 8299 * 8300 * forall i in { 0..seq.length-1 } : seq[i] != i 8301 * 8302 */ 8303 @EnsuresNonNullIf(result=true, expression="#1") 8304 @Pure 8305 public static boolean eltsNotEqualIndex(int @Nullable [] seq) { 8306 if (seq == null) { 8307 return false; 8308 } 8309 for (int i = 0 ; i < seq.length ; i++) { 8310 if (eq(seq[i], i)) { 8311 return false; 8312 } 8313 } 8314 return true; 8315 } 8316 8317 /** True iff for all applicable i, every seq[i] < i. 8318 * 8319 * Meaning (in pseudo-FOL): 8320 * 8321 * forall i in { 0..seq.length-1 } : seq[i] < i 8322 * 8323 */ 8324 @EnsuresNonNullIf(result=true, expression="#1") 8325 @Pure 8326 public static boolean eltsLtIndex(int @Nullable [] seq) { 8327 if (seq == null) { 8328 return false; 8329 } 8330 for (int i = 0 ; i < seq.length ; i++) { 8331 if (gte(seq[i], i)) { 8332 return false; 8333 } 8334 } 8335 return true; 8336 } 8337 8338 /** True iff for all applicable i, every seq[i] ≤ i. 8339 * 8340 * Meaning (in pseudo-FOL): 8341 * 8342 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 8343 * 8344 */ 8345 @EnsuresNonNullIf(result=true, expression="#1") 8346 @Pure 8347 public static boolean eltsLteIndex(int @Nullable [] seq) { 8348 if (seq == null) { 8349 return false; 8350 } 8351 for (int i = 0 ; i < seq.length ; i++) { 8352 if (gt(seq[i], i)) { 8353 return false; 8354 } 8355 } 8356 return true; 8357 } 8358 8359 /** True iff for all applicable i, every seq[i] > i. 8360 * 8361 * Meaning (in pseudo-FOL): 8362 * 8363 * forall i in { 0..seq.length-1 } : seq[i] > i 8364 * 8365 */ 8366 @EnsuresNonNullIf(result=true, expression="#1") 8367 @Pure 8368 public static boolean eltsGtIndex(int @Nullable [] seq) { 8369 if (seq == null) { 8370 return false; 8371 } 8372 for (int i = 0 ; i < seq.length ; i++) { 8373 if (lte(seq[i], i)) { 8374 return false; 8375 } 8376 } 8377 return true; 8378 } 8379 8380 /** True iff for all applicable i, every seq[i] ≥ i. 8381 * 8382 * Meaning (in pseudo-FOL): 8383 * 8384 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 8385 * 8386 */ 8387 @EnsuresNonNullIf(result=true, expression="#1") 8388 @Pure 8389 public static boolean eltsGteIndex(int @Nullable [] seq) { 8390 if (seq == null) { 8391 return false; 8392 } 8393 for (int i = 0 ; i < seq.length ; i++) { 8394 if (lt(seq[i], i)) { 8395 return false; 8396 } 8397 } 8398 return true; 8399 } 8400 8401 /// Deferencing (accessing) fields 8402 8403 /** 8404 * collectint accepts an object and a list of fields (one of which is of array type, and the 8405 * rest of which are not), and produces an array in which the original object has had the given 8406 * fields accessed. 8407 * 8408 * <p>Daikon creates invariants over "variables" such as the following. 8409 * 8410 * <dl> 8411 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 8412 * for all y's in array x.arr.</dd> 8413 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 8414 * for all x's in array arr.</dd> 8415 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 8416 * </dl> 8417 * 8418 * <p>The collectint() method does this collecting work. 8419 * 8420 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 8421 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 8422 * elements that result from following the fields, one of which is assumed to be an array. 8423 * 8424 * <p> 8425 * requires: fieldStr.length() > 0 and object != null 8426 * <p> 8427 * requires: fieldStr contains only field names, no "[]" strings. 8428 * <p> 8429 * requires: the method only works for field sequences with exactly one field representing an 8430 * array. For example, the collection a[].b[].c will fail. 8431 * 8432 * @return if the resulting collection is of non-primitive type, then returns an array of type 8433 * Object[]. Returns null if any array or field access causes an exception. 8434 */ 8435 8436 @SideEffectFree 8437 public static int @Nullable [] collectint(@Nullable Object object, @Nullable String fieldStr) { 8438 8439 if (object == null) { 8440 return null; 8441 } 8442 if (fieldStr == null) { 8443 return null; 8444 } 8445 8446 // assert fieldStr != null && !"".equals(fieldStr); 8447 String[] fieldNames = fieldStr.split("\\."); 8448 int[] retval = collectint(object, fieldNames, 0); 8449 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 8450 return retval; 8451 } 8452 8453 /** Helper method for collectint(Object, String). 8454 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 8455 * @see collectint(Object, String) 8456 */ 8457 // @PolyNull does not work for return type, because null is returned on error. 8458 @SideEffectFree 8459 private static int @Nullable [] collectint(@Nullable Object object, 8460 String[] fields, int fieldsStartIdx) { 8461 8462 if (object == null) { 8463 return null; 8464 } 8465 assert (fields != null); 8466 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 8467 8468 Object fieldObj; 8469 try { 8470 Field field = (object instanceof java.lang.Class<?>) 8471 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 8472 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 8473 field.setAccessible(true); 8474 // Class cls = field.getType(); 8475 fieldObj = field.get(object); 8476 // System.out.println("***fieldObj="+fieldObj); 8477 8478 } catch (Exception e) { 8479 return null; 8480 8481 } 8482 8483 if (fieldObj == null) { 8484 return null; 8485 } 8486 8487 // base case: just accessed the last field 8488 if (fields.length - 1 == fieldsStartIdx) { 8489 8490 if (fieldObj.getClass().isArray()) { 8491 // last field is an array 8492 return (int[])fieldObj; 8493 } else { 8494 // This hack should be removed in favor of, at "oneEltArray = ..." 8495 // below, calling a version of collectint_field that throws an 8496 // error. Then, this case becomes a run-time error. -MDE 8497 8498 // Just one element; return a one-element array. 8499 // assert cls.equals(Integer.TYPE); 8500 return new int[] { ((Integer)fieldObj).intValue() }; 8501 } 8502 } else { 8503 // recursive case: more fields to access after this one 8504 8505 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 8506 8507 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 8508 int[] intermediate = new int[collection.size()]; 8509 int index = 0; 8510 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 8511 Object obj = i.next(); 8512 int[] oneEltArray = collectint(obj, fields, fieldsStartIdx + 1); 8513 if (oneEltArray == null) { 8514 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 8515 } 8516 // assert oneEltArray.length == 1; 8517 intermediate[index++] = oneEltArray[0]; 8518 } 8519 return intermediate; 8520 } else if (fieldObj.getClass().isArray()) { 8521 8522 // collect elements across array 8523 int[] intermediate = new int[Array.getLength(fieldObj)]; 8524 for (int i = 0 ; i < intermediate.length ; i++) { 8525 Object obj = Array.get(fieldObj, i); 8526 int[] oneEltArray = collectint(obj, fields, fieldsStartIdx + 1); 8527 if (oneEltArray == null) { 8528 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 8529 } 8530 // assert oneEltArray.length == 1; 8531 intermediate[i] = oneEltArray[0]; 8532 } 8533 return intermediate; 8534 } else { 8535 8536 return collectint(fieldObj, fields, fieldsStartIdx + 1); 8537 } 8538 } 8539 } 8540 8541 /** 8542 * Returns the results of dereferencing the fields for 'object'. For example, the call 8543 * 8544 * <pre>collectint_field(x, "f.g.h")</pre> 8545 * 8546 * has the same value as 8547 * 8548 * <pre>x.f.g.h</pre>. 8549 * Returns a default value if any field access causes an exception. 8550 */ 8551 @SideEffectFree 8552 public static int collectint_field(Object object, String fieldStr) { 8553 8554 if (object == null) { 8555 return Integer.MAX_VALUE; // return default value 8556 } 8557 if (fieldStr == null) { 8558 return Integer.MAX_VALUE; // return default value 8559 } 8560 8561 String[] fieldNames = fieldStr.split("\\."); 8562 8563 // Holds the intermediate (and final) result 8564 Object fieldObj = object; 8565 8566 for (int i = 0 ; i < fieldNames.length ; i++) { 8567 8568 String fieldName = fieldNames[i]; 8569 8570 try { 8571 Field field = 8572 (fieldObj instanceof java.lang.Class<?>) 8573 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 8574 : fieldObj.getClass().getDeclaredField(fieldName); 8575 field.setAccessible(true); 8576 fieldObj = field.get(fieldObj); 8577 8578 if (fieldObj == null) { 8579 return Integer.MAX_VALUE; // return default value 8580 } 8581 8582 } catch (Exception e) { 8583 return Integer.MAX_VALUE; // return default value 8584 8585 } 8586 8587 } 8588 8589 return ((Integer)fieldObj).intValue(); 8590 } 8591 8592 /////////////////////////////////////////////////////////////////////////// 8593 /// Methods for "long" (from QuantBody.java.jpp) 8594 /// 8595 8596 /** 8597 * Returns the ith element of the array or collection argument. If the argument is null or not an 8598 * array or collection, returns a default value (Long.MAX_VALUE). 8599 */ 8600 8601 @Pure 8602 public static long getElement_long(Object o, long i) { 8603 if (o == null) { 8604 return Long.MAX_VALUE; // return default value 8605 } 8606 java.lang.Class<?> c = o.getClass(); 8607 if (c.isArray()) { 8608 return java.lang.reflect.Array.getLong(o, (int)i); 8609 } else if (o instanceof java.util.AbstractCollection<?>) { 8610 return java.lang.reflect.Array.getLong(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 8611 } else { 8612 return Long.MAX_VALUE; // return default value 8613 } 8614 } 8615 8616 @Pure 8617 public static long getElement_long(long[] arr, long i) { 8618 if (arr == null) { 8619 return Long.MAX_VALUE; // return default value 8620 } 8621 return arr[(int)i]; 8622 } 8623 8624 private static boolean eq(long x, long y) { 8625 return x == y; 8626 } 8627 8628 private static boolean ne(long x, long y) { 8629 return x != y; 8630 } 8631 8632 private static boolean lt(long x, long y) { 8633 return x < y; 8634 } 8635 8636 private static boolean lte(long x, long y) { 8637 return x <= y; 8638 } 8639 8640 private static boolean gt(long x, long y) { 8641 return x > y; 8642 } 8643 8644 private static boolean gte(long x, long y) { 8645 return x >= y; 8646 } 8647 8648 /** True iff both sequences are non-null and have the same length. */ 8649 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 8650 @Pure 8651 public static boolean sameLength(long @Nullable [] seq1, long @Nullable [] seq2) { 8652 return ((seq1 != null) 8653 && (seq2 != null) 8654 && seq1.length == seq2.length); 8655 } 8656 8657 /** True iff both sequences are non-null and have the same length. */ 8658 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 8659 @Pure 8660 public static boolean sameLength(long @Nullable [] seq1, int @Nullable [] seq2) { 8661 return ((seq1 != null) 8662 && (seq2 != null) 8663 && seq1.length == seq2.length); 8664 } 8665 8666 /** True iff both sequences have the same length, and all seq2[i] divide seq1[i]. 8667 * 8668 * Meaning (in pseudo-FOL): 8669 * 8670 * <pre> 8671 * /\ seq1.length == seq2.length 8672 * /\ forall i in { 0..seq2.length-1 } : seq2[i] divides seq1[i] 8673 * </pre> 8674 * 8675 */ 8676 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8677 @Pure 8678 public static boolean pairwiseDivides(long[] seq1, long[] seq2) { 8679 if (!sameLength(seq1, seq2)) { 8680 return false; 8681 } 8682 assert seq1 != null && seq2 != null; // because sameLength() = true 8683 for (int i = 0 ; i < seq1.length ; i++) { 8684 if (ne(seq1[i] % seq2[i], 0)) { 8685 return false; 8686 } 8687 } 8688 return true; 8689 } 8690 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8691 @Pure 8692 public static boolean pairwiseDivides(long[] seq1, int[] seq2) { 8693 if (!sameLength(seq1, seq2)) { 8694 return false; 8695 } 8696 assert seq1 != null && seq2 != null; // because sameLength() = true 8697 for (int i = 0 ; i < seq1.length ; i++) { 8698 if (ne(seq1[i] % seq2[i], 0)) { 8699 return false; 8700 } 8701 } 8702 return true; 8703 } 8704 8705 /** 8706 * True iff both sequences have the same length, and all seq1[i] == seq2[i] * seq2[i]. 8707 * 8708 * Meaning (in pseudo-FOL): 8709 * 8710 * <pre> 8711 * /\ seq1.length == seq2.length 8712 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == seq2[i] * seq2[i] 8713 * </pre> 8714 * 8715 */ 8716 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8717 @Pure 8718 public static boolean pairwiseSquare(long[] seq1, long[] seq2) { 8719 if (!sameLength(seq1, seq2)) { 8720 return false; 8721 } 8722 assert seq1 != null && seq2 != null; // because sameLength() = true 8723 for (int i = 0 ; i < seq1.length ; i++) { 8724 if (ne(seq1[i], seq2[i] * seq2[i])) { 8725 return false; 8726 } 8727 } 8728 return true; 8729 } 8730 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8731 @Pure 8732 public static boolean pairwiseSquare(long[] seq1, int[] seq2) { 8733 if (!sameLength(seq1, seq2)) { 8734 return false; 8735 } 8736 assert seq1 != null && seq2 != null; // because sameLength() = true 8737 for (int i = 0 ; i < seq1.length ; i++) { 8738 8739 if (ne(seq1[i], ((long) seq2[i]) * ((long) seq2[i]))) { 8740 8741 return false; 8742 } 8743 } 8744 return true; 8745 } 8746 8747 /** True iff both sequences have the same length, and all seq1[i] == ~ seq2[i]. 8748 * 8749 * Meaning (in pseudo-FOL): 8750 * 8751 * <pre> 8752 * /\ seq1.length == seq2.length 8753 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == ~ seq2[i] 8754 * </pre> 8755 * 8756 */ 8757 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8758 @Pure 8759 public static boolean pairwiseBitwiseComplement(long[] seq1, long[] seq2) { 8760 if (!sameLength(seq1, seq2)) { 8761 return false; 8762 } 8763 assert seq1 != null && seq2 != null; // because sameLength() = true 8764 for (int i = 0 ; i < seq1.length ; i++) { 8765 if (seq1[i] != ~seq2[i]) { 8766 return false; 8767 } 8768 } 8769 return true; 8770 } 8771 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8772 @Pure 8773 public static boolean pairwiseBitwiseComplement(long[] seq1, int[] seq2) { 8774 if (!sameLength(seq1, seq2)) { 8775 return false; 8776 } 8777 assert seq1 != null && seq2 != null; // because sameLength() = true 8778 for (int i = 0 ; i < seq1.length ; i++) { 8779 if (seq1[i] != ~seq2[i]) { 8780 return false; 8781 } 8782 } 8783 return true; 8784 } 8785 8786 /** True iff both sequences have the same length, and all seq1[i] == (seq2[i] | seq1[i]). 8787 * 8788 * Meaning (in pseudo-FOL): 8789 * 8790 * <pre> 8791 * /\ seq1.length == seq2.length 8792 * /\ forall i in { 0..seq2.length-1 } : seq1[i] == (seq2[i] | seq1[i]) 8793 * </pre> 8794 * 8795 */ 8796 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8797 @Pure 8798 public static boolean pairwiseBitwiseSubset(long[] seq1, long[] seq2) { 8799 if (seq1 == null) { 8800 return false; 8801 } 8802 if (seq2 == null) { 8803 return false; 8804 } 8805 if (seq1.length != seq2.length) { 8806 return false; 8807 } 8808 for (int i = 0 ; i < seq1.length ; i++) { 8809 if (ne(seq1[i], (seq2[i] | seq1[i]))) { 8810 return false; 8811 } 8812 } 8813 return true; 8814 } 8815 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8816 @Pure 8817 public static boolean pairwiseBitwiseSubset(long[] seq1, int[] seq2) { 8818 if (!sameLength(seq1, seq2)) { 8819 return false; 8820 } 8821 assert seq1 != null && seq2 != null; // because sameLength() = true 8822 for (int i = 0 ; i < seq1.length ; i++) { 8823 if (ne(seq1[i], (seq2[i] | seq1[i]))) { 8824 return false; 8825 } 8826 } 8827 return true; 8828 } 8829 8830 /** 8831 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 8832 * 8833 * <p>If either array is null, returns null. If either array is empty, returns only those 8834 * elements in the other array. If both arrays are empty, returns a new empty array. 8835 */ 8836 @SideEffectFree 8837 public static long @PolyNull [] concat(long @PolyNull [] seq1, long @PolyNull [] seq2) { 8838 if (seq1 == null) { 8839 return null; 8840 } 8841 if (seq2 == null) { 8842 return null; 8843 } 8844 return ArraysPlume.concat(seq1, seq2); 8845 } 8846 8847 @SideEffectFree 8848 public static long @PolyNull [] concat(long @PolyNull [] seq1, int @PolyNull [] seq2) { 8849 if (seq1 == null) { 8850 return null; 8851 } 8852 if (seq2 == null) { 8853 return null; 8854 } 8855 // Cannot just use ArraysPlume.concat because the two arrays 8856 // have different types. This essentially inlines that method. 8857 int newLength = seq1.length + seq2.length; 8858 long[] retval = new long[newLength]; 8859 8860 System.arraycopy(seq1, 0, retval, 0, seq1.length); 8861 for (int j = 0 ; j < seq2.length ; j++) { 8862 retval[seq1.length + j] = seq2[j]; 8863 } 8864 8865 return retval; 8866 } 8867 8868 /** 8869 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 8870 * assurances about the order or repetition of elements: elements may be repeated, and their 8871 * order may be different from the order of elements in seq1 and seq2. 8872 */ 8873 @SideEffectFree 8874 public static long @PolyNull [] union(long @PolyNull [] seq1, long @PolyNull [] seq2) { 8875 if (seq1 == null) { 8876 return null; 8877 } 8878 if (seq2 == null) { 8879 return null; 8880 } 8881 return concat(seq1, seq2); 8882 } 8883 8884 @Pure 8885 public static long @PolyNull [] union(long @PolyNull [] seq1, int @PolyNull [] seq2) { 8886 if (seq1 == null) { 8887 return null; 8888 } 8889 if (seq2 == null) { 8890 return null; 8891 } 8892 return concat(seq1, seq2); 8893 } 8894 8895 /** 8896 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 8897 * gives no assurances about the order or repetition of elements: elements may be repeated, and 8898 * their order may be different from the order of elements in seq1 and seq2. 8899 */ 8900 @Pure 8901 public static long @PolyNull [] intersection(long @PolyNull [] seq1, long @PolyNull [] seq2) { 8902 if (seq1 == null) { 8903 return null; 8904 } 8905 if (seq2 == null) { 8906 return null; 8907 } 8908 long[] intermediate = new long[Math.min(seq1.length, seq2.length)]; 8909 int length = 0; 8910 for (int i = 0 ; i < seq1.length ; i++) { 8911 if (memberOf(seq1[i], seq2) ) { 8912 intermediate[length++] = seq1[i]; 8913 } 8914 } 8915 return ArraysPlume.subarray(intermediate, 0, length); 8916 } 8917 8918 @Pure 8919 public static long @PolyNull [] intersection(long @PolyNull [] seq1, int @PolyNull [] seq2) { 8920 if (seq1 == null) { 8921 return null; 8922 } 8923 if (seq2 == null) { 8924 return null; 8925 } 8926 long[] intermediate = new long[Math.min(seq1.length, seq2.length)]; 8927 int length = 0; 8928 for (int i = 0 ; i < seq1.length ; i++) { 8929 if (memberOf(seq1[i], seq2) ) { 8930 intermediate[length++] = seq1[i]; 8931 } 8932 } 8933 return ArraysPlume.subarray(intermediate, 0, length); 8934 } 8935 8936 /** 8937 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 8938 * no assurances about the order or repetition of elements: elements may be repeated, and their 8939 * order may be different from the order of elements in seq1 and seq2. 8940 */ 8941 @Pure 8942 public static long @PolyNull [] setDiff(long @PolyNull [] seq1, long @PolyNull [] seq2) { 8943 if (seq1 == null) { 8944 return null; 8945 } 8946 if (seq2 == null) { 8947 return null; 8948 } 8949 long[] intermediate = new long[seq1.length]; 8950 int length = 0; 8951 for (int i = 0 ; i < seq1.length ; i++) { 8952 if (!memberOf(seq1[i], seq2)) { 8953 intermediate[length++] = seq1[i]; 8954 } 8955 } 8956 return ArraysPlume.subarray(intermediate, 0, length); 8957 } 8958 8959 @Pure 8960 public static long @PolyNull [] setDiff(long @PolyNull [] seq1, int @PolyNull [] seq2) { 8961 if (seq1 == null) { 8962 return null; 8963 } 8964 if (seq2 == null) { 8965 return null; 8966 } 8967 long[] intermediate = new long[seq1.length]; 8968 int length = 0; 8969 for (int i = 0 ; i < seq1.length ; i++) { 8970 if (!memberOf(seq1[i], seq2)) { 8971 intermediate[length++] = seq1[i]; 8972 } 8973 } 8974 return ArraysPlume.subarray(intermediate, 0, length); 8975 } 8976 8977 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 8978 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 8979 @Pure 8980 public static boolean setEqual(long @Nullable [] seq1, long @Nullable [] seq2) { 8981 if (seq1 == null) { 8982 return false; 8983 } 8984 if (seq2 == null) { 8985 return false; 8986 } 8987 for (int i = 0; i < seq1.length ; i++) { 8988 if (!memberOf(seq1[i], seq2) ) { 8989 return false; 8990 } 8991 } 8992 for (int i = 0; i < seq2.length ; i++) { 8993 if (!memberOf(seq2[i], seq1) ) { 8994 return false; 8995 } 8996 } 8997 return true; 8998 } 8999 9000 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9001 @Pure 9002 public static boolean setEqual(long @Nullable [] seq1, int @Nullable [] seq2) { 9003 if (seq1 == null) { 9004 return false; 9005 } 9006 if (seq2 == null) { 9007 return false; 9008 } 9009 for (int i = 0; i < seq1.length ; i++) { 9010 if (!memberOf(seq1[i], seq2) ) { 9011 return false; 9012 } 9013 } 9014 for (int i = 0; i < seq2.length ; i++) { 9015 if (!memberOf(seq2[i], seq1) ) { 9016 return false; 9017 } 9018 } 9019 return true; 9020 } 9021 9022 /** True iff seq1 is the reverse of seq2. 9023 * 9024 * Meaning (in pseudo-FOL): 9025 * 9026 * <pre> 9027 * /\ seq1.length == seq2.length 9028 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 9029 * </pre> 9030 * 9031 */ 9032 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9033 @Pure 9034 public static boolean isReverse(long[] seq1, long[] seq2) { 9035 if (!sameLength(seq1, seq2)) { 9036 return false; 9037 } 9038 assert seq1 != null && seq2 != null; // because sameLength() = true 9039 int length = seq1.length; 9040 for (int i = 0 ; i < length ; i++) { 9041 if (ne(seq1[i], seq2[length - i - 1])) { 9042 return false; 9043 } 9044 } 9045 return true; 9046 } 9047 9048 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9049 @Pure 9050 public static boolean isReverse(long @Nullable [] seq1, int @Nullable [] seq2) { 9051 if (!sameLength(seq1, seq2)) { 9052 return false; 9053 } 9054 assert seq1 != null && seq2 != null; // because sameLength() = true 9055 int length = seq1.length; 9056 for (int i = 0 ; i < length ; i++) { 9057 if (ne(seq1[i], seq2[length - i - 1])) { 9058 return false; 9059 } 9060 } 9061 return true; 9062 } 9063 9064 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 9065 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9066 @Pure 9067 public static boolean subsetOf(long @Nullable [] seq1, long @Nullable [] seq2) { 9068 if (seq1 == null) { 9069 return false; 9070 } 9071 if (seq2 == null) { 9072 return false; 9073 } 9074 for (int i = 0 ; i < seq1.length ; i++) { 9075 if (!memberOf(seq1[i], seq2)) { 9076 return false; 9077 } 9078 } 9079 return true; 9080 } 9081 9082 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9083 @Pure 9084 public static boolean subsetOf(long @Nullable [] seq1, int @Nullable [] seq2) { 9085 if (seq1 == null) { 9086 return false; 9087 } 9088 if (seq2 == null) { 9089 return false; 9090 } 9091 for (int i = 0 ; i < seq1.length ; i++) { 9092 if (!memberOf(seq1[i], seq2)) { 9093 return false; 9094 } 9095 } 9096 return true; 9097 } 9098 9099 /** Returns true iff seq contains no duplicate elements. */ 9100 @EnsuresNonNullIf(result=true, expression="#1") 9101 @Pure 9102 public static boolean noDups(long @Nullable [] seq) { 9103 if (seq == null) { 9104 return false; 9105 } 9106 return ArraysPlume.noDuplicates(seq); 9107 } 9108 9109 /** Returns true iff elt is in array arr. */ 9110 @EnsuresNonNullIf(result=true, expression="#2") 9111 @Pure 9112 public static boolean memberOf(long elt, long @Nullable [] arr) { 9113 if (arr == null) { 9114 return false; 9115 } 9116 for (int i = 0 ; i < arr.length ; i++) { 9117 if (eq(arr[i], elt)) { 9118 return true; 9119 } 9120 } 9121 return false; 9122 } 9123 9124 @EnsuresNonNullIf(result=true, expression="#2") 9125 @Pure 9126 public static boolean memberOf(long elt, int @Nullable [] arr) { 9127 if (arr == null) { 9128 return false; 9129 } 9130 for (int i = 0 ; i < arr.length ; i++) { 9131 if (eq(arr[i], elt)) { 9132 return true; 9133 } 9134 } 9135 return false; 9136 } 9137 9138 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 9139 @Pure 9140 public static long @PolyNull [] slice(long @PolyNull [] seq, int start, int end) { 9141 if (seq == null) { 9142 return null; 9143 } 9144 int sliceStart = start; 9145 int sliceEnd = end; 9146 if (start < 0) { 9147 return new long[] { }; 9148 } 9149 if (end > seq.length - 1) { 9150 return new long[] { }; 9151 } 9152 if (sliceStart > sliceEnd) { 9153 return new long[] { }; 9154 } 9155 int length = sliceEnd - sliceStart + 1; 9156 return ArraysPlume.subarray(seq, sliceStart, length); 9157 } 9158 9159 @Pure 9160 public static long @PolyNull [] slice(long @PolyNull [] seq, long start, int end) { 9161 return slice(seq, (int)start, end); 9162 } 9163 @Pure 9164 public static long @PolyNull [] slice(long @PolyNull [] seq, int start, long end) { 9165 return slice(seq, start, (int)end); 9166 } 9167 @Pure 9168 public static long @PolyNull [] slice(long @PolyNull [] seq, long start, long end) { 9169 return slice(seq, (int)start, (int)end); 9170 } 9171 9172 /** True iff all elements in arr equal elt. 9173 * 9174 * Meaning (in pseudo-FOL): 9175 * 9176 * forall i in { 0..arr.length-1 } : arr[i] == elt 9177 * 9178 */ 9179 @EnsuresNonNullIf(result=true, expression="#1") 9180 @Pure 9181 public static boolean eltsEqual(long @Nullable [] arr, long elt) { 9182 if (arr == null) { 9183 return false; 9184 } 9185 for (int i = 0 ; i < arr.length ; i++) { 9186 if (ne(arr[i], elt)) { 9187 return false; 9188 } 9189 } 9190 return true; 9191 } 9192 9193 @EnsuresNonNullIf(result=true, expression="#1") 9194 @Pure 9195 public static boolean eltsEqual(long @Nullable [] arr, int elt) { 9196 if (arr == null) { 9197 return false; 9198 } 9199 for (int i = 0 ; i < arr.length ; i++) { 9200 if (ne(arr[i], elt)) { 9201 return false; 9202 } 9203 } 9204 return true; 9205 } 9206 9207 /** True iff every element in arr does not equal elt. 9208 * 9209 * Meaning (in pseudo-FOL): 9210 * 9211 * forall i in { 0..arr.length-1 } : arr[i] != elt 9212 * 9213 */ 9214 @EnsuresNonNullIf(result=true, expression="#1") 9215 @Pure 9216 public static boolean eltsNotEqual(long @Nullable [] arr, long elt) { 9217 if (arr == null) { 9218 return false; 9219 } 9220 for (int i = 0 ; i < arr.length ; i++) { 9221 if (eq(arr[i], elt)) { 9222 return false; 9223 } 9224 } 9225 return true; 9226 } 9227 9228 @EnsuresNonNullIf(result=true, expression="#1") 9229 @Pure 9230 public static boolean eltsNotEqual(long @Nullable [] arr, int elt) { 9231 if (arr == null) { 9232 return false; 9233 } 9234 for (int i = 0 ; i < arr.length ; i++) { 9235 if (eq(arr[i], elt)) { 9236 return false; 9237 } 9238 } 9239 return true; 9240 } 9241 9242 /** True iff every element in arr is greater than elt. 9243 * 9244 * Meaning (in pseudo-FOL): 9245 * 9246 * forall i in { 0..arr.length-1 } : arr[i] > elt 9247 * 9248 */ 9249 @EnsuresNonNullIf(result=true, expression="#1") 9250 @Pure 9251 public static boolean eltsGT(long @Nullable [] arr, long elt) { 9252 if (arr == null) { 9253 return false; 9254 } 9255 for (int i = 0 ; i < arr.length ; i++) { 9256 if (lte(arr[i], elt)) { 9257 return false; 9258 } 9259 } 9260 return true; 9261 } 9262 9263 @EnsuresNonNullIf(result=true, expression="#1") 9264 @Pure 9265 public static boolean eltsGT(long @Nullable [] arr, int elt) { 9266 if (arr == null) { 9267 return false; 9268 } 9269 for (int i = 0 ; i < arr.length ; i++) { 9270 if (lte(arr[i], elt)) { 9271 return false; 9272 } 9273 } 9274 return true; 9275 } 9276 9277 /** True iff every element in arr is greater than or equal to elt. 9278 * 9279 * Meaning (in pseudo-FOL): 9280 * 9281 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 9282 * 9283 */ 9284 @EnsuresNonNullIf(result=true, expression="#1") 9285 @Pure 9286 public static boolean eltsGTE(long @Nullable [] arr, long elt) { 9287 if (arr == null) { 9288 return false; 9289 } 9290 for (int i = 0 ; i < arr.length ; i++) { 9291 if (lt(arr[i], elt)) { 9292 return false; 9293 } 9294 } 9295 return true; 9296 } 9297 9298 @EnsuresNonNullIf(result=true, expression="#1") 9299 @Pure 9300 public static boolean eltsGTE(long @Nullable [] arr, int elt) { 9301 if (arr == null) { 9302 return false; 9303 } 9304 for (int i = 0 ; i < arr.length ; i++) { 9305 if (lt(arr[i], elt)) { 9306 return false; 9307 } 9308 } 9309 return true; 9310 } 9311 9312 /** True iff every element in arr is less than elt. 9313 * 9314 * Meaning (in pseudo-FOL): 9315 * 9316 * forall i in { 0..arr.length-1 } : arr[i] < elt 9317 * 9318 */ 9319 @EnsuresNonNullIf(result=true, expression="#1") 9320 @Pure 9321 public static boolean eltsLT(long @Nullable [] arr, long elt) { 9322 if (arr == null) { 9323 return false; 9324 } 9325 for (int i = 0 ; i < arr.length ; i++) { 9326 if (gte(arr[i], elt)) { 9327 return false; 9328 } 9329 } 9330 return true; 9331 } 9332 9333 @EnsuresNonNullIf(result=true, expression="#1") 9334 @Pure 9335 public static boolean eltsLT(long @Nullable [] arr, int elt) { 9336 if (arr == null) { 9337 return false; 9338 } 9339 for (int i = 0 ; i < arr.length ; i++) { 9340 if (gte(arr[i], elt)) { 9341 return false; 9342 } 9343 } 9344 return true; 9345 } 9346 9347 /** True iff every element in arr is less than or equal to elt. 9348 * 9349 * Meaning (in pseudo-FOL): 9350 * 9351 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 9352 * 9353 */ 9354 @EnsuresNonNullIf(result=true, expression="#1") 9355 @Pure 9356 public static boolean eltsLTE(long @Nullable [] arr, long elt) { 9357 if (arr == null) { 9358 return false; 9359 } 9360 for (int i = 0 ; i < arr.length ; i++) { 9361 if (gt(arr[i], elt)) { 9362 return false; 9363 } 9364 } 9365 return true; 9366 } 9367 9368 @EnsuresNonNullIf(result=true, expression="#1") 9369 @Pure 9370 public static boolean eltsLTE(long @Nullable [] arr, int elt) { 9371 if (arr == null) { 9372 return false; 9373 } 9374 for (int i = 0 ; i < arr.length ; i++) { 9375 if (gt(arr[i], elt)) { 9376 return false; 9377 } 9378 } 9379 return true; 9380 } 9381 9382 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 9383 * 9384 * Meaning (in pseudo-FOL): 9385 * 9386 * /\ seq1.length == se2.length 9387 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 9388 * 9389 */ 9390 9391 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9392 @Pure 9393 public static boolean pairwiseEqual(long @Nullable [] seq1, long @Nullable [] seq2) { 9394 if (!sameLength(seq1, seq2)) { 9395 return false; 9396 } 9397 assert seq1 != null && seq2 != null; // because sameLength() = true 9398 for (int i = 0 ; i < seq1.length ; i++) { 9399 if (ne(seq1[i], seq2[i])) { 9400 return false; 9401 } 9402 } 9403 return true; 9404 } 9405 9406 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9407 @Pure 9408 public static boolean pairwiseEqual(long @Nullable [] seq1, int @Nullable [] seq2) { 9409 if (!sameLength(seq1, seq2)) { 9410 return false; 9411 } 9412 assert seq1 != null && seq2 != null; // because sameLength() = true 9413 for (int i = 0 ; i < seq1.length ; i++) { 9414 if (ne(seq1[i], seq2[i])) { 9415 return false; 9416 } 9417 } 9418 return true; 9419 } 9420 9421 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 9422 * 9423 * Meaning (in pseudo-FOL): 9424 * 9425 * /\ seq1.length == se2.length 9426 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 9427 * 9428 */ 9429 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9430 @Pure 9431 public static boolean pairwiseNotEqual(long @Nullable [] seq1, long @Nullable [] seq2) { 9432 if (!sameLength(seq1, seq2)) { 9433 return false; 9434 } 9435 assert seq1 != null && seq2 != null; // because sameLength() = true 9436 for (int i = 0 ; i < seq1.length ; i++) { 9437 if (eq(seq1[i], seq2[i])) { 9438 return false; 9439 } 9440 } 9441 return true; 9442 } 9443 9444 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9445 @Pure 9446 public static boolean pairwiseNotEqual(long @Nullable [] seq1, int @Nullable [] seq2) { 9447 if (!sameLength(seq1, seq2)) { 9448 return false; 9449 } 9450 assert seq1 != null && seq2 != null; // because sameLength() = true 9451 for (int i = 0 ; i < seq1.length ; i++) { 9452 if (eq(seq1[i], seq2[i])) { 9453 return false; 9454 } 9455 } 9456 return true; 9457 } 9458 9459 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 9460 * 9461 * Meaning (in pseudo-FOL): 9462 * 9463 * /\ seq1.length == se2.length 9464 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 9465 * 9466 */ 9467 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9468 @Pure 9469 public static boolean pairwiseLT(long @Nullable [] seq1, long @Nullable [] seq2) { 9470 if (!sameLength(seq1, seq2)) { 9471 return false; 9472 } 9473 assert seq1 != null && seq2 != null; // because sameLength() = true 9474 for (int i = 0 ; i < seq1.length ; i++) { 9475 if (gte(seq1[i], seq2[i])) { 9476 return false; 9477 } 9478 } 9479 return true; 9480 } 9481 9482 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9483 @Pure 9484 public static boolean pairwiseLT(long @Nullable [] seq1, int @Nullable [] seq2) { 9485 if (!sameLength(seq1, seq2)) { 9486 return false; 9487 } 9488 assert seq1 != null && seq2 != null; // because sameLength() = true 9489 for (int i = 0 ; i < seq1.length ; i++) { 9490 if (gte(seq1[i], seq2[i])) { 9491 return false; 9492 } 9493 } 9494 return true; 9495 } 9496 9497 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 9498 * Meaning (in pseudo-FOL): 9499 * 9500 * /\ seq1.length == se2.length 9501 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 9502 * 9503 */ 9504 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9505 @Pure 9506 public static boolean pairwiseLTE(long @Nullable [] seq1, long @Nullable [] seq2) { 9507 if (!sameLength(seq1, seq2)) { 9508 return false; 9509 } 9510 assert seq1 != null && seq2 != null; // because sameLength() = true 9511 for (int i = 0 ; i < seq1.length ; i++) { 9512 if (gt(seq1[i], seq2[i])) { 9513 return false; 9514 } 9515 } 9516 return true; 9517 } 9518 9519 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9520 @Pure 9521 public static boolean pairwiseLTE(long @Nullable [] seq1, int @Nullable [] seq2) { 9522 if (!sameLength(seq1, seq2)) { 9523 return false; 9524 } 9525 assert seq1 != null && seq2 != null; // because sameLength() = true 9526 for (int i = 0 ; i < seq1.length ; i++) { 9527 if (gt(seq1[i], seq2[i])) { 9528 return false; 9529 } 9530 } 9531 return true; 9532 } 9533 9534 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 9535 * Meaning (in pseudo-FOL): 9536 * 9537 * /\ seq1.length == se2.length 9538 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 9539 * 9540 */ 9541 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9542 @Pure 9543 public static boolean pairwiseGT(long @Nullable [] seq1, long @Nullable [] seq2) { 9544 if (!sameLength(seq1, seq2)) { 9545 return false; 9546 } 9547 assert seq1 != null && seq2 != null; // because sameLength() = true 9548 for (int i = 0 ; i < seq1.length ; i++) { 9549 if (lte(seq1[i], seq2[i])) { 9550 return false; 9551 } 9552 } 9553 return true; 9554 } 9555 9556 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9557 @Pure 9558 public static boolean pairwiseGT(long @Nullable [] seq1, int @Nullable [] seq2) { 9559 if (!sameLength(seq1, seq2)) { 9560 return false; 9561 } 9562 assert seq1 != null && seq2 != null; // because sameLength() = true 9563 for (int i = 0 ; i < seq1.length ; i++) { 9564 if (lte(seq1[i], seq2[i])) { 9565 return false; 9566 } 9567 } 9568 return true; 9569 } 9570 9571 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 9572 * Meaning (in pseudo-FOL): 9573 * 9574 * /\ seq1.length == se2.length 9575 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 9576 * 9577 */ 9578 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9579 @Pure 9580 public static boolean pairwiseGTE(long @Nullable [] seq1, long @Nullable [] seq2) { 9581 if (!sameLength(seq1, seq2)) { 9582 return false; 9583 } 9584 assert seq1 != null && seq2 != null; // because sameLength() = true 9585 for (int i = 0 ; i < seq1.length ; i++) { 9586 if (lt(seq1[i], seq2[i])) { 9587 return false; 9588 } 9589 } 9590 return true; 9591 } 9592 9593 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9594 @Pure 9595 public static boolean pairwiseGTE(long @Nullable [] seq1, int @Nullable [] seq2) { 9596 if (!sameLength(seq1, seq2)) { 9597 return false; 9598 } 9599 assert seq1 != null && seq2 != null; // because sameLength() = true 9600 for (int i = 0 ; i < seq1.length ; i++) { 9601 if (lt(seq1[i], seq2[i])) { 9602 return false; 9603 } 9604 } 9605 return true; 9606 } 9607 9608 /** 9609 * Returns true iff seq1 is lexically equal to seq2. 9610 * For equality, "lexically" and "pairwise" are the same. 9611 */ 9612 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9613 @Pure 9614 public static boolean lexEqual(long @Nullable [] seq1, long @Nullable [] seq2) { 9615 if (seq1 == null) { 9616 return false; 9617 } 9618 if (seq2 == null) { 9619 return false; 9620 } 9621 return pairwiseEqual(seq1, seq2); 9622 } 9623 9624 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9625 @Pure 9626 public static boolean lexEqual(long @Nullable [] seq1, int @Nullable [] seq2) { 9627 if (seq1 == null) { 9628 return false; 9629 } 9630 if (seq2 == null) { 9631 return false; 9632 } 9633 return pairwiseEqual(seq1, seq2); 9634 } 9635 9636 /** Returns true iff seq1 is lexically not equal to seq2. */ 9637 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9638 @Pure 9639 public static boolean lexNotEqual(long @Nullable [] seq1, long @Nullable [] seq2) { 9640 if (seq1 == null) { 9641 return false; 9642 } 9643 if (seq2 == null) { 9644 return false; 9645 } 9646 return !lexEqual(seq1, seq2); 9647 } 9648 9649 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9650 @Pure 9651 public static boolean lexNotEqual(long @Nullable [] seq1, int @Nullable [] seq2) { 9652 if (seq1 == null) { 9653 return false; 9654 } 9655 if (seq2 == null) { 9656 return false; 9657 } 9658 return !lexEqual(seq1, seq2); 9659 } 9660 9661 /** Returns true iff seq1 is lexically < seq2. */ 9662 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9663 @Pure 9664 public static boolean lexLT(long @Nullable [] seq1, long @Nullable [] seq2) { 9665 if (seq1 == null) { 9666 return false; 9667 } 9668 if (seq2 == null) { 9669 return false; 9670 } 9671 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9672 for (int i = 0 ; i < minlength ; i++) { 9673 if (gt(seq1[i], seq2[i])) { 9674 return false; 9675 } else if (lt(seq1[i], seq2[i])) { 9676 return true; 9677 } 9678 } 9679 if (seq1.length >= seq2.length) { 9680 return false; 9681 } 9682 return true; 9683 } 9684 9685 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9686 @Pure 9687 public static boolean lexLT(long @Nullable [] seq1, int @Nullable [] seq2) { 9688 if (seq1 == null) { 9689 return false; 9690 } 9691 if (seq2 == null) { 9692 return false; 9693 } 9694 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9695 for (int i = 0 ; i < minlength ; i++) { 9696 if (gt(seq1[i], seq2[i])) { 9697 return false; 9698 } else if (lt(seq1[i], seq2[i])) { 9699 return true; 9700 } 9701 } 9702 if (seq1.length >= seq2.length) { 9703 return false; 9704 } 9705 return true; 9706 } 9707 9708 /** Returns true iff seq1 is lexically ≤ to seq2. */ 9709 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9710 @Pure 9711 public static boolean lexLTE(long @Nullable [] seq1, long @Nullable [] seq2) { 9712 if (seq1 == null) { 9713 return false; 9714 } 9715 if (seq2 == null) { 9716 return false; 9717 } 9718 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9719 for (int i = 0 ; i < minlength ; i++) { 9720 if (gt(seq1[i], seq2[i])) { 9721 return false; 9722 } else if (lt(seq1[i], seq2[i])) { 9723 return true; 9724 } 9725 } 9726 if (seq1.length > seq2.length) { 9727 return false; 9728 } 9729 return true; 9730 } 9731 9732 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9733 @Pure 9734 public static boolean lexLTE(long @Nullable [] seq1, int @Nullable [] seq2) { 9735 if (seq1 == null) { 9736 return false; 9737 } 9738 if (seq2 == null) { 9739 return false; 9740 } 9741 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9742 for (int i = 0 ; i < minlength ; i++) { 9743 if (gt(seq1[i], seq2[i])) { 9744 return false; 9745 } else if (lt(seq1[i], seq2[i])) { 9746 return true; 9747 } 9748 } 9749 if (seq1.length > seq2.length) { 9750 return false; 9751 } 9752 return true; 9753 } 9754 9755 /** Returns true iff seq1 is lexically > to seq2. */ 9756 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9757 @Pure 9758 public static boolean lexGT(long @Nullable [] seq1, long @Nullable [] seq2) { 9759 if (seq1 == null) { 9760 return false; 9761 } 9762 if (seq2 == null) { 9763 return false; 9764 } 9765 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9766 for (int i = 0 ; i < minlength ; i++) { 9767 if (lt(seq1[i], seq2[i])) { 9768 return false; 9769 } else if (gt(seq1[i], seq2[i])) { 9770 return true; 9771 } 9772 } 9773 if (seq1.length <= seq2.length) { 9774 return false; 9775 } 9776 return true; 9777 } 9778 9779 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9780 @Pure 9781 public static boolean lexGT(long @Nullable [] seq1, int @Nullable [] seq2) { 9782 if (seq1 == null) { 9783 return false; 9784 } 9785 if (seq2 == null) { 9786 return false; 9787 } 9788 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9789 for (int i = 0 ; i < minlength ; i++) { 9790 if (lt(seq1[i], seq2[i])) { 9791 return false; 9792 } else if (gt(seq1[i], seq2[i])) { 9793 return true; 9794 } 9795 } 9796 if (seq1.length <= seq2.length) { 9797 return false; 9798 } 9799 return true; 9800 } 9801 9802 /** Returns true iff seq1 is lexically ≥ to seq2. */ 9803 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9804 @Pure 9805 public static boolean lexGTE(long @Nullable [] seq1, long @Nullable [] seq2) { 9806 if (seq1 == null) { 9807 return false; 9808 } 9809 if (seq2 == null) { 9810 return false; 9811 } 9812 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9813 for (int i = 0 ; i < minlength ; i++) { 9814 if (lt(seq1[i], seq2[i])) { 9815 return false; 9816 } else if (gt(seq1[i], seq2[i])) { 9817 return true; 9818 } 9819 } 9820 if (seq1.length < seq2.length) { 9821 return false; 9822 } 9823 return true; 9824 } 9825 9826 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 9827 @Pure 9828 public static boolean lexGTE(long @Nullable [] seq1, int @Nullable [] seq2) { 9829 if (seq1 == null) { 9830 return false; 9831 } 9832 if (seq2 == null) { 9833 return false; 9834 } 9835 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 9836 for (int i = 0 ; i < minlength ; i++) { 9837 if (lt(seq1[i], seq2[i])) { 9838 return false; 9839 } else if (gt(seq1[i], seq2[i])) { 9840 return true; 9841 } 9842 } 9843 if (seq1.length < seq2.length) { 9844 return false; 9845 } 9846 return true; 9847 } 9848 9849 /** True iff for all applicable i, every seq[i] == seq[i+1]. 9850 * 9851 * Meaning (in pseudo-FOL): 9852 * 9853 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 9854 * 9855 */ 9856 @EnsuresNonNullIf(result=true, expression="#1") 9857 @Pure 9858 public static boolean eltwiseEqual(long @Nullable [] seq) { 9859 if (seq == null) { 9860 return false; 9861 } 9862 for (int i = 0 ; i < seq.length ; i++) { 9863 if (i < seq.length - 1) { 9864 if (ne(seq[i], seq[i + 1])) { 9865 return false; 9866 } 9867 } 9868 } 9869 return true; 9870 } 9871 9872 /** True iff for all applicable i, every seq[i] != seq[i+1]. 9873 * 9874 * Meaning (in pseudo-FOL): 9875 * 9876 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 9877 * 9878 */ 9879 @EnsuresNonNullIf(result=true, expression="#1") 9880 @Pure 9881 public static boolean eltwiseNotEqual(long @Nullable [] seq) { 9882 if (seq == null) { 9883 return false; 9884 } 9885 for (int i = 0 ; i < seq.length ; i++) { 9886 if (i < seq.length - 1) { 9887 if (eq(seq[i], seq[i + 1])) { 9888 return false; 9889 } 9890 } 9891 } 9892 return true; 9893 } 9894 9895 /** True iff for all applicable i, every seq[i] < seq[i+1]. 9896 * 9897 * Meaning (in pseudo-FOL): 9898 * 9899 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 9900 * 9901 */ 9902 @EnsuresNonNullIf(result=true, expression="#1") 9903 @Pure 9904 public static boolean eltwiseLT(long @Nullable [] seq) { 9905 if (seq == null) { 9906 return false; 9907 } 9908 for (int i = 0 ; i < seq.length ; i++) { 9909 if (i < seq.length - 1) { 9910 if (gte(seq[i], seq[i + 1])) { 9911 return false; 9912 } 9913 } 9914 } 9915 return true; 9916 } 9917 9918 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 9919 * 9920 * Meaning (in pseudo-FOL): 9921 * 9922 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 9923 * 9924 */ 9925 @EnsuresNonNullIf(result=true, expression="#1") 9926 @Pure 9927 public static boolean eltwiseLTE(long @Nullable [] seq) { 9928 if (seq == null) { 9929 return false; 9930 } 9931 for (int i = 0 ; i < seq.length ; i++) { 9932 if (i < seq.length - 1) { 9933 if (gt(seq[i], seq[i + 1])) { 9934 return false; 9935 } 9936 } 9937 } 9938 return true; 9939 } 9940 9941 /** True iff for all applicable i, every seq[i] > seq[i+1]. 9942 * 9943 * Meaning (in pseudo-FOL): 9944 * 9945 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 9946 * 9947 */ 9948 @EnsuresNonNullIf(result=true, expression="#1") 9949 @Pure 9950 public static boolean eltwiseGT(long @Nullable [] seq) { 9951 if (seq == null) { 9952 return false; 9953 } 9954 for (int i = 0 ; i < seq.length ; i++) { 9955 if (i < seq.length - 1) { 9956 if (lte(seq[i], seq[i + 1])) { 9957 return false; 9958 } 9959 } 9960 } 9961 return true; 9962 } 9963 9964 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 9965 * 9966 * Meaning (in pseudo-FOL): 9967 * 9968 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 9969 * 9970 */ 9971 @EnsuresNonNullIf(result=true, expression="#1") 9972 @Pure 9973 public static boolean eltwiseGTE(long @Nullable [] seq) { 9974 if (seq == null) { 9975 return false; 9976 } 9977 for (int i = 0 ; i < seq.length ; i++) { 9978 if (i < seq.length - 1) { 9979 if (lt(seq[i], seq[i + 1])) { 9980 return false; 9981 } 9982 } 9983 } 9984 return true; 9985 } 9986 9987 /** True iff for all applicable i, every seq[i] == i. 9988 * 9989 * Meaning (in pseudo-FOL): 9990 * 9991 * forall i in { 0..seq.length-1 } : seq[i] == i 9992 * 9993 */ 9994 @EnsuresNonNullIf(result=true, expression="#1") 9995 @Pure 9996 public static boolean eltsEqualIndex(long @Nullable [] seq) { 9997 if (seq == null) { 9998 return false; 9999 } 10000 for (int i = 0 ; i < seq.length ; i++) { 10001 if (ne(seq[i], i)) { 10002 return false; 10003 } 10004 } 10005 return true; 10006 } 10007 10008 /** True iff for all applicable i, every seq[i] != i. 10009 * 10010 * Meaning (in pseudo-FOL): 10011 * 10012 * forall i in { 0..seq.length-1 } : seq[i] != i 10013 * 10014 */ 10015 @EnsuresNonNullIf(result=true, expression="#1") 10016 @Pure 10017 public static boolean eltsNotEqualIndex(long @Nullable [] seq) { 10018 if (seq == null) { 10019 return false; 10020 } 10021 for (int i = 0 ; i < seq.length ; i++) { 10022 if (eq(seq[i], i)) { 10023 return false; 10024 } 10025 } 10026 return true; 10027 } 10028 10029 /** True iff for all applicable i, every seq[i] < i. 10030 * 10031 * Meaning (in pseudo-FOL): 10032 * 10033 * forall i in { 0..seq.length-1 } : seq[i] < i 10034 * 10035 */ 10036 @EnsuresNonNullIf(result=true, expression="#1") 10037 @Pure 10038 public static boolean eltsLtIndex(long @Nullable [] seq) { 10039 if (seq == null) { 10040 return false; 10041 } 10042 for (int i = 0 ; i < seq.length ; i++) { 10043 if (gte(seq[i], i)) { 10044 return false; 10045 } 10046 } 10047 return true; 10048 } 10049 10050 /** True iff for all applicable i, every seq[i] ≤ i. 10051 * 10052 * Meaning (in pseudo-FOL): 10053 * 10054 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 10055 * 10056 */ 10057 @EnsuresNonNullIf(result=true, expression="#1") 10058 @Pure 10059 public static boolean eltsLteIndex(long @Nullable [] seq) { 10060 if (seq == null) { 10061 return false; 10062 } 10063 for (int i = 0 ; i < seq.length ; i++) { 10064 if (gt(seq[i], i)) { 10065 return false; 10066 } 10067 } 10068 return true; 10069 } 10070 10071 /** True iff for all applicable i, every seq[i] > i. 10072 * 10073 * Meaning (in pseudo-FOL): 10074 * 10075 * forall i in { 0..seq.length-1 } : seq[i] > i 10076 * 10077 */ 10078 @EnsuresNonNullIf(result=true, expression="#1") 10079 @Pure 10080 public static boolean eltsGtIndex(long @Nullable [] seq) { 10081 if (seq == null) { 10082 return false; 10083 } 10084 for (int i = 0 ; i < seq.length ; i++) { 10085 if (lte(seq[i], i)) { 10086 return false; 10087 } 10088 } 10089 return true; 10090 } 10091 10092 /** True iff for all applicable i, every seq[i] ≥ i. 10093 * 10094 * Meaning (in pseudo-FOL): 10095 * 10096 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 10097 * 10098 */ 10099 @EnsuresNonNullIf(result=true, expression="#1") 10100 @Pure 10101 public static boolean eltsGteIndex(long @Nullable [] seq) { 10102 if (seq == null) { 10103 return false; 10104 } 10105 for (int i = 0 ; i < seq.length ; i++) { 10106 if (lt(seq[i], i)) { 10107 return false; 10108 } 10109 } 10110 return true; 10111 } 10112 10113 /// Deferencing (accessing) fields 10114 10115 /** 10116 * collectlong accepts an object and a list of fields (one of which is of array type, and the 10117 * rest of which are not), and produces an array in which the original object has had the given 10118 * fields accessed. 10119 * 10120 * <p>Daikon creates invariants over "variables" such as the following. 10121 * 10122 * <dl> 10123 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 10124 * for all y's in array x.arr.</dd> 10125 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 10126 * for all x's in array arr.</dd> 10127 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 10128 * </dl> 10129 * 10130 * <p>The collectlong() method does this collecting work. 10131 * 10132 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 10133 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 10134 * elements that result from following the fields, one of which is assumed to be an array. 10135 * 10136 * <p> 10137 * requires: fieldStr.length() > 0 and object != null 10138 * <p> 10139 * requires: fieldStr contains only field names, no "[]" strings. 10140 * <p> 10141 * requires: the method only works for field sequences with exactly one field representing an 10142 * array. For example, the collection a[].b[].c will fail. 10143 * 10144 * @return if the resulting collection is of non-primitive type, then returns an array of type 10145 * Object[]. Returns null if any array or field access causes an exception. 10146 */ 10147 10148 @SideEffectFree 10149 public static long @Nullable [] collectlong(@Nullable Object object, @Nullable String fieldStr) { 10150 10151 if (object == null) { 10152 return null; 10153 } 10154 if (fieldStr == null) { 10155 return null; 10156 } 10157 10158 // assert fieldStr != null && !"".equals(fieldStr); 10159 String[] fieldNames = fieldStr.split("\\."); 10160 long[] retval = collectlong(object, fieldNames, 0); 10161 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 10162 return retval; 10163 } 10164 10165 /** Helper method for collectlong(Object, String). 10166 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 10167 * @see collectlong(Object, String) 10168 */ 10169 // @PolyNull does not work for return type, because null is returned on error. 10170 @SideEffectFree 10171 private static long @Nullable [] collectlong(@Nullable Object object, 10172 String[] fields, int fieldsStartIdx) { 10173 10174 if (object == null) { 10175 return null; 10176 } 10177 assert (fields != null); 10178 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 10179 10180 Object fieldObj; 10181 try { 10182 Field field = (object instanceof java.lang.Class<?>) 10183 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 10184 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 10185 field.setAccessible(true); 10186 // Class cls = field.getType(); 10187 fieldObj = field.get(object); 10188 // System.out.println("***fieldObj="+fieldObj); 10189 10190 } catch (Exception e) { 10191 return null; 10192 10193 } 10194 10195 if (fieldObj == null) { 10196 return null; 10197 } 10198 10199 // base case: just accessed the last field 10200 if (fields.length - 1 == fieldsStartIdx) { 10201 10202 if (fieldObj.getClass().isArray()) { 10203 // last field is an array 10204 return (long[])fieldObj; 10205 } else { 10206 // This hack should be removed in favor of, at "oneEltArray = ..." 10207 // below, calling a version of collectlong_field that throws an 10208 // error. Then, this case becomes a run-time error. -MDE 10209 10210 // Just one element; return a one-element array. 10211 // assert cls.equals(Long.TYPE); 10212 return new long[] { ((Long)fieldObj).longValue() }; 10213 } 10214 } else { 10215 // recursive case: more fields to access after this one 10216 10217 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 10218 10219 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 10220 long[] intermediate = new long[collection.size()]; 10221 int index = 0; 10222 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 10223 Object obj = i.next(); 10224 long[] oneEltArray = collectlong(obj, fields, fieldsStartIdx + 1); 10225 if (oneEltArray == null) { 10226 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 10227 } 10228 // assert oneEltArray.length == 1; 10229 intermediate[index++] = oneEltArray[0]; 10230 } 10231 return intermediate; 10232 } else if (fieldObj.getClass().isArray()) { 10233 10234 // collect elements across array 10235 long[] intermediate = new long[Array.getLength(fieldObj)]; 10236 for (int i = 0 ; i < intermediate.length ; i++) { 10237 Object obj = Array.get(fieldObj, i); 10238 long[] oneEltArray = collectlong(obj, fields, fieldsStartIdx + 1); 10239 if (oneEltArray == null) { 10240 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 10241 } 10242 // assert oneEltArray.length == 1; 10243 intermediate[i] = oneEltArray[0]; 10244 } 10245 return intermediate; 10246 } else { 10247 10248 return collectlong(fieldObj, fields, fieldsStartIdx + 1); 10249 } 10250 } 10251 } 10252 10253 /** 10254 * Returns the results of dereferencing the fields for 'object'. For example, the call 10255 * 10256 * <pre>collectlong_field(x, "f.g.h")</pre> 10257 * 10258 * has the same value as 10259 * 10260 * <pre>x.f.g.h</pre>. 10261 * Returns a default value if any field access causes an exception. 10262 */ 10263 @SideEffectFree 10264 public static long collectlong_field(Object object, String fieldStr) { 10265 10266 if (object == null) { 10267 return Long.MAX_VALUE; // return default value 10268 } 10269 if (fieldStr == null) { 10270 return Long.MAX_VALUE; // return default value 10271 } 10272 10273 String[] fieldNames = fieldStr.split("\\."); 10274 10275 // Holds the intermediate (and final) result 10276 Object fieldObj = object; 10277 10278 for (int i = 0 ; i < fieldNames.length ; i++) { 10279 10280 String fieldName = fieldNames[i]; 10281 10282 try { 10283 Field field = 10284 (fieldObj instanceof java.lang.Class<?>) 10285 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 10286 : fieldObj.getClass().getDeclaredField(fieldName); 10287 field.setAccessible(true); 10288 fieldObj = field.get(fieldObj); 10289 10290 if (fieldObj == null) { 10291 return Long.MAX_VALUE; // return default value 10292 } 10293 10294 } catch (Exception e) { 10295 return Long.MAX_VALUE; // return default value 10296 10297 } 10298 10299 } 10300 10301 return ((Long)fieldObj).longValue(); 10302 } 10303 10304 /////////////////////////////////////////////////////////////////////////// 10305 /// Methods for "short" (from QuantBody.java.jpp) 10306 /// 10307 10308 /** 10309 * Returns the ith element of the array or collection argument. If the argument is null or not an 10310 * array or collection, returns a default value (Short.MAX_VALUE). 10311 */ 10312 10313 @Pure 10314 public static short getElement_short(Object o, long i) { 10315 if (o == null) { 10316 return Short.MAX_VALUE; // return default value 10317 } 10318 java.lang.Class<?> c = o.getClass(); 10319 if (c.isArray()) { 10320 return java.lang.reflect.Array.getShort(o, (int)i); 10321 } else if (o instanceof java.util.AbstractCollection<?>) { 10322 return java.lang.reflect.Array.getShort(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 10323 } else { 10324 return Short.MAX_VALUE; // return default value 10325 } 10326 } 10327 10328 @Pure 10329 public static short getElement_short(short[] arr, long i) { 10330 if (arr == null) { 10331 return Short.MAX_VALUE; // return default value 10332 } 10333 return arr[(int)i]; 10334 } 10335 10336 private static boolean eq(short x, short y) { 10337 return x == y; 10338 } 10339 10340 private static boolean ne(short x, short y) { 10341 return x != y; 10342 } 10343 10344 private static boolean lt(short x, short y) { 10345 return x < y; 10346 } 10347 10348 private static boolean lte(short x, short y) { 10349 return x <= y; 10350 } 10351 10352 private static boolean gt(short x, short y) { 10353 return x > y; 10354 } 10355 10356 private static boolean gte(short x, short y) { 10357 return x >= y; 10358 } 10359 10360 /** True iff both sequences are non-null and have the same length. */ 10361 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 10362 @Pure 10363 public static boolean sameLength(short @Nullable [] seq1, short @Nullable [] seq2) { 10364 return ((seq1 != null) 10365 && (seq2 != null) 10366 && seq1.length == seq2.length); 10367 } 10368 10369 /** 10370 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 10371 * 10372 * <p>If either array is null, returns null. If either array is empty, returns only those 10373 * elements in the other array. If both arrays are empty, returns a new empty array. 10374 */ 10375 @SideEffectFree 10376 public static short @PolyNull [] concat(short @PolyNull [] seq1, short @PolyNull [] seq2) { 10377 if (seq1 == null) { 10378 return null; 10379 } 10380 if (seq2 == null) { 10381 return null; 10382 } 10383 return ArraysPlume.concat(seq1, seq2); 10384 } 10385 10386 /** 10387 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 10388 * assurances about the order or repetition of elements: elements may be repeated, and their 10389 * order may be different from the order of elements in seq1 and seq2. 10390 */ 10391 @SideEffectFree 10392 public static short @PolyNull [] union(short @PolyNull [] seq1, short @PolyNull [] seq2) { 10393 if (seq1 == null) { 10394 return null; 10395 } 10396 if (seq2 == null) { 10397 return null; 10398 } 10399 return concat(seq1, seq2); 10400 } 10401 10402 /** 10403 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 10404 * gives no assurances about the order or repetition of elements: elements may be repeated, and 10405 * their order may be different from the order of elements in seq1 and seq2. 10406 */ 10407 @Pure 10408 public static short @PolyNull [] intersection(short @PolyNull [] seq1, short @PolyNull [] seq2) { 10409 if (seq1 == null) { 10410 return null; 10411 } 10412 if (seq2 == null) { 10413 return null; 10414 } 10415 short[] intermediate = new short[Math.min(seq1.length, seq2.length)]; 10416 int length = 0; 10417 for (int i = 0 ; i < seq1.length ; i++) { 10418 if (memberOf(seq1[i], seq2) ) { 10419 intermediate[length++] = seq1[i]; 10420 } 10421 } 10422 return ArraysPlume.subarray(intermediate, 0, length); 10423 } 10424 10425 /** 10426 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 10427 * no assurances about the order or repetition of elements: elements may be repeated, and their 10428 * order may be different from the order of elements in seq1 and seq2. 10429 */ 10430 @Pure 10431 public static short @PolyNull [] setDiff(short @PolyNull [] seq1, short @PolyNull [] seq2) { 10432 if (seq1 == null) { 10433 return null; 10434 } 10435 if (seq2 == null) { 10436 return null; 10437 } 10438 short[] intermediate = new short[seq1.length]; 10439 int length = 0; 10440 for (int i = 0 ; i < seq1.length ; i++) { 10441 if (!memberOf(seq1[i], seq2)) { 10442 intermediate[length++] = seq1[i]; 10443 } 10444 } 10445 return ArraysPlume.subarray(intermediate, 0, length); 10446 } 10447 10448 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 10449 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10450 @Pure 10451 public static boolean setEqual(short @Nullable [] seq1, short @Nullable [] seq2) { 10452 if (seq1 == null) { 10453 return false; 10454 } 10455 if (seq2 == null) { 10456 return false; 10457 } 10458 for (int i = 0; i < seq1.length ; i++) { 10459 if (!memberOf(seq1[i], seq2) ) { 10460 return false; 10461 } 10462 } 10463 for (int i = 0; i < seq2.length ; i++) { 10464 if (!memberOf(seq2[i], seq1) ) { 10465 return false; 10466 } 10467 } 10468 return true; 10469 } 10470 10471 /** True iff seq1 is the reverse of seq2. 10472 * 10473 * Meaning (in pseudo-FOL): 10474 * 10475 * <pre> 10476 * /\ seq1.length == seq2.length 10477 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 10478 * </pre> 10479 * 10480 */ 10481 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10482 @Pure 10483 public static boolean isReverse(short[] seq1, short[] seq2) { 10484 if (!sameLength(seq1, seq2)) { 10485 return false; 10486 } 10487 assert seq1 != null && seq2 != null; // because sameLength() = true 10488 int length = seq1.length; 10489 for (int i = 0 ; i < length ; i++) { 10490 if (ne(seq1[i], seq2[length - i - 1])) { 10491 return false; 10492 } 10493 } 10494 return true; 10495 } 10496 10497 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 10498 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10499 @Pure 10500 public static boolean subsetOf(short @Nullable [] seq1, short @Nullable [] seq2) { 10501 if (seq1 == null) { 10502 return false; 10503 } 10504 if (seq2 == null) { 10505 return false; 10506 } 10507 for (int i = 0 ; i < seq1.length ; i++) { 10508 if (!memberOf(seq1[i], seq2)) { 10509 return false; 10510 } 10511 } 10512 return true; 10513 } 10514 10515 /** Returns true iff seq contains no duplicate elements. */ 10516 @EnsuresNonNullIf(result=true, expression="#1") 10517 @Pure 10518 public static boolean noDups(short @Nullable [] seq) { 10519 if (seq == null) { 10520 return false; 10521 } 10522 return ArraysPlume.noDuplicates(seq); 10523 } 10524 10525 /** Returns true iff elt is in array arr. */ 10526 @EnsuresNonNullIf(result=true, expression="#2") 10527 @Pure 10528 public static boolean memberOf(short elt, short @Nullable [] arr) { 10529 if (arr == null) { 10530 return false; 10531 } 10532 for (int i = 0 ; i < arr.length ; i++) { 10533 if (eq(arr[i], elt)) { 10534 return true; 10535 } 10536 } 10537 return false; 10538 } 10539 10540 @EnsuresNonNullIf(result=true, expression="#2") 10541 @Pure 10542 public static boolean memberOf(long elt, short @Nullable [] arr) { 10543 if (arr == null) { 10544 return false; 10545 } 10546 for (int i = 0 ; i < arr.length ; i++) { 10547 if (eq(arr[i], elt)) { 10548 return true; 10549 } 10550 } 10551 return false; 10552 } 10553 10554 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 10555 @Pure 10556 public static short @PolyNull [] slice(short @PolyNull [] seq, int start, int end) { 10557 if (seq == null) { 10558 return null; 10559 } 10560 int sliceStart = start; 10561 int sliceEnd = end; 10562 if (start < 0) { 10563 return new short[] { }; 10564 } 10565 if (end > seq.length - 1) { 10566 return new short[] { }; 10567 } 10568 if (sliceStart > sliceEnd) { 10569 return new short[] { }; 10570 } 10571 int length = sliceEnd - sliceStart + 1; 10572 return ArraysPlume.subarray(seq, sliceStart, length); 10573 } 10574 10575 @Pure 10576 public static short @PolyNull [] slice(short @PolyNull [] seq, long start, int end) { 10577 return slice(seq, (int)start, end); 10578 } 10579 @Pure 10580 public static short @PolyNull [] slice(short @PolyNull [] seq, int start, long end) { 10581 return slice(seq, start, (int)end); 10582 } 10583 @Pure 10584 public static short @PolyNull [] slice(short @PolyNull [] seq, long start, long end) { 10585 return slice(seq, (int)start, (int)end); 10586 } 10587 10588 /** True iff all elements in arr equal elt. 10589 * 10590 * Meaning (in pseudo-FOL): 10591 * 10592 * forall i in { 0..arr.length-1 } : arr[i] == elt 10593 * 10594 */ 10595 @EnsuresNonNullIf(result=true, expression="#1") 10596 @Pure 10597 public static boolean eltsEqual(short @Nullable [] arr, short elt) { 10598 if (arr == null) { 10599 return false; 10600 } 10601 for (int i = 0 ; i < arr.length ; i++) { 10602 if (ne(arr[i], elt)) { 10603 return false; 10604 } 10605 } 10606 return true; 10607 } 10608 10609 /** True iff every element in arr does not equal elt. 10610 * 10611 * Meaning (in pseudo-FOL): 10612 * 10613 * forall i in { 0..arr.length-1 } : arr[i] != elt 10614 * 10615 */ 10616 @EnsuresNonNullIf(result=true, expression="#1") 10617 @Pure 10618 public static boolean eltsNotEqual(short @Nullable [] arr, short elt) { 10619 if (arr == null) { 10620 return false; 10621 } 10622 for (int i = 0 ; i < arr.length ; i++) { 10623 if (eq(arr[i], elt)) { 10624 return false; 10625 } 10626 } 10627 return true; 10628 } 10629 10630 /** True iff every element in arr is greater than elt. 10631 * 10632 * Meaning (in pseudo-FOL): 10633 * 10634 * forall i in { 0..arr.length-1 } : arr[i] > elt 10635 * 10636 */ 10637 @EnsuresNonNullIf(result=true, expression="#1") 10638 @Pure 10639 public static boolean eltsGT(short @Nullable [] arr, short elt) { 10640 if (arr == null) { 10641 return false; 10642 } 10643 for (int i = 0 ; i < arr.length ; i++) { 10644 if (lte(arr[i], elt)) { 10645 return false; 10646 } 10647 } 10648 return true; 10649 } 10650 10651 /** True iff every element in arr is greater than or equal to elt. 10652 * 10653 * Meaning (in pseudo-FOL): 10654 * 10655 * forall i in { 0..arr.length-1 } : arr[i] ≥ elt 10656 * 10657 */ 10658 @EnsuresNonNullIf(result=true, expression="#1") 10659 @Pure 10660 public static boolean eltsGTE(short @Nullable [] arr, short elt) { 10661 if (arr == null) { 10662 return false; 10663 } 10664 for (int i = 0 ; i < arr.length ; i++) { 10665 if (lt(arr[i], elt)) { 10666 return false; 10667 } 10668 } 10669 return true; 10670 } 10671 10672 /** True iff every element in arr is less than elt. 10673 * 10674 * Meaning (in pseudo-FOL): 10675 * 10676 * forall i in { 0..arr.length-1 } : arr[i] < elt 10677 * 10678 */ 10679 @EnsuresNonNullIf(result=true, expression="#1") 10680 @Pure 10681 public static boolean eltsLT(short @Nullable [] arr, short elt) { 10682 if (arr == null) { 10683 return false; 10684 } 10685 for (int i = 0 ; i < arr.length ; i++) { 10686 if (gte(arr[i], elt)) { 10687 return false; 10688 } 10689 } 10690 return true; 10691 } 10692 10693 /** True iff every element in arr is less than or equal to elt. 10694 * 10695 * Meaning (in pseudo-FOL): 10696 * 10697 * forall i in { 0..arr.length-1 } : arr[i] ≤ elt 10698 * 10699 */ 10700 @EnsuresNonNullIf(result=true, expression="#1") 10701 @Pure 10702 public static boolean eltsLTE(short @Nullable [] arr, short elt) { 10703 if (arr == null) { 10704 return false; 10705 } 10706 for (int i = 0 ; i < arr.length ; i++) { 10707 if (gt(arr[i], elt)) { 10708 return false; 10709 } 10710 } 10711 return true; 10712 } 10713 10714 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 10715 * 10716 * Meaning (in pseudo-FOL): 10717 * 10718 * /\ seq1.length == se2.length 10719 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 10720 * 10721 */ 10722 10723 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10724 @Pure 10725 public static boolean pairwiseEqual(short @Nullable [] seq1, short @Nullable [] seq2) { 10726 if (!sameLength(seq1, seq2)) { 10727 return false; 10728 } 10729 assert seq1 != null && seq2 != null; // because sameLength() = true 10730 for (int i = 0 ; i < seq1.length ; i++) { 10731 if (ne(seq1[i], seq2[i])) { 10732 return false; 10733 } 10734 } 10735 return true; 10736 } 10737 10738 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 10739 * 10740 * Meaning (in pseudo-FOL): 10741 * 10742 * /\ seq1.length == se2.length 10743 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 10744 * 10745 */ 10746 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10747 @Pure 10748 public static boolean pairwiseNotEqual(short @Nullable [] seq1, short @Nullable [] seq2) { 10749 if (!sameLength(seq1, seq2)) { 10750 return false; 10751 } 10752 assert seq1 != null && seq2 != null; // because sameLength() = true 10753 for (int i = 0 ; i < seq1.length ; i++) { 10754 if (eq(seq1[i], seq2[i])) { 10755 return false; 10756 } 10757 } 10758 return true; 10759 } 10760 10761 /** True iff seq1 and seq2 have the same length, and every seq1[i] < seq2[i]. 10762 * 10763 * Meaning (in pseudo-FOL): 10764 * 10765 * /\ seq1.length == se2.length 10766 * /\ forall i in { 0..seq1.length-1 } : seq1[i] < seq2[i] 10767 * 10768 */ 10769 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10770 @Pure 10771 public static boolean pairwiseLT(short @Nullable [] seq1, short @Nullable [] seq2) { 10772 if (!sameLength(seq1, seq2)) { 10773 return false; 10774 } 10775 assert seq1 != null && seq2 != null; // because sameLength() = true 10776 for (int i = 0 ; i < seq1.length ; i++) { 10777 if (gte(seq1[i], seq2[i])) { 10778 return false; 10779 } 10780 } 10781 return true; 10782 } 10783 10784 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≤ seq2[i]. 10785 * Meaning (in pseudo-FOL): 10786 * 10787 * /\ seq1.length == se2.length 10788 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≤ seq2[i] 10789 * 10790 */ 10791 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10792 @Pure 10793 public static boolean pairwiseLTE(short @Nullable [] seq1, short @Nullable [] seq2) { 10794 if (!sameLength(seq1, seq2)) { 10795 return false; 10796 } 10797 assert seq1 != null && seq2 != null; // because sameLength() = true 10798 for (int i = 0 ; i < seq1.length ; i++) { 10799 if (gt(seq1[i], seq2[i])) { 10800 return false; 10801 } 10802 } 10803 return true; 10804 } 10805 10806 /** True iff seq1 and seq2 have the same length, and every seq1[i] > seq2[i]. 10807 * Meaning (in pseudo-FOL): 10808 * 10809 * /\ seq1.length == se2.length 10810 * /\ forall i in { 0..seq1.length-1 } : seq1[i] > seq2[i] 10811 * 10812 */ 10813 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10814 @Pure 10815 public static boolean pairwiseGT(short @Nullable [] seq1, short @Nullable [] seq2) { 10816 if (!sameLength(seq1, seq2)) { 10817 return false; 10818 } 10819 assert seq1 != null && seq2 != null; // because sameLength() = true 10820 for (int i = 0 ; i < seq1.length ; i++) { 10821 if (lte(seq1[i], seq2[i])) { 10822 return false; 10823 } 10824 } 10825 return true; 10826 } 10827 10828 /** True iff seq1 and seq2 have the same length, and every seq1[i] ≥ seq2[i]. 10829 * Meaning (in pseudo-FOL): 10830 * 10831 * /\ seq1.length == se2.length 10832 * /\ forall i in { 0..seq1.length-1 } : seq1[i] ≥ seq2[i] 10833 * 10834 */ 10835 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10836 @Pure 10837 public static boolean pairwiseGTE(short @Nullable [] seq1, short @Nullable [] seq2) { 10838 if (!sameLength(seq1, seq2)) { 10839 return false; 10840 } 10841 assert seq1 != null && seq2 != null; // because sameLength() = true 10842 for (int i = 0 ; i < seq1.length ; i++) { 10843 if (lt(seq1[i], seq2[i])) { 10844 return false; 10845 } 10846 } 10847 return true; 10848 } 10849 10850 /** 10851 * Returns true iff seq1 is lexically equal to seq2. 10852 * For equality, "lexically" and "pairwise" are the same. 10853 */ 10854 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10855 @Pure 10856 public static boolean lexEqual(short @Nullable [] seq1, short @Nullable [] seq2) { 10857 if (seq1 == null) { 10858 return false; 10859 } 10860 if (seq2 == null) { 10861 return false; 10862 } 10863 return pairwiseEqual(seq1, seq2); 10864 } 10865 10866 /** Returns true iff seq1 is lexically not equal to seq2. */ 10867 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10868 @Pure 10869 public static boolean lexNotEqual(short @Nullable [] seq1, short @Nullable [] seq2) { 10870 if (seq1 == null) { 10871 return false; 10872 } 10873 if (seq2 == null) { 10874 return false; 10875 } 10876 return !lexEqual(seq1, seq2); 10877 } 10878 10879 /** Returns true iff seq1 is lexically < seq2. */ 10880 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10881 @Pure 10882 public static boolean lexLT(short @Nullable [] seq1, short @Nullable [] seq2) { 10883 if (seq1 == null) { 10884 return false; 10885 } 10886 if (seq2 == null) { 10887 return false; 10888 } 10889 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 10890 for (int i = 0 ; i < minlength ; i++) { 10891 if (gt(seq1[i], seq2[i])) { 10892 return false; 10893 } else if (lt(seq1[i], seq2[i])) { 10894 return true; 10895 } 10896 } 10897 if (seq1.length >= seq2.length) { 10898 return false; 10899 } 10900 return true; 10901 } 10902 10903 /** Returns true iff seq1 is lexically ≤ to seq2. */ 10904 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10905 @Pure 10906 public static boolean lexLTE(short @Nullable [] seq1, short @Nullable [] seq2) { 10907 if (seq1 == null) { 10908 return false; 10909 } 10910 if (seq2 == null) { 10911 return false; 10912 } 10913 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 10914 for (int i = 0 ; i < minlength ; i++) { 10915 if (gt(seq1[i], seq2[i])) { 10916 return false; 10917 } else if (lt(seq1[i], seq2[i])) { 10918 return true; 10919 } 10920 } 10921 if (seq1.length > seq2.length) { 10922 return false; 10923 } 10924 return true; 10925 } 10926 10927 /** Returns true iff seq1 is lexically > to seq2. */ 10928 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10929 @Pure 10930 public static boolean lexGT(short @Nullable [] seq1, short @Nullable [] seq2) { 10931 if (seq1 == null) { 10932 return false; 10933 } 10934 if (seq2 == null) { 10935 return false; 10936 } 10937 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 10938 for (int i = 0 ; i < minlength ; i++) { 10939 if (lt(seq1[i], seq2[i])) { 10940 return false; 10941 } else if (gt(seq1[i], seq2[i])) { 10942 return true; 10943 } 10944 } 10945 if (seq1.length <= seq2.length) { 10946 return false; 10947 } 10948 return true; 10949 } 10950 10951 /** Returns true iff seq1 is lexically ≥ to seq2. */ 10952 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 10953 @Pure 10954 public static boolean lexGTE(short @Nullable [] seq1, short @Nullable [] seq2) { 10955 if (seq1 == null) { 10956 return false; 10957 } 10958 if (seq2 == null) { 10959 return false; 10960 } 10961 int minlength = (seq1.length < seq2.length) ? seq1.length : seq2.length; 10962 for (int i = 0 ; i < minlength ; i++) { 10963 if (lt(seq1[i], seq2[i])) { 10964 return false; 10965 } else if (gt(seq1[i], seq2[i])) { 10966 return true; 10967 } 10968 } 10969 if (seq1.length < seq2.length) { 10970 return false; 10971 } 10972 return true; 10973 } 10974 10975 /** True iff for all applicable i, every seq[i] == seq[i+1]. 10976 * 10977 * Meaning (in pseudo-FOL): 10978 * 10979 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 10980 * 10981 */ 10982 @EnsuresNonNullIf(result=true, expression="#1") 10983 @Pure 10984 public static boolean eltwiseEqual(short @Nullable [] seq) { 10985 if (seq == null) { 10986 return false; 10987 } 10988 for (int i = 0 ; i < seq.length ; i++) { 10989 if (i < seq.length - 1) { 10990 if (ne(seq[i], seq[i + 1])) { 10991 return false; 10992 } 10993 } 10994 } 10995 return true; 10996 } 10997 10998 /** True iff for all applicable i, every seq[i] != seq[i+1]. 10999 * 11000 * Meaning (in pseudo-FOL): 11001 * 11002 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 11003 * 11004 */ 11005 @EnsuresNonNullIf(result=true, expression="#1") 11006 @Pure 11007 public static boolean eltwiseNotEqual(short @Nullable [] seq) { 11008 if (seq == null) { 11009 return false; 11010 } 11011 for (int i = 0 ; i < seq.length ; i++) { 11012 if (i < seq.length - 1) { 11013 if (eq(seq[i], seq[i + 1])) { 11014 return false; 11015 } 11016 } 11017 } 11018 return true; 11019 } 11020 11021 /** True iff for all applicable i, every seq[i] < seq[i+1]. 11022 * 11023 * Meaning (in pseudo-FOL): 11024 * 11025 * forall i in { 0..seq.length-2 } : seq[i] < seq[i+1] 11026 * 11027 */ 11028 @EnsuresNonNullIf(result=true, expression="#1") 11029 @Pure 11030 public static boolean eltwiseLT(short @Nullable [] seq) { 11031 if (seq == null) { 11032 return false; 11033 } 11034 for (int i = 0 ; i < seq.length ; i++) { 11035 if (i < seq.length - 1) { 11036 if (gte(seq[i], seq[i + 1])) { 11037 return false; 11038 } 11039 } 11040 } 11041 return true; 11042 } 11043 11044 /** True iff for all applicable i, every seq[i] ≤ seq[i+1]. 11045 * 11046 * Meaning (in pseudo-FOL): 11047 * 11048 * forall i in { 0..seq.length-2 } : seq[i] ≤ seq[i+1] 11049 * 11050 */ 11051 @EnsuresNonNullIf(result=true, expression="#1") 11052 @Pure 11053 public static boolean eltwiseLTE(short @Nullable [] seq) { 11054 if (seq == null) { 11055 return false; 11056 } 11057 for (int i = 0 ; i < seq.length ; i++) { 11058 if (i < seq.length - 1) { 11059 if (gt(seq[i], seq[i + 1])) { 11060 return false; 11061 } 11062 } 11063 } 11064 return true; 11065 } 11066 11067 /** True iff for all applicable i, every seq[i] > seq[i+1]. 11068 * 11069 * Meaning (in pseudo-FOL): 11070 * 11071 * forall i in { 0..seq.length-2 } : seq[i] > seq[i+1] 11072 * 11073 */ 11074 @EnsuresNonNullIf(result=true, expression="#1") 11075 @Pure 11076 public static boolean eltwiseGT(short @Nullable [] seq) { 11077 if (seq == null) { 11078 return false; 11079 } 11080 for (int i = 0 ; i < seq.length ; i++) { 11081 if (i < seq.length - 1) { 11082 if (lte(seq[i], seq[i + 1])) { 11083 return false; 11084 } 11085 } 11086 } 11087 return true; 11088 } 11089 11090 /** True iff for all applicable i, every seq[i] ≥ seq[i+1]. 11091 * 11092 * Meaning (in pseudo-FOL): 11093 * 11094 * forall i in { 0..seq.length-2 } : seq[i] ≥ seq[i+1] 11095 * 11096 */ 11097 @EnsuresNonNullIf(result=true, expression="#1") 11098 @Pure 11099 public static boolean eltwiseGTE(short @Nullable [] seq) { 11100 if (seq == null) { 11101 return false; 11102 } 11103 for (int i = 0 ; i < seq.length ; i++) { 11104 if (i < seq.length - 1) { 11105 if (lt(seq[i], seq[i + 1])) { 11106 return false; 11107 } 11108 } 11109 } 11110 return true; 11111 } 11112 11113 /** True iff for all applicable i, every seq[i] == i. 11114 * 11115 * Meaning (in pseudo-FOL): 11116 * 11117 * forall i in { 0..seq.length-1 } : seq[i] == i 11118 * 11119 */ 11120 @EnsuresNonNullIf(result=true, expression="#1") 11121 @Pure 11122 public static boolean eltsEqualIndex(short @Nullable [] seq) { 11123 if (seq == null) { 11124 return false; 11125 } 11126 for (int i = 0 ; i < seq.length ; i++) { 11127 if (ne(seq[i], i)) { 11128 return false; 11129 } 11130 } 11131 return true; 11132 } 11133 11134 /** True iff for all applicable i, every seq[i] != i. 11135 * 11136 * Meaning (in pseudo-FOL): 11137 * 11138 * forall i in { 0..seq.length-1 } : seq[i] != i 11139 * 11140 */ 11141 @EnsuresNonNullIf(result=true, expression="#1") 11142 @Pure 11143 public static boolean eltsNotEqualIndex(short @Nullable [] seq) { 11144 if (seq == null) { 11145 return false; 11146 } 11147 for (int i = 0 ; i < seq.length ; i++) { 11148 if (eq(seq[i], i)) { 11149 return false; 11150 } 11151 } 11152 return true; 11153 } 11154 11155 /** True iff for all applicable i, every seq[i] < i. 11156 * 11157 * Meaning (in pseudo-FOL): 11158 * 11159 * forall i in { 0..seq.length-1 } : seq[i] < i 11160 * 11161 */ 11162 @EnsuresNonNullIf(result=true, expression="#1") 11163 @Pure 11164 public static boolean eltsLtIndex(short @Nullable [] seq) { 11165 if (seq == null) { 11166 return false; 11167 } 11168 for (int i = 0 ; i < seq.length ; i++) { 11169 if (gte(seq[i], i)) { 11170 return false; 11171 } 11172 } 11173 return true; 11174 } 11175 11176 /** True iff for all applicable i, every seq[i] ≤ i. 11177 * 11178 * Meaning (in pseudo-FOL): 11179 * 11180 * forall i in { 0..seq.length-1 } : seq[i] ≤ i 11181 * 11182 */ 11183 @EnsuresNonNullIf(result=true, expression="#1") 11184 @Pure 11185 public static boolean eltsLteIndex(short @Nullable [] seq) { 11186 if (seq == null) { 11187 return false; 11188 } 11189 for (int i = 0 ; i < seq.length ; i++) { 11190 if (gt(seq[i], i)) { 11191 return false; 11192 } 11193 } 11194 return true; 11195 } 11196 11197 /** True iff for all applicable i, every seq[i] > i. 11198 * 11199 * Meaning (in pseudo-FOL): 11200 * 11201 * forall i in { 0..seq.length-1 } : seq[i] > i 11202 * 11203 */ 11204 @EnsuresNonNullIf(result=true, expression="#1") 11205 @Pure 11206 public static boolean eltsGtIndex(short @Nullable [] seq) { 11207 if (seq == null) { 11208 return false; 11209 } 11210 for (int i = 0 ; i < seq.length ; i++) { 11211 if (lte(seq[i], i)) { 11212 return false; 11213 } 11214 } 11215 return true; 11216 } 11217 11218 /** True iff for all applicable i, every seq[i] ≥ i. 11219 * 11220 * Meaning (in pseudo-FOL): 11221 * 11222 * forall i in { 0..seq.length-1 } : seq[i] ≥ i 11223 * 11224 */ 11225 @EnsuresNonNullIf(result=true, expression="#1") 11226 @Pure 11227 public static boolean eltsGteIndex(short @Nullable [] seq) { 11228 if (seq == null) { 11229 return false; 11230 } 11231 for (int i = 0 ; i < seq.length ; i++) { 11232 if (lt(seq[i], i)) { 11233 return false; 11234 } 11235 } 11236 return true; 11237 } 11238 11239 /// Deferencing (accessing) fields 11240 11241 /** 11242 * collectshort accepts an object and a list of fields (one of which is of array type, and the 11243 * rest of which are not), and produces an array in which the original object has had the given 11244 * fields accessed. 11245 * 11246 * <p>Daikon creates invariants over "variables" such as the following. 11247 * 11248 * <dl> 11249 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 11250 * for all y's in array x.arr.</dd> 11251 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 11252 * for all x's in array arr.</dd> 11253 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 11254 * </dl> 11255 * 11256 * <p>The collectshort() method does this collecting work. 11257 * 11258 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 11259 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 11260 * elements that result from following the fields, one of which is assumed to be an array. 11261 * 11262 * <p> 11263 * requires: fieldStr.length() > 0 and object != null 11264 * <p> 11265 * requires: fieldStr contains only field names, no "[]" strings. 11266 * <p> 11267 * requires: the method only works for field sequences with exactly one field representing an 11268 * array. For example, the collection a[].b[].c will fail. 11269 * 11270 * @return if the resulting collection is of non-primitive type, then returns an array of type 11271 * Object[]. Returns null if any array or field access causes an exception. 11272 */ 11273 11274 @SideEffectFree 11275 public static short @Nullable [] collectshort(@Nullable Object object, @Nullable String fieldStr) { 11276 11277 if (object == null) { 11278 return null; 11279 } 11280 if (fieldStr == null) { 11281 return null; 11282 } 11283 11284 // assert fieldStr != null && !"".equals(fieldStr); 11285 String[] fieldNames = fieldStr.split("\\."); 11286 short[] retval = collectshort(object, fieldNames, 0); 11287 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 11288 return retval; 11289 } 11290 11291 /** Helper method for collectshort(Object, String). 11292 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 11293 * @see collectshort(Object, String) 11294 */ 11295 // @PolyNull does not work for return type, because null is returned on error. 11296 @SideEffectFree 11297 private static short @Nullable [] collectshort(@Nullable Object object, 11298 String[] fields, int fieldsStartIdx) { 11299 11300 if (object == null) { 11301 return null; 11302 } 11303 assert (fields != null); 11304 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 11305 11306 Object fieldObj; 11307 try { 11308 Field field = (object instanceof java.lang.Class<?>) 11309 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 11310 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 11311 field.setAccessible(true); 11312 // Class cls = field.getType(); 11313 fieldObj = field.get(object); 11314 // System.out.println("***fieldObj="+fieldObj); 11315 11316 } catch (Exception e) { 11317 return null; 11318 11319 } 11320 11321 if (fieldObj == null) { 11322 return null; 11323 } 11324 11325 // base case: just accessed the last field 11326 if (fields.length - 1 == fieldsStartIdx) { 11327 11328 if (fieldObj.getClass().isArray()) { 11329 // last field is an array 11330 return (short[])fieldObj; 11331 } else { 11332 // This hack should be removed in favor of, at "oneEltArray = ..." 11333 // below, calling a version of collectshort_field that throws an 11334 // error. Then, this case becomes a run-time error. -MDE 11335 11336 // Just one element; return a one-element array. 11337 // assert cls.equals(Short.TYPE); 11338 return new short[] { ((Short)fieldObj).shortValue() }; 11339 } 11340 } else { 11341 // recursive case: more fields to access after this one 11342 11343 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 11344 11345 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 11346 short[] intermediate = new short[collection.size()]; 11347 int index = 0; 11348 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 11349 Object obj = i.next(); 11350 short[] oneEltArray = collectshort(obj, fields, fieldsStartIdx + 1); 11351 if (oneEltArray == null) { 11352 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 11353 } 11354 // assert oneEltArray.length == 1; 11355 intermediate[index++] = oneEltArray[0]; 11356 } 11357 return intermediate; 11358 } else if (fieldObj.getClass().isArray()) { 11359 11360 // collect elements across array 11361 short[] intermediate = new short[Array.getLength(fieldObj)]; 11362 for (int i = 0 ; i < intermediate.length ; i++) { 11363 Object obj = Array.get(fieldObj, i); 11364 short[] oneEltArray = collectshort(obj, fields, fieldsStartIdx + 1); 11365 if (oneEltArray == null) { 11366 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 11367 } 11368 // assert oneEltArray.length == 1; 11369 intermediate[i] = oneEltArray[0]; 11370 } 11371 return intermediate; 11372 } else { 11373 11374 return collectshort(fieldObj, fields, fieldsStartIdx + 1); 11375 } 11376 } 11377 } 11378 11379 /** 11380 * Returns the results of dereferencing the fields for 'object'. For example, the call 11381 * 11382 * <pre>collectshort_field(x, "f.g.h")</pre> 11383 * 11384 * has the same value as 11385 * 11386 * <pre>x.f.g.h</pre>. 11387 * Returns a default value if any field access causes an exception. 11388 */ 11389 @SideEffectFree 11390 public static short collectshort_field(Object object, String fieldStr) { 11391 11392 if (object == null) { 11393 return Short.MAX_VALUE; // return default value 11394 } 11395 if (fieldStr == null) { 11396 return Short.MAX_VALUE; // return default value 11397 } 11398 11399 String[] fieldNames = fieldStr.split("\\."); 11400 11401 // Holds the intermediate (and final) result 11402 Object fieldObj = object; 11403 11404 for (int i = 0 ; i < fieldNames.length ; i++) { 11405 11406 String fieldName = fieldNames[i]; 11407 11408 try { 11409 Field field = 11410 (fieldObj instanceof java.lang.Class<?>) 11411 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 11412 : fieldObj.getClass().getDeclaredField(fieldName); 11413 field.setAccessible(true); 11414 fieldObj = field.get(fieldObj); 11415 11416 if (fieldObj == null) { 11417 return Short.MAX_VALUE; // return default value 11418 } 11419 11420 } catch (Exception e) { 11421 return Short.MAX_VALUE; // return default value 11422 11423 } 11424 11425 } 11426 11427 return ((Short)fieldObj).shortValue(); 11428 } 11429 11430 /////////////////////////////////////////////////////////////////////////// 11431 /// Methods for #@Interned Object (from QuantBody.java.jpp) 11432 /// 11433 11434 /** 11435 * Returns the ith element of the array or collection argument. If the argument is null or not an 11436 * array or collection, returns a default value (null). 11437 */ 11438 11439 @SuppressWarnings("interning") // reflection 11440 11441 @Pure 11442 public static @Nullable @Interned Object getElement_Object(Object o, long i) { 11443 if (o == null) { 11444 return null; // return default value 11445 } 11446 java.lang.Class<?> c = o.getClass(); 11447 if (c.isArray()) { 11448 return java.lang.reflect.Array.get(o, (int)i); 11449 } else if (o instanceof java.util.AbstractCollection<?>) { 11450 return java.lang.reflect.Array.get(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 11451 } else { 11452 return null; // return default value 11453 } 11454 } 11455 11456 @SuppressWarnings("interning") // called reflectively 11457 11458 @Pure 11459 public static @Nullable @Interned Object getElement_Object(Object[] arr, long i) { 11460 if (arr == null) { 11461 return null; // return default value 11462 } 11463 return arr[(int)i]; 11464 } 11465 11466 private static boolean eq(@Interned Object x, @Interned Object y) { 11467 return x == y; 11468 } 11469 11470 private static boolean ne(@Interned Object x, @Interned Object y) { 11471 return x != y; 11472 } 11473 11474 /** 11475 * Returns an array of Strings, where the strings are the result of invoking 11476 * x.getClass().toString() for each element x in the array. If an element of the array is null, 11477 * its slot in the returned array is null. 11478 */ 11479 @SideEffectFree 11480 public static @PolyNull/*("elt")*/ String @PolyNull/*("container")*/ [] typeArray(@PolyNull/*("elt")*/ @Interned Object @PolyNull/*("container")*/ [] seq) { 11481 if (seq == null) { 11482 return null; 11483 } 11484 @PolyNull/*("elt")*/ String[] retval = new @PolyNull/*("elt")*/ String[seq.length]; 11485 for (int i = 0 ; i < seq.length ; i++) { 11486 if (seq[i] == null) { 11487 retval[i] = null; 11488 } else { 11489 retval[i] = seq[i].getClass().toString(); 11490 } 11491 } 11492 return retval; 11493 } 11494 11495 /** True iff both sequences are non-null and have the same length. */ 11496 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 11497 @Pure 11498 public static boolean sameLength(Object @Nullable [] seq1, Object @Nullable [] seq2) { 11499 return ((seq1 != null) 11500 && (seq2 != null) 11501 && seq1.length == seq2.length); 11502 } 11503 11504 /** 11505 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 11506 * 11507 * <p>If either array is null, returns null. If either array is empty, returns only those 11508 * elements in the other array. If both arrays are empty, returns a new empty array. 11509 */ 11510 @SideEffectFree 11511 public static @Interned Object @PolyNull [] concat(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) { 11512 if (seq1 == null) { 11513 return null; 11514 } 11515 if (seq2 == null) { 11516 return null; 11517 } 11518 return ArraysPlume.concat(seq1, seq2); 11519 } 11520 11521 /** 11522 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 11523 * assurances about the order or repetition of elements: elements may be repeated, and their 11524 * order may be different from the order of elements in seq1 and seq2. 11525 */ 11526 @SideEffectFree 11527 public static @Interned Object @PolyNull [] union(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) { 11528 if (seq1 == null) { 11529 return null; 11530 } 11531 if (seq2 == null) { 11532 return null; 11533 } 11534 return concat(seq1, seq2); 11535 } 11536 11537 /** 11538 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 11539 * gives no assurances about the order or repetition of elements: elements may be repeated, and 11540 * their order may be different from the order of elements in seq1 and seq2. 11541 */ 11542 @Pure 11543 public static @Interned Object @PolyNull [] intersection(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) { 11544 if (seq1 == null) { 11545 return null; 11546 } 11547 if (seq2 == null) { 11548 return null; 11549 } 11550 @Interned Object[] intermediate = new @Interned Object[Math.min(seq1.length, seq2.length)]; 11551 int length = 0; 11552 for (int i = 0 ; i < seq1.length ; i++) { 11553 if (memberOf(seq1[i], seq2) ) { 11554 intermediate[length++] = seq1[i]; 11555 } 11556 } 11557 return ArraysPlume.subarray(intermediate, 0, length); 11558 } 11559 11560 /** 11561 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 11562 * no assurances about the order or repetition of elements: elements may be repeated, and their 11563 * order may be different from the order of elements in seq1 and seq2. 11564 */ 11565 @Pure 11566 public static @Interned Object @PolyNull [] setDiff(@Interned Object @PolyNull [] seq1, @Interned Object @PolyNull [] seq2) { 11567 if (seq1 == null) { 11568 return null; 11569 } 11570 if (seq2 == null) { 11571 return null; 11572 } 11573 @Interned Object[] intermediate = new @Interned Object[seq1.length]; 11574 int length = 0; 11575 for (int i = 0 ; i < seq1.length ; i++) { 11576 if (!memberOf(seq1[i], seq2)) { 11577 intermediate[length++] = seq1[i]; 11578 } 11579 } 11580 return ArraysPlume.subarray(intermediate, 0, length); 11581 } 11582 11583 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 11584 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11585 @Pure 11586 public static boolean setEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) { 11587 if (seq1 == null) { 11588 return false; 11589 } 11590 if (seq2 == null) { 11591 return false; 11592 } 11593 for (int i = 0; i < seq1.length ; i++) { 11594 if (!memberOf(seq1[i], seq2) ) { 11595 return false; 11596 } 11597 } 11598 for (int i = 0; i < seq2.length ; i++) { 11599 if (!memberOf(seq2[i], seq1) ) { 11600 return false; 11601 } 11602 } 11603 return true; 11604 } 11605 11606 /** True iff seq1 is the reverse of seq2. 11607 * 11608 * Meaning (in pseudo-FOL): 11609 * 11610 * <pre> 11611 * /\ seq1.length == seq2.length 11612 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 11613 * </pre> 11614 * 11615 */ 11616 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11617 @Pure 11618 public static boolean isReverse(@Interned Object[] seq1, @Interned Object[] seq2) { 11619 if (!sameLength(seq1, seq2)) { 11620 return false; 11621 } 11622 assert seq1 != null && seq2 != null; // because sameLength() = true 11623 int length = seq1.length; 11624 for (int i = 0 ; i < length ; i++) { 11625 if (ne(seq1[i], seq2[length - i - 1])) { 11626 return false; 11627 } 11628 } 11629 return true; 11630 } 11631 11632 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11633 @Pure 11634 public static boolean isReverse(@PolyNull Collection<? extends @Interned Object> seq1, @Interned Object @Nullable [] seq2) { 11635 if (seq1 == null) { 11636 return false; 11637 } 11638 if (seq2 == null) { 11639 return false; 11640 } 11641 @Interned Object[] seq1_array = seq1.toArray(new @Interned Object[]{}); 11642 return isReverse(seq1_array, seq2); 11643 } 11644 11645 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 11646 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11647 @Pure 11648 public static boolean subsetOf(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) { 11649 if (seq1 == null) { 11650 return false; 11651 } 11652 if (seq2 == null) { 11653 return false; 11654 } 11655 for (int i = 0 ; i < seq1.length ; i++) { 11656 if (!memberOf(seq1[i], seq2)) { 11657 return false; 11658 } 11659 } 11660 return true; 11661 } 11662 11663 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11664 @Pure 11665 public static boolean subsetOf(@Nullable Collection<? extends @Interned Object> seq1, @Interned Object @Nullable [] seq2) { 11666 if (seq1 == null) { 11667 return false; 11668 } 11669 if (seq2 == null) { 11670 return false; 11671 } 11672 @Interned Object[] seq1_array = seq1.toArray(new @Interned Object[]{}); 11673 return subsetOf(seq1_array, seq2); 11674 } 11675 11676 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11677 @Pure 11678 public static boolean subsetOf(@Interned Object @Nullable [] seq1, @Nullable Collection<? extends @Interned Object> seq2) { 11679 if (seq1 == null) { 11680 return false; 11681 } 11682 if (seq2 == null) { 11683 return false; 11684 } 11685 @Interned Object[] seq2_array = seq2.toArray(new @Interned Object[]{}); 11686 return subsetOf(seq1, seq2_array); 11687 } 11688 11689 /** Returns true iff seq contains no duplicate elements. */ 11690 @EnsuresNonNullIf(result=true, expression="#1") 11691 @Pure 11692 public static boolean noDups(@Interned Object @Nullable [] seq) { 11693 if (seq == null) { 11694 return false; 11695 } 11696 return ArraysPlume.noDuplicates(seq); 11697 } 11698 11699 /** Returns true iff elt is in array arr. */ 11700 @EnsuresNonNullIf(result=true, expression="#2") 11701 @Pure 11702 public static boolean memberOf(@Interned Object elt, @Interned Object @Nullable [] arr) { 11703 if (arr == null) { 11704 return false; 11705 } 11706 for (int i = 0 ; i < arr.length ; i++) { 11707 if (eq(arr[i], elt)) { 11708 return true; 11709 } 11710 } 11711 return false; 11712 } 11713 11714 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 11715 @Pure 11716 public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, int start, int end) { 11717 if (seq == null) { 11718 return null; 11719 } 11720 int sliceStart = start; 11721 int sliceEnd = end; 11722 if (start < 0) { 11723 return new @Interned Object[] { }; 11724 } 11725 if (end > seq.length - 1) { 11726 return new @Interned Object[] { }; 11727 } 11728 if (sliceStart > sliceEnd) { 11729 return new @Interned Object[] { }; 11730 } 11731 int length = sliceEnd - sliceStart + 1; 11732 return ArraysPlume.subarray(seq, sliceStart, length); 11733 } 11734 11735 @Pure 11736 public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, long start, int end) { 11737 return slice(seq, (int)start, end); 11738 } 11739 @Pure 11740 public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, int start, long end) { 11741 return slice(seq, start, (int)end); 11742 } 11743 @Pure 11744 public static @Interned Object @PolyNull [] slice(@Interned Object @PolyNull [] seq, long start, long end) { 11745 return slice(seq, (int)start, (int)end); 11746 } 11747 11748 /** True iff all elements in arr equal elt. 11749 * 11750 * Meaning (in pseudo-FOL): 11751 * 11752 * forall i in { 0..arr.length-1 } : arr[i] == elt 11753 * 11754 */ 11755 @EnsuresNonNullIf(result=true, expression="#1") 11756 @Pure 11757 public static boolean eltsEqual(@Interned Object @Nullable [] arr, @Interned Object elt) { 11758 if (arr == null) { 11759 return false; 11760 } 11761 for (int i = 0 ; i < arr.length ; i++) { 11762 if (ne(arr[i], elt)) { 11763 return false; 11764 } 11765 } 11766 return true; 11767 } 11768 11769 /** True iff every element in arr does not equal elt. 11770 * 11771 * Meaning (in pseudo-FOL): 11772 * 11773 * forall i in { 0..arr.length-1 } : arr[i] != elt 11774 * 11775 */ 11776 @EnsuresNonNullIf(result=true, expression="#1") 11777 @Pure 11778 public static boolean eltsNotEqual(@Interned Object @Nullable [] arr, @Interned Object elt) { 11779 if (arr == null) { 11780 return false; 11781 } 11782 for (int i = 0 ; i < arr.length ; i++) { 11783 if (eq(arr[i], elt)) { 11784 return false; 11785 } 11786 } 11787 return true; 11788 } 11789 11790 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 11791 * 11792 * Meaning (in pseudo-FOL): 11793 * 11794 * /\ seq1.length == se2.length 11795 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 11796 * 11797 */ 11798 11799 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11800 @Pure 11801 public static boolean pairwiseEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) { 11802 if (!sameLength(seq1, seq2)) { 11803 return false; 11804 } 11805 assert seq1 != null && seq2 != null; // because sameLength() = true 11806 for (int i = 0 ; i < seq1.length ; i++) { 11807 if (ne(seq1[i], seq2[i])) { 11808 return false; 11809 } 11810 } 11811 return true; 11812 } 11813 11814 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11815 @Pure 11816 public static boolean pairwiseEqual(@Nullable AbstractCollection<@Interned Object> seq1, @Interned Object @Nullable [] seq2) { 11817 if (seq1 == null) { 11818 return false; 11819 } 11820 if (seq2 == null) { 11821 return false; 11822 } 11823 @SuppressWarnings("cast") // cast is redundant (except in JSR 308) 11824 @Interned Object[] seq1a = (@Interned Object[]) seq1.toArray(new @Interned Object[0]); 11825 return pairwiseEqual(seq1a, seq2); 11826 } 11827 11828 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11829 @Pure 11830 public static boolean pairwiseEqual(@Interned Object @Nullable [] seq1, @Nullable AbstractCollection<@Interned Object> seq2) { 11831 if (seq1 == null) { 11832 return false; 11833 } 11834 if (seq2 == null) { 11835 return false; 11836 } 11837 @SuppressWarnings("cast") // cast is redundant (except in JSR 308) 11838 @Interned Object[] seq2a = (@Interned Object[]) seq2.toArray(); 11839 return pairwiseEqual(seq1, seq2a); 11840 } 11841 11842 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 11843 * 11844 * Meaning (in pseudo-FOL): 11845 * 11846 * /\ seq1.length == se2.length 11847 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 11848 * 11849 */ 11850 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11851 @Pure 11852 public static boolean pairwiseNotEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) { 11853 if (!sameLength(seq1, seq2)) { 11854 return false; 11855 } 11856 assert seq1 != null && seq2 != null; // because sameLength() = true 11857 for (int i = 0 ; i < seq1.length ; i++) { 11858 if (eq(seq1[i], seq2[i])) { 11859 return false; 11860 } 11861 } 11862 return true; 11863 } 11864 11865 /** 11866 * Returns true iff seq1 is lexically equal to seq2. 11867 * For equality, "lexically" and "pairwise" are the same. 11868 */ 11869 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11870 @Pure 11871 public static boolean lexEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) { 11872 if (seq1 == null) { 11873 return false; 11874 } 11875 if (seq2 == null) { 11876 return false; 11877 } 11878 return pairwiseEqual(seq1, seq2); 11879 } 11880 11881 /** Returns true iff seq1 is lexically not equal to seq2. */ 11882 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 11883 @Pure 11884 public static boolean lexNotEqual(@Interned Object @Nullable [] seq1, @Interned Object @Nullable [] seq2) { 11885 if (seq1 == null) { 11886 return false; 11887 } 11888 if (seq2 == null) { 11889 return false; 11890 } 11891 return !lexEqual(seq1, seq2); 11892 } 11893 11894 /** True iff for all applicable i, every seq[i] == seq[i+1]. 11895 * 11896 * Meaning (in pseudo-FOL): 11897 * 11898 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 11899 * 11900 */ 11901 @EnsuresNonNullIf(result=true, expression="#1") 11902 @Pure 11903 public static boolean eltwiseEqual(@Interned Object @Nullable [] seq) { 11904 if (seq == null) { 11905 return false; 11906 } 11907 for (int i = 0 ; i < seq.length ; i++) { 11908 if (i < seq.length - 1) { 11909 if (ne(seq[i], seq[i + 1])) { 11910 return false; 11911 } 11912 } 11913 } 11914 return true; 11915 } 11916 11917 /** True iff for all applicable i, every seq[i] != seq[i+1]. 11918 * 11919 * Meaning (in pseudo-FOL): 11920 * 11921 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 11922 * 11923 */ 11924 @EnsuresNonNullIf(result=true, expression="#1") 11925 @Pure 11926 public static boolean eltwiseNotEqual(@Interned Object @Nullable [] seq) { 11927 if (seq == null) { 11928 return false; 11929 } 11930 for (int i = 0 ; i < seq.length ; i++) { 11931 if (i < seq.length - 1) { 11932 if (eq(seq[i], seq[i + 1])) { 11933 return false; 11934 } 11935 } 11936 } 11937 return true; 11938 } 11939 11940 /// Deferencing (accessing) fields 11941 11942 /** 11943 * collectObject accepts an object and a list of fields (one of which is of array type, and the 11944 * rest of which are not), and produces an array in which the original object has had the given 11945 * fields accessed. 11946 * 11947 * <p>Daikon creates invariants over "variables" such as the following. 11948 * 11949 * <dl> 11950 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 11951 * for all y's in array x.arr.</dd> 11952 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 11953 * for all x's in array arr.</dd> 11954 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 11955 * </dl> 11956 * 11957 * <p>The collectObject() method does this collecting work. 11958 * 11959 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 11960 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 11961 * elements that result from following the fields, one of which is assumed to be an array. 11962 * 11963 * <p> 11964 * requires: fieldStr.length() > 0 and object != null 11965 * <p> 11966 * requires: fieldStr contains only field names, no "[]" strings. 11967 * <p> 11968 * requires: the method only works for field sequences with exactly one field representing an 11969 * array. For example, the collection a[].b[].c will fail. 11970 * 11971 * @return if the resulting collection is of non-primitive type, then returns an array of type 11972 * Object[]. Returns null if any array or field access causes an exception. 11973 */ 11974 11975 @SuppressWarnings("interning") // reflection 11976 11977 @SideEffectFree 11978 public static Object @Nullable [] collectObject(@Nullable Object object, @Nullable String fieldStr) { 11979 11980 if (object == null) { 11981 return null; 11982 } 11983 if (fieldStr == null) { 11984 return null; 11985 } 11986 11987 // assert fieldStr != null && !"".equals(fieldStr); 11988 String[] fieldNames = fieldStr.split("\\."); 11989 @Interned Object[] retval = collectObject(object, fieldNames, 0); 11990 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 11991 return retval; 11992 } 11993 11994 @SuppressWarnings("interning") // reflection 11995 11996 /** Helper method for collectObject(Object, String). 11997 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 11998 * @see collectObject(Object, String) 11999 */ 12000 // @PolyNull does not work for return type, because null is returned on error. 12001 @SideEffectFree 12002 private static Object @Nullable [] collectObject(@Nullable Object object, 12003 String[] fields, int fieldsStartIdx) { 12004 12005 if (object == null) { 12006 return null; 12007 } 12008 assert (fields != null); 12009 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 12010 12011 Object fieldObj; 12012 try { 12013 Field field = (object instanceof java.lang.Class<?>) 12014 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 12015 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 12016 field.setAccessible(true); 12017 // Class cls = field.getType(); 12018 fieldObj = field.get(object); 12019 // System.out.println("***fieldObj="+fieldObj); 12020 12021 } catch (Exception e) { 12022 return null; 12023 12024 } 12025 12026 if (fieldObj == null) { 12027 return null; 12028 } 12029 12030 // base case: just accessed the last field 12031 if (fields.length - 1 == fieldsStartIdx) { 12032 12033 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 12034 // last field is the collection 12035 @SuppressWarnings("unchecked") 12036 java.util.AbstractCollection<@Interned Object> ac = (java.util.AbstractCollection<@Interned Object>)fieldObj; 12037 return ac.toArray(new @Interned Object[]{}); 12038 } else 12039 12040 if (fieldObj.getClass().isArray()) { 12041 // last field is an array 12042 return (@Interned Object[])fieldObj; 12043 } else { 12044 // This hack should be removed in favor of, at "oneEltArray = ..." 12045 // below, calling a version of collectObject_field that throws an 12046 // error. Then, this case becomes a run-time error. -MDE 12047 12048 // Just one element; return a one-element array. 12049 // assert cls.equals(_TYPE_WRAPPER_NAME.TYPE); 12050 return new @Interned Object[] { fieldObj }; 12051 } 12052 } else { 12053 // recursive case: more fields to access after this one 12054 12055 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 12056 12057 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 12058 @Interned Object[] intermediate = new @Interned Object[collection.size()]; 12059 int index = 0; 12060 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 12061 Object obj = i.next(); 12062 Object[] oneEltArray = collectObject(obj, fields, fieldsStartIdx + 1); 12063 if (oneEltArray == null) { 12064 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 12065 } 12066 // assert oneEltArray.length == 1; 12067 intermediate[index++] = oneEltArray[0]; 12068 } 12069 return intermediate; 12070 } else if (fieldObj.getClass().isArray()) { 12071 12072 // collect elements across array 12073 @Interned Object[] intermediate = new @Interned Object[Array.getLength(fieldObj)]; 12074 for (int i = 0 ; i < intermediate.length ; i++) { 12075 Object obj = Array.get(fieldObj, i); 12076 Object[] oneEltArray = collectObject(obj, fields, fieldsStartIdx + 1); 12077 if (oneEltArray == null) { 12078 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 12079 } 12080 // assert oneEltArray.length == 1; 12081 intermediate[i] = oneEltArray[0]; 12082 } 12083 return intermediate; 12084 } else { 12085 12086 return collectObject(fieldObj, fields, fieldsStartIdx + 1); 12087 } 12088 } 12089 } 12090 12091 /** 12092 * Returns the results of dereferencing the fields for 'object'. For example, the call 12093 * 12094 * <pre>collectObject_field(x, "f.g.h")</pre> 12095 * 12096 * has the same value as 12097 * 12098 * <pre>x.f.g.h</pre>. 12099 * Returns a default value if any field access causes an exception. 12100 */ 12101 @SideEffectFree 12102 public static @Nullable Object collectObject_field(Object object, String fieldStr) { 12103 12104 if (object == null) { 12105 return null; // return default value 12106 } 12107 if (fieldStr == null) { 12108 return null; // return default value 12109 } 12110 12111 String[] fieldNames = fieldStr.split("\\."); 12112 12113 // Holds the intermediate (and final) result 12114 Object fieldObj = object; 12115 12116 for (int i = 0 ; i < fieldNames.length ; i++) { 12117 12118 String fieldName = fieldNames[i]; 12119 12120 try { 12121 Field field = 12122 (fieldObj instanceof java.lang.Class<?>) 12123 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 12124 : fieldObj.getClass().getDeclaredField(fieldName); 12125 field.setAccessible(true); 12126 fieldObj = field.get(fieldObj); 12127 12128 if (fieldObj == null) { 12129 return null; // return default value 12130 } 12131 12132 } catch (Exception e) { 12133 return null; // return default value 12134 12135 } 12136 12137 } 12138 12139 return fieldObj; 12140 } 12141 12142 /////////////////////////////////////////////////////////////////////////// 12143 /// Methods for #@Interned String (from QuantBody.java.jpp) 12144 /// 12145 12146 /** 12147 * Returns the ith element of the array or collection argument. If the argument is null or not an 12148 * array or collection, returns a default value (null). 12149 */ 12150 12151 @SuppressWarnings("interning") // reflection 12152 12153 @Pure 12154 public static @Nullable @Interned String getElement_String(Object o, long i) { 12155 if (o == null) { 12156 return null; // return default value 12157 } 12158 java.lang.Class<?> c = o.getClass(); 12159 if (c.isArray()) { 12160 return (String)java.lang.reflect.Array.get(o, (int)i); 12161 } else if (o instanceof java.util.AbstractCollection<?>) { 12162 return (String)java.lang.reflect.Array.get(((java.util.AbstractCollection<?>)o).toArray(), (int)i); 12163 } else { 12164 return null; // return default value 12165 } 12166 } 12167 12168 @SuppressWarnings("interning") // called reflectively 12169 12170 @Pure 12171 public static @Nullable @Interned String getElement_String(String[] arr, long i) { 12172 if (arr == null) { 12173 return null; // return default value 12174 } 12175 return arr[(int)i]; 12176 } 12177 12178 private static boolean eq(@Interned String x, @Interned String y) { 12179 return x == y; 12180 } 12181 12182 private static boolean ne(@Interned String x, @Interned String y) { 12183 return x != y; 12184 } 12185 12186 /** True iff both sequences are non-null and have the same length. */ 12187 @EnsuresNonNullIf(result=true, expression={"#1", "#2"}) 12188 @Pure 12189 public static boolean sameLength(String @Nullable [] seq1, String @Nullable [] seq2) { 12190 return ((seq1 != null) 12191 && (seq2 != null) 12192 && seq1.length == seq2.length); 12193 } 12194 12195 /** 12196 * Returns the array { seq1[0], ..., seq1[seq1.length-1], seq2[0], ... , seq2[seq2.length-1] } . 12197 * 12198 * <p>If either array is null, returns null. If either array is empty, returns only those 12199 * elements in the other array. If both arrays are empty, returns a new empty array. 12200 */ 12201 @SideEffectFree 12202 public static @Interned String @PolyNull [] concat(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) { 12203 if (seq1 == null) { 12204 return null; 12205 } 12206 if (seq2 == null) { 12207 return null; 12208 } 12209 return ArraysPlume.concat(seq1, seq2); 12210 } 12211 12212 /** 12213 * Returns an array that is equivalent to the set union of seq1 and seq2. This method gives no 12214 * assurances about the order or repetition of elements: elements may be repeated, and their 12215 * order may be different from the order of elements in seq1 and seq2. 12216 */ 12217 @SideEffectFree 12218 public static @Interned String @PolyNull [] union(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) { 12219 if (seq1 == null) { 12220 return null; 12221 } 12222 if (seq2 == null) { 12223 return null; 12224 } 12225 return concat(seq1, seq2); 12226 } 12227 12228 /** 12229 * Returns an array that is equivalent to the set intersection of seq1 and seq2. This method 12230 * gives no assurances about the order or repetition of elements: elements may be repeated, and 12231 * their order may be different from the order of elements in seq1 and seq2. 12232 */ 12233 @Pure 12234 public static @Interned String @PolyNull [] intersection(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) { 12235 if (seq1 == null) { 12236 return null; 12237 } 12238 if (seq2 == null) { 12239 return null; 12240 } 12241 @Interned String[] intermediate = new @Interned String[Math.min(seq1.length, seq2.length)]; 12242 int length = 0; 12243 for (int i = 0 ; i < seq1.length ; i++) { 12244 if (memberOf(seq1[i], seq2) ) { 12245 intermediate[length++] = seq1[i]; 12246 } 12247 } 12248 return ArraysPlume.subarray(intermediate, 0, length); 12249 } 12250 12251 /** 12252 * Returns an array that is equivalent to the set difference of seq1 and seq2. This method gives 12253 * no assurances about the order or repetition of elements: elements may be repeated, and their 12254 * order may be different from the order of elements in seq1 and seq2. 12255 */ 12256 @Pure 12257 public static @Interned String @PolyNull [] setDiff(@Interned String @PolyNull [] seq1, @Interned String @PolyNull [] seq2) { 12258 if (seq1 == null) { 12259 return null; 12260 } 12261 if (seq2 == null) { 12262 return null; 12263 } 12264 @Interned String[] intermediate = new @Interned String[seq1.length]; 12265 int length = 0; 12266 for (int i = 0 ; i < seq1.length ; i++) { 12267 if (!memberOf(seq1[i], seq2)) { 12268 intermediate[length++] = seq1[i]; 12269 } 12270 } 12271 return ArraysPlume.subarray(intermediate, 0, length); 12272 } 12273 12274 /** Returns true iff seq1 and seq2 are equal when considered as sets. */ 12275 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12276 @Pure 12277 public static boolean setEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) { 12278 if (seq1 == null) { 12279 return false; 12280 } 12281 if (seq2 == null) { 12282 return false; 12283 } 12284 for (int i = 0; i < seq1.length ; i++) { 12285 if (!memberOf(seq1[i], seq2) ) { 12286 return false; 12287 } 12288 } 12289 for (int i = 0; i < seq2.length ; i++) { 12290 if (!memberOf(seq2[i], seq1) ) { 12291 return false; 12292 } 12293 } 12294 return true; 12295 } 12296 12297 /** True iff seq1 is the reverse of seq2. 12298 * 12299 * Meaning (in pseudo-FOL): 12300 * 12301 * <pre> 12302 * /\ seq1.length == seq2.length 12303 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[seq2.length-1-i] 12304 * </pre> 12305 * 12306 */ 12307 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12308 @Pure 12309 public static boolean isReverse(@Interned String[] seq1, @Interned String[] seq2) { 12310 if (!sameLength(seq1, seq2)) { 12311 return false; 12312 } 12313 assert seq1 != null && seq2 != null; // because sameLength() = true 12314 int length = seq1.length; 12315 for (int i = 0 ; i < length ; i++) { 12316 if (ne(seq1[i], seq2[length - i - 1])) { 12317 return false; 12318 } 12319 } 12320 return true; 12321 } 12322 12323 /** True iff seq1 is a subset of seq2, when the sequences are considered as sets. */ 12324 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12325 @Pure 12326 public static boolean subsetOf(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) { 12327 if (seq1 == null) { 12328 return false; 12329 } 12330 if (seq2 == null) { 12331 return false; 12332 } 12333 for (int i = 0 ; i < seq1.length ; i++) { 12334 if (!memberOf(seq1[i], seq2)) { 12335 return false; 12336 } 12337 } 12338 return true; 12339 } 12340 12341 /** Returns true iff seq contains no duplicate elements. */ 12342 @EnsuresNonNullIf(result=true, expression="#1") 12343 @Pure 12344 public static boolean noDups(@Interned String @Nullable [] seq) { 12345 if (seq == null) { 12346 return false; 12347 } 12348 return ArraysPlume.noDuplicates(seq); 12349 } 12350 12351 /** Returns true iff elt is in array arr. */ 12352 @EnsuresNonNullIf(result=true, expression="#2") 12353 @Pure 12354 public static boolean memberOf(@Interned String elt, @Interned String @Nullable [] arr) { 12355 if (arr == null) { 12356 return false; 12357 } 12358 for (int i = 0 ; i < arr.length ; i++) { 12359 if (eq(arr[i], elt)) { 12360 return true; 12361 } 12362 } 12363 return false; 12364 } 12365 12366 /** Returns a subsequence of seq with first elements seq[start] and last element seq[end]. */ 12367 @Pure 12368 public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, int start, int end) { 12369 if (seq == null) { 12370 return null; 12371 } 12372 int sliceStart = start; 12373 int sliceEnd = end; 12374 if (start < 0) { 12375 return new @Interned String[] { }; 12376 } 12377 if (end > seq.length - 1) { 12378 return new @Interned String[] { }; 12379 } 12380 if (sliceStart > sliceEnd) { 12381 return new @Interned String[] { }; 12382 } 12383 int length = sliceEnd - sliceStart + 1; 12384 return ArraysPlume.subarray(seq, sliceStart, length); 12385 } 12386 12387 @Pure 12388 public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, long start, int end) { 12389 return slice(seq, (int)start, end); 12390 } 12391 @Pure 12392 public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, int start, long end) { 12393 return slice(seq, start, (int)end); 12394 } 12395 @Pure 12396 public static @Interned String @PolyNull [] slice(@Interned String @PolyNull [] seq, long start, long end) { 12397 return slice(seq, (int)start, (int)end); 12398 } 12399 12400 /** True iff all elements in arr equal elt. 12401 * 12402 * Meaning (in pseudo-FOL): 12403 * 12404 * forall i in { 0..arr.length-1 } : arr[i] == elt 12405 * 12406 */ 12407 @EnsuresNonNullIf(result=true, expression="#1") 12408 @Pure 12409 public static boolean eltsEqual(@Interned String @Nullable [] arr, @Interned String elt) { 12410 if (arr == null) { 12411 return false; 12412 } 12413 for (int i = 0 ; i < arr.length ; i++) { 12414 if (ne(arr[i], elt)) { 12415 return false; 12416 } 12417 } 12418 return true; 12419 } 12420 12421 /** True iff every element in arr does not equal elt. 12422 * 12423 * Meaning (in pseudo-FOL): 12424 * 12425 * forall i in { 0..arr.length-1 } : arr[i] != elt 12426 * 12427 */ 12428 @EnsuresNonNullIf(result=true, expression="#1") 12429 @Pure 12430 public static boolean eltsNotEqual(@Interned String @Nullable [] arr, @Interned String elt) { 12431 if (arr == null) { 12432 return false; 12433 } 12434 for (int i = 0 ; i < arr.length ; i++) { 12435 if (eq(arr[i], elt)) { 12436 return false; 12437 } 12438 } 12439 return true; 12440 } 12441 12442 /** True iff seq1 and seq2 have the same length, and every seq1[i] == seq2[i]. 12443 * 12444 * Meaning (in pseudo-FOL): 12445 * 12446 * /\ seq1.length == se2.length 12447 * /\ forall i in { 0..seq1.length-1 } : seq1[i] == seq2[i] 12448 * 12449 */ 12450 12451 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12452 @Pure 12453 public static boolean pairwiseEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) { 12454 if (!sameLength(seq1, seq2)) { 12455 return false; 12456 } 12457 assert seq1 != null && seq2 != null; // because sameLength() = true 12458 for (int i = 0 ; i < seq1.length ; i++) { 12459 if (ne(seq1[i], seq2[i])) { 12460 return false; 12461 } 12462 } 12463 return true; 12464 } 12465 12466 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12467 @Pure 12468 public static boolean pairwiseEqual(@Nullable AbstractCollection<@Interned String> seq1, @Interned String @Nullable [] seq2) { 12469 if (seq1 == null) { 12470 return false; 12471 } 12472 if (seq2 == null) { 12473 return false; 12474 } 12475 @SuppressWarnings("cast") // cast is redundant (except in JSR 308) 12476 @Interned String[] seq1a = (@Interned String[]) seq1.toArray(new @Interned String[0]); 12477 return pairwiseEqual(seq1a, seq2); 12478 } 12479 12480 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12481 @Pure 12482 public static boolean pairwiseEqual(@Interned String @Nullable [] seq1, @Nullable AbstractCollection<@Interned String> seq2) { 12483 if (seq1 == null) { 12484 return false; 12485 } 12486 if (seq2 == null) { 12487 return false; 12488 } 12489 @SuppressWarnings("cast") // cast is redundant (except in JSR 308) 12490 @Interned String[] seq2a = (@Interned String[]) seq2.toArray(); 12491 return pairwiseEqual(seq1, seq2a); 12492 } 12493 12494 /** True iff seq1 and seq2 have the same length, and every seq1[i] != seq2[i]. 12495 * 12496 * Meaning (in pseudo-FOL): 12497 * 12498 * /\ seq1.length == se2.length 12499 * /\ forall i in { 0..seq1.length-1 } : seq1[i] != seq2[i] 12500 * 12501 */ 12502 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12503 @Pure 12504 public static boolean pairwiseNotEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) { 12505 if (!sameLength(seq1, seq2)) { 12506 return false; 12507 } 12508 assert seq1 != null && seq2 != null; // because sameLength() = true 12509 for (int i = 0 ; i < seq1.length ; i++) { 12510 if (eq(seq1[i], seq2[i])) { 12511 return false; 12512 } 12513 } 12514 return true; 12515 } 12516 12517 /** 12518 * Returns true iff seq1 is lexically equal to seq2. 12519 * For equality, "lexically" and "pairwise" are the same. 12520 */ 12521 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12522 @Pure 12523 public static boolean lexEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) { 12524 if (seq1 == null) { 12525 return false; 12526 } 12527 if (seq2 == null) { 12528 return false; 12529 } 12530 return pairwiseEqual(seq1, seq2); 12531 } 12532 12533 /** Returns true iff seq1 is lexically not equal to seq2. */ 12534 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12535 @Pure 12536 public static boolean lexNotEqual(@Interned String @Nullable [] seq1, @Interned String @Nullable [] seq2) { 12537 if (seq1 == null) { 12538 return false; 12539 } 12540 if (seq2 == null) { 12541 return false; 12542 } 12543 return !lexEqual(seq1, seq2); 12544 } 12545 12546 /** True iff for all applicable i, every seq[i] == seq[i+1]. 12547 * 12548 * Meaning (in pseudo-FOL): 12549 * 12550 * forall i in { 0..seq.length-2 } : seq[i] == seq[i+1] 12551 * 12552 */ 12553 @EnsuresNonNullIf(result=true, expression="#1") 12554 @Pure 12555 public static boolean eltwiseEqual(@Interned String @Nullable [] seq) { 12556 if (seq == null) { 12557 return false; 12558 } 12559 for (int i = 0 ; i < seq.length ; i++) { 12560 if (i < seq.length - 1) { 12561 if (ne(seq[i], seq[i + 1])) { 12562 return false; 12563 } 12564 } 12565 } 12566 return true; 12567 } 12568 12569 /** True iff for all applicable i, every seq[i] != seq[i+1]. 12570 * 12571 * Meaning (in pseudo-FOL): 12572 * 12573 * forall i in { 0..seq.length-2 } : seq[i] != seq[i+1] 12574 * 12575 */ 12576 @EnsuresNonNullIf(result=true, expression="#1") 12577 @Pure 12578 public static boolean eltwiseNotEqual(@Interned String @Nullable [] seq) { 12579 if (seq == null) { 12580 return false; 12581 } 12582 for (int i = 0 ; i < seq.length ; i++) { 12583 if (i < seq.length - 1) { 12584 if (eq(seq[i], seq[i + 1])) { 12585 return false; 12586 } 12587 } 12588 } 12589 return true; 12590 } 12591 12592 /// Deferencing (accessing) fields 12593 12594 /** 12595 * collectString accepts an object and a list of fields (one of which is of array type, and the 12596 * rest of which are not), and produces an array in which the original object has had the given 12597 * fields accessed. 12598 * 12599 * <p>Daikon creates invariants over "variables" such as the following. 12600 * 12601 * <dl> 12602 * <dt>x.arr[].z</dt> <dd>The result of collecting all elements y.z 12603 * for all y's in array x.arr.</dd> 12604 * <dt>arr[].y.z</dt> <dd>The result of collecting all elements x.y.z 12605 * for all x's in array arr.</dd> 12606 * <dt>x.y.z[]</dt> <dd>The result of collecting all elements in array x.y.z[]</dd> 12607 * </dl> 12608 * 12609 * <p>The collectString() method does this collecting work. 12610 * 12611 * <p>Given an object (x, arr, or x, correspondingly, in the above examples) and a "field string" 12612 * (arr.z, y.z, or y.z, correspondingly, in the above example), the collect method collects the 12613 * elements that result from following the fields, one of which is assumed to be an array. 12614 * 12615 * <p> 12616 * requires: fieldStr.length() > 0 and object != null 12617 * <p> 12618 * requires: fieldStr contains only field names, no "[]" strings. 12619 * <p> 12620 * requires: the method only works for field sequences with exactly one field representing an 12621 * array. For example, the collection a[].b[].c will fail. 12622 * 12623 * @return if the resulting collection is of non-primitive type, then returns an array of type 12624 * Object[]. Returns null if any array or field access causes an exception. 12625 */ 12626 12627 @SuppressWarnings("interning") // reflection 12628 12629 @SideEffectFree 12630 public static String @Nullable [] collectString(@Nullable Object object, @Nullable String fieldStr) { 12631 12632 if (object == null) { 12633 return null; 12634 } 12635 if (fieldStr == null) { 12636 return null; 12637 } 12638 12639 // assert fieldStr != null && !"".equals(fieldStr); 12640 String[] fieldNames = fieldStr.split("\\."); 12641 @Interned String[] retval = collectString(object, fieldNames, 0); 12642 // System.err.println("%%% fieldArray returned: " + plume.Arrays.toString(retval)); 12643 return retval; 12644 } 12645 12646 @SuppressWarnings("interning") // reflection 12647 12648 /** Helper method for collectString(Object, String). 12649 * Operates on a subset of the fields: those in fields[fieldsStartIdx..]. 12650 * @see collectString(Object, String) 12651 */ 12652 // @PolyNull does not work for return type, because null is returned on error. 12653 @SideEffectFree 12654 private static String @Nullable [] collectString(@Nullable Object object, 12655 String[] fields, int fieldsStartIdx) { 12656 12657 if (object == null) { 12658 return null; 12659 } 12660 assert (fields != null); 12661 assert (fieldsStartIdx >= 0 && fieldsStartIdx < fields.length); 12662 12663 Object fieldObj; 12664 try { 12665 Field field = (object instanceof java.lang.Class<?>) 12666 ? ((Class<?>)object).getDeclaredField(fields[fieldsStartIdx]) 12667 : object.getClass().getDeclaredField(fields[fieldsStartIdx]); 12668 field.setAccessible(true); 12669 // Class cls = field.getType(); 12670 fieldObj = field.get(object); 12671 // System.out.println("***fieldObj="+fieldObj); 12672 12673 } catch (Exception e) { 12674 return null; 12675 12676 } 12677 12678 if (fieldObj == null) { 12679 return null; 12680 } 12681 12682 // base case: just accessed the last field 12683 if (fields.length - 1 == fieldsStartIdx) { 12684 12685 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 12686 // last field is the collection 12687 @SuppressWarnings("unchecked") 12688 java.util.AbstractCollection<@Interned String> ac = (java.util.AbstractCollection<@Interned String>)fieldObj; 12689 return ac.toArray(new @Interned String[]{}); 12690 } else 12691 12692 if (fieldObj.getClass().isArray()) { 12693 // last field is an array 12694 return (@Interned String[])fieldObj; 12695 } else { 12696 // This hack should be removed in favor of, at "oneEltArray = ..." 12697 // below, calling a version of collectString_field that throws an 12698 // error. Then, this case becomes a run-time error. -MDE 12699 12700 // Just one element; return a one-element array. 12701 // assert cls.equals(_TYPE_WRAPPER_NAME.TYPE); 12702 return new @Interned String[] { (String)fieldObj }; 12703 } 12704 } else { 12705 // recursive case: more fields to access after this one 12706 12707 if (daikon.ProglangType.list_implementors.contains(fieldObj.getClass().getName())) { 12708 12709 java.util.AbstractCollection<? extends Object> collection = (java.util.AbstractCollection<? extends Object>)fieldObj; 12710 @Interned String[] intermediate = new @Interned String[collection.size()]; 12711 int index = 0; 12712 for (Iterator<? extends Object> i = collection.iterator() ; i.hasNext() ; ) { 12713 Object obj = i.next(); 12714 String[] oneEltArray = collectString(obj, fields, fieldsStartIdx + 1); 12715 if (oneEltArray == null) { 12716 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 12717 } 12718 // assert oneEltArray.length == 1; 12719 intermediate[index++] = oneEltArray[0]; 12720 } 12721 return intermediate; 12722 } else if (fieldObj.getClass().isArray()) { 12723 12724 // collect elements across array 12725 @Interned String[] intermediate = new @Interned String[Array.getLength(fieldObj)]; 12726 for (int i = 0 ; i < intermediate.length ; i++) { 12727 Object obj = Array.get(fieldObj, i); 12728 String[] oneEltArray = collectString(obj, fields, fieldsStartIdx + 1); 12729 if (oneEltArray == null) { 12730 throw new Error("bad fields: " + (obj == null ? "null" : obj.getClass()) + " " + Arrays.toString(fields) + " " + (fieldsStartIdx + 1)); 12731 } 12732 // assert oneEltArray.length == 1; 12733 intermediate[i] = oneEltArray[0]; 12734 } 12735 return intermediate; 12736 } else { 12737 12738 return collectString(fieldObj, fields, fieldsStartIdx + 1); 12739 } 12740 } 12741 } 12742 12743 /** 12744 * Returns the results of dereferencing the fields for 'object'. For example, the call 12745 * 12746 * <pre>collectString_field(x, "f.g.h")</pre> 12747 * 12748 * has the same value as 12749 * 12750 * <pre>x.f.g.h</pre>. 12751 * Returns a default value if any field access causes an exception. 12752 */ 12753 @SideEffectFree 12754 public static @Nullable String collectString_field(Object object, String fieldStr) { 12755 12756 if (object == null) { 12757 return null; // return default value 12758 } 12759 if (fieldStr == null) { 12760 return null; // return default value 12761 } 12762 12763 String[] fieldNames = fieldStr.split("\\."); 12764 12765 // Holds the intermediate (and final) result 12766 Object fieldObj = object; 12767 12768 for (int i = 0 ; i < fieldNames.length ; i++) { 12769 12770 String fieldName = fieldNames[i]; 12771 12772 try { 12773 Field field = 12774 (fieldObj instanceof java.lang.Class<?>) 12775 ? ((Class<?>)fieldObj).getDeclaredField(fieldName) 12776 : fieldObj.getClass().getDeclaredField(fieldName); 12777 field.setAccessible(true); 12778 fieldObj = field.get(fieldObj); 12779 12780 if (fieldObj == null) { 12781 return null; // return default value 12782 } 12783 12784 } catch (Exception e) { 12785 return null; // return default value 12786 12787 } 12788 12789 } 12790 12791 return (String)fieldObj; 12792 } 12793 12794 /////////////////////////////////////////////////////////////////////////// 12795 /// Collection methods (dispatch to array methods) 12796 // 12797 12798 // These methods handle calls to quant methods that instead of passing an 12799 // Object[] array, pass a Collection. Each method handles arrays or 12800 // Collections. They convert any Collection to an array, then invoke the 12801 // Object[] version of the method. 12802 12803 /** 12804 * See {@link #noDups(Object[])}. 12805 * @see #noDups(Object[]) 12806 */ 12807 @SuppressWarnings("interning") // cast from Object 12808 @EnsuresNonNullIf(result=true, expression="#1") 12809 @Pure 12810 public static boolean noDups(Object seq) { 12811 if (seq == null) { 12812 return false; 12813 } 12814 return noDups(toObjArray(seq)); 12815 } 12816 12817 /** 12818 * See {@link #typeArray(Object[])}. 12819 * @see #typeArray(Object[]) 12820 */ 12821 @SuppressWarnings("interning") // cast from Object 12822 /*TODO: @AssertNonNullIfNonNull({"#1"})*/ 12823 /* pure */ public static String @PolyNull [] typeArray(@PolyNull Object seq) { 12824 if (seq == null) { 12825 return null; 12826 } 12827 return typeArray(toObjArray(seq)); 12828 } 12829 12830 /** 12831 * See {@link #eltwiseEqual(Object[])}. 12832 * @see #eltwiseEqual(Object[]) 12833 */ 12834 @SuppressWarnings("interning") // cast from Object 12835 @EnsuresNonNullIf(result=true, expression="#1") 12836 @Pure 12837 public static boolean eltwiseEqual(Object seq) { 12838 if (seq == null) { 12839 return false; 12840 } 12841 return eltwiseEqual(toObjArray(seq)); 12842 } 12843 12844 /** 12845 * See {@link #eltwiseNotEqual(Object[])}. 12846 * @see #eltwiseNotEqual(Object[]) 12847 */ 12848 @SuppressWarnings("interning") // cast from Object 12849 @EnsuresNonNullIf(result=true, expression="#1") 12850 @Pure 12851 public static boolean eltwiseNotEqual(Object seq) { 12852 if (seq == null) { 12853 return false; 12854 } 12855 return eltwiseNotEqual(toObjArray(seq)); 12856 } 12857 12858 /** 12859 * See {@link #concat(Object[], Object[])}. 12860 * @see #concat(Object[], Object[]) 12861 */ 12862 @SuppressWarnings("interning") // cast from Object 12863 /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/ 12864 @SideEffectFree 12865 public static java.lang.Object @PolyNull [] concat(@PolyNull Object seq1, @PolyNull Object seq2) { 12866 if (seq1 == null) { 12867 return null; 12868 } 12869 if (seq2 == null) { 12870 return null; 12871 } 12872 return concat(toObjArray(seq1), toObjArray(seq2)); 12873 } 12874 12875 /** 12876 * See {@link #union(Object[], Object[])}. 12877 * @see #union(Object[], Object[]) 12878 */ 12879 @SuppressWarnings("interning") // cast from Object 12880 /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/ 12881 @SideEffectFree 12882 public static java.lang.Object @PolyNull [] union(@PolyNull Object seq1, @PolyNull Object seq2) { 12883 if (seq1 == null) { 12884 return null; 12885 } 12886 if (seq2 == null) { 12887 return null; 12888 } 12889 return union(toObjArray(seq1), toObjArray(seq2)); 12890 } 12891 12892 /** 12893 * See {@link #intersection(Object[], Object[])}. 12894 * @see #intersection(Object[], Object[]) 12895 */ 12896 @SuppressWarnings("interning") // cast from Object 12897 /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/ 12898 @SideEffectFree 12899 public static java.lang.Object @PolyNull [] intersection(@PolyNull Object seq1, @PolyNull Object seq2) { 12900 if (seq1 == null) { 12901 return null; 12902 } 12903 if (seq2 == null) { 12904 return null; 12905 } 12906 return intersection(toObjArray(seq1), toObjArray(seq2)); 12907 } 12908 12909 /** 12910 * See {@link #setDiff(Object[], Object[])}. 12911 * @see #setDiff(Object[], Object[]) 12912 */ 12913 @SuppressWarnings("interning") // cast from Object 12914 /*TODO: @AssertNonNullIfNonNull({"#1","#2"})*/ 12915 @SideEffectFree 12916 public static java.lang.Object @PolyNull [] setDiff(@PolyNull Object seq1, @PolyNull Object seq2) { 12917 if (seq1 == null) { 12918 return null; 12919 } 12920 if (seq2 == null) { 12921 return null; 12922 } 12923 return setDiff(toObjArray(seq1), toObjArray(seq2)); 12924 } 12925 12926 /** 12927 * See {@link #setEqual(Object[], Object[])}. 12928 * @see #setEqual(Object[], Object[]) 12929 */ 12930 @SuppressWarnings("interning") // cast from Object 12931 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12932 @Pure 12933 public static boolean setEqual(@Nullable Object seq1, @Nullable Object seq2) { 12934 if (seq1 == null) { 12935 return false; 12936 } 12937 if (seq2 == null) { 12938 return false; 12939 } 12940 return setEqual(toObjArray(seq1), toObjArray(seq2)); 12941 } 12942 12943 /** 12944 * See {@link #isReverse(Object[], Object[])}. 12945 * @see #isReverse(Object[], Object[]) 12946 */ 12947 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12948 @SuppressWarnings("interning") // cast from Object 12949 @Pure 12950 public static boolean isReverse(@Nullable Object seq1, @Nullable Object seq2) { 12951 if (seq1 == null) { 12952 return false; 12953 } 12954 if (seq2 == null) { 12955 return false; 12956 } 12957 return isReverse(toObjArray(seq1), toObjArray(seq2)); 12958 } 12959 12960 /** 12961 * See {@link #pairwiseEqual(Object[], Object[])}. 12962 * @see #pairwiseEqual(Object[], Object[]) 12963 */ 12964 @SuppressWarnings("interning") // cast from Object 12965 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12966 @Pure 12967 public static boolean pairwiseEqual(@Nullable Object seq1, @Nullable Object seq2) { 12968 if (seq1 == null) { 12969 return false; 12970 } 12971 if (seq2 == null) { 12972 return false; 12973 } 12974 return pairwiseEqual(toObjArray(seq1), toObjArray(seq2)); 12975 } 12976 12977 /** 12978 * See {@link #pairwiseNotEqual(Object[], Object[])}. 12979 * @see #pairwiseNotEqual(Object[], Object[]) 12980 */ 12981 @SuppressWarnings("interning") // cast from Object 12982 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 12983 @Pure 12984 public static boolean pairwiseNotEqual(@Nullable Object seq1, @Nullable Object seq2) { 12985 if (seq1 == null) { 12986 return false; 12987 } 12988 if (seq2 == null) { 12989 return false; 12990 } 12991 return pairwiseNotEqual(toObjArray(seq1), toObjArray(seq2)); 12992 } 12993 12994 /** 12995 * See {@link #lexEqual(Object[], Object[])}. 12996 * @see #lexEqual(Object[], Object[]) 12997 */ 12998 @SuppressWarnings("interning") // cast from Object 12999 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 13000 @Pure 13001 public static boolean lexEqual(@Nullable Object seq1, @Nullable Object seq2) { 13002 if (seq1 == null) { 13003 return false; 13004 } 13005 if (seq2 == null) { 13006 return false; 13007 } 13008 return lexEqual(toObjArray(seq1), toObjArray(seq2)); 13009 } 13010 13011 /** 13012 * See {@link #lexNotEqual(Object[], Object[])}. 13013 * @see #lexNotEqual(Object[], Object[]) 13014 */ 13015 @SuppressWarnings("interning") // cast from Object 13016 @EnsuresNonNullIf(result=true, expression={"#1","#2"}) 13017 @Pure 13018 public static boolean lexNotEqual(@Nullable Object seq1, @Nullable Object seq2) { 13019 if (seq1 == null) { 13020 return false; 13021 } 13022 if (seq2 == null) { 13023 return false; 13024 } 13025 return lexNotEqual(toObjArray(seq1), toObjArray(seq2)); 13026 } 13027 13028 /** 13029 * See {@link #memberOf(Object, Object[])}. 13030 * @see #memberOf(Object, Object[]) 13031 */ 13032 @SuppressWarnings("interning") // cast from Object 13033 @EnsuresNonNullIf(result=true, expression="#2") 13034 @Pure 13035 public static boolean memberOf(Object elt, @Nullable Object arr) { 13036 if (arr == null) { 13037 return false; 13038 } 13039 return memberOf(elt, toObjArray(arr)); 13040 } 13041 13042 /** 13043 * See {@link #slice(Object[], int, int)}. 13044 * @see #slice(Object[], int, int) 13045 */ 13046 @SuppressWarnings("interning") // cast from Object 13047 /*TODO: @AssertNonNullIfNonNull("#1")*/ 13048 @SideEffectFree 13049 public static Object @PolyNull [] slice(@PolyNull Object seq, int start, int end) { 13050 if (seq == null) { 13051 return null; 13052 } 13053 return slice(toObjArray(seq), start, end); 13054 } 13055 13056 /** 13057 * See {@link #eltsEqual(Object[], Object)}. 13058 * @see #eltsEqual(Object[], Object) 13059 */ 13060 @SuppressWarnings("interning") // cast from Object 13061 @EnsuresNonNullIf(result=true, expression="#1") 13062 @Pure 13063 public static boolean eltsEqual(@Nullable Object arr, Object elt) { 13064 if (arr == null) { 13065 return false; 13066 } 13067 return eltsEqual(toObjArray(arr), elt); 13068 } 13069 13070 /** 13071 * See {@link #eltsNotEqual(Object[], Object)}. 13072 * @see #eltsNotEqual(Object[], Object) 13073 */ 13074 @SuppressWarnings("interning") // cast from Object 13075 @EnsuresNonNullIf(result=true, expression="#1") 13076 @Pure 13077 public static boolean eltsNotEqual(@Nullable Object arr, Object elt) { 13078 if (arr == null) { 13079 return false; 13080 } 13081 return eltsNotEqual(toObjArray(arr), elt); 13082 } 13083 13084 @EnsuresNonNullIf(result=true, expression="#1") 13085 @Pure 13086 public static boolean isIntegralType(@Nullable Class<?> c) { 13087 if (c == null) { 13088 return false; 13089 } 13090 return 13091 (c.equals(Byte.TYPE) 13092 || c.equals(Short.TYPE) 13093 || c.equals(Integer.TYPE) 13094 || c.equals(Long.TYPE)); 13095 } 13096 13097 @EnsuresNonNullIf(result=true, expression="#1") 13098 @Pure 13099 public static boolean isRealType(@Nullable Class<?> c) { 13100 if (c == null) { 13101 return false; 13102 } 13103 return 13104 (c.equals(Float.TYPE) 13105 || c.equals(Double.TYPE)); 13106 } 13107 13108 @EnsuresNonNullIf(result=true, expression="#1") 13109 @Pure 13110 public static boolean isNumericType(Class<?> c) { 13111 if (c == null) { 13112 return false; 13113 } 13114 return isIntegralType(c) || isRealType(c); 13115 } 13116 13117 /** Returns an Object[] array, either by casting or by conversion from an 13118 * AbstractCollection. 13119 */ 13120 /*TODO: @AssertNonNullIfNonNull("#1")*/ 13121 public static Object @PolyNull [] toObjArray(@PolyNull Object o) { 13122 if (o == null) { 13123 return null; 13124 } 13125 if (o instanceof java.util.AbstractCollection<?>) { 13126 @SuppressWarnings({"unchecked"}) 13127 AbstractCollection<Object> ac = (AbstractCollection<Object>)o; 13128 Object [] result = ac.toArray(new java.lang.Object []{}); 13129 return result; 13130 } else if (o.getClass().isArray()) { 13131 return (Object[])o; 13132 } else { 13133 throw new IllegalArgumentException("not an array or collection: " + o); 13134 } 13135 } 13136}