| 1 | /*@ predicate
|
|---|
| 2 | @ IsSubArray{S}(int * a, integer offset, int * b, integer m) =
|
|---|
| 3 | @ m >= 0 && (\forall integer i; 0 <= i < m ==> a[offset + i] == b[i]);
|
|---|
| 4 | @*/
|
|---|
| 5 |
|
|---|
| 6 | /*@ requires \valid(a + (0 .. m-1)) && \valid(b + (0 .. m-1));
|
|---|
| 7 | @ requires m >= 0;
|
|---|
| 8 | @ assigns \nothing;
|
|---|
| 9 | @ ensures \result <==> IsSubArray{Here}(a, 0, b, m);
|
|---|
| 10 | @*/
|
|---|
| 11 | _Bool equals(int *a, int * b, int m) {
|
|---|
| 12 | /*@ loop invariant 0 <= i <= m;
|
|---|
| 13 | @ loop invariant IsSubArray(a, 0, b, i);
|
|---|
| 14 | @ loop assigns i;
|
|---|
| 15 | @ loop variant m - i;
|
|---|
| 16 | @*/
|
|---|
| 17 | for (int i = 0; i < m; i++)
|
|---|
| 18 | if (a[i] != b[i])
|
|---|
| 19 | return 0;
|
|---|
| 20 | return 1;
|
|---|
| 21 | }
|
|---|
| 22 |
|
|---|
| 23 | /*@ requires \valid(a + (0 .. n-1)) && \valid(b + (0 .. m-1));
|
|---|
| 24 | @ requires n >= 0 && m >= 0;
|
|---|
| 25 | @ assigns \nothing;
|
|---|
| 26 | @ ensures \result != n ==> IsSubArray{Here}(a, \result, b, m);
|
|---|
| 27 | @ ensures (\forall integer i1; 0 <= i1 <= n-m ==> !IsSubArray{Here}(a, i1, b, m)) ==> \result == n;
|
|---|
| 28 | @ ensures 0 <= \result <= n;
|
|---|
| 29 | @*/
|
|---|
| 30 | int search(int *a, int n, int *b, int m) {
|
|---|
| 31 | int i;
|
|---|
| 32 |
|
|---|
| 33 | if (n < m)
|
|---|
| 34 | return n;
|
|---|
| 35 | /*@ loop invariant 0 <= i <= n-m+1;
|
|---|
| 36 | @ loop invariant \forall integer i1; 0 <= i1 < i ==> !IsSubArray{Here}(a, i1, b, m);
|
|---|
| 37 | @ loop assigns i;
|
|---|
| 38 | @ loop variant n - m - i;
|
|---|
| 39 | @*/
|
|---|
| 40 | for (i = 0; i <= n - m; i++)
|
|---|
| 41 | if (equals(a+i, b, m))
|
|---|
| 42 | return i;
|
|---|
| 43 | return n;
|
|---|
| 44 | }
|
|---|