/* Utility functions for working with arrays of integers * Mostly specification functions, but swap is effectful * * 15-122 Principles of Imperative Computation */ /*** Interface ***/ /* is_in: x in A[lo,hi) */ bool is_in(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ ; /* is_sorted: A[lo,hi) SORTED */ bool is_sorted(int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ ; /* swap(A, i, j) has the effect of switching A[i] and A[j] */ void swap(int[] A, int i, int j) /*@ requires 0 <= i && i < \length(A) && 0 <= j && j < \length(A); @*/ ; /* gt_seg: x > A[lo,hi) */ bool gt_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ ; /* ge_seg: x >= A[lo,hi) */ bool ge_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ ; /* lt_seg: x < A[lo,hi) */ bool lt_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ ; /* le_seg: x <= A[lo,hi) */ bool le_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ ; /* gt_segs: A[lo1,hi1) > B[lo2,hi2) */ bool gt_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) /*@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); @*/ /*@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); @*/ ; /* ge_segs: A[lo1,hi1) >= B[lo2,hi2) */ bool ge_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) /*@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); @*/ /*@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); @*/ ; /* lt_segs: A[lo1,hi1) < B[lo2,hi2) */ bool lt_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) /*@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); @*/ /*@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); @*/ ; /* le_segs: A[lo1,hi1) <= B[lo2,hi2) */ bool le_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) /*@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); @*/ /*@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); @*/ ; /*** Implementation ***/ bool is_in(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ { if (lo == hi) return false; return A[lo] == x || is_in(x,A,lo+1,hi); } void swap(int[] A, int i, int j) //@requires 0 <= i && i < \length(A); //@requires 0 <= j && j < \length(A); { int tmp = A[i]; A[i] = A[j]; A[j] = tmp; } bool gt_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ { if (lo == hi) return true; return x > A[lo] && gt_seg(x, A, lo+1, hi); } bool ge_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ { if (lo == hi) return true; return x >= A[lo] && ge_seg(x, A, lo+1, hi); } bool lt_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ { if (lo == hi) return true; return x < A[lo] && lt_seg(x, A, lo+1, hi); } bool le_seg(int x, int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ { if (lo == hi) return true; return x <= A[lo] && le_seg(x, A, lo+1, hi); } bool is_sorted(int[] A, int lo, int hi) /*@requires 0 <= lo && lo <= hi && hi <= \length(A); @*/ { if (lo == hi) return true; return le_seg(A[lo], A, lo+1, hi) && is_sorted(A, lo+1, hi); } bool gt_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) //@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); //@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); { if (lo1 == hi1) return true; return gt_seg(A[lo1], B, lo2, hi2) && gt_segs(A, lo1+1, hi1, B, lo2, hi2); } bool ge_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) //@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); //@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); { if (lo1 == hi1) return true; return ge_seg(A[lo1], B, lo2, hi2) && ge_segs(A, lo1+1, hi1, B, lo2, hi2); } bool lt_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) //@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); //@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); { if (lo1 == hi1) return true; return lt_seg(A[lo1], B, lo2, hi2) && lt_segs(A, lo1+1, hi1, B, lo2, hi2); } bool le_segs(int[] A, int lo1, int hi1, int[] B, int lo2, int hi2) //@requires 0 <= lo1 && lo1 <= hi1 && hi1 <= \length(A); //@requires 0 <= lo2 && lo2 <= hi2 && hi2 <= \length(B); { if (lo1 == hi1) return true; return le_seg(A[lo1], B, lo2, hi2) && le_segs(A, lo1+1, hi1, B, lo2, hi2); }