| 1 | /*
|
|---|
| 2 | Author: Yihao Yan
|
|---|
| 3 |
|
|---|
| 4 | Download LCP.zip from: http://fm2012.verifythis.org/challenges
|
|---|
| 5 |
|
|---|
| 6 | -----------------
|
|---|
| 7 | Problem decription:
|
|---|
| 8 |
|
|---|
| 9 | Longest Common Prefix (LCP)
|
|---|
| 10 | Input: an integer array X1[n], and two indices x and y into this array
|
|---|
| 11 | Output: length of the longest common prefix of the subarrays of a
|
|---|
| 12 | starting at x and y respectively.
|
|---|
| 13 |
|
|---|
| 14 | -----------------
|
|---|
| 15 | Verification task:
|
|---|
| 16 |
|
|---|
| 17 | Implement the lcp function, and verify that it behaves in the way described above.
|
|---|
| 18 |
|
|---|
| 19 | -----------------
|
|---|
| 20 | Result:
|
|---|
| 21 |
|
|---|
| 22 | For arrays with length less than 5, lcp function returns an integer n which is
|
|---|
| 23 | the length of the longest common prefix between its two suffixes: The two suffixes
|
|---|
| 24 | are the same with indexes from 0 to n-1 while they are different at index n. Therefore
|
|---|
| 25 | the lcp function behave correctly.
|
|---|
| 26 |
|
|---|
| 27 | -----------------
|
|---|
| 28 | command: civl verify lcp.c
|
|---|
| 29 | */
|
|---|
| 30 |
|
|---|
| 31 | #include <civlc.cvh>
|
|---|
| 32 | #pragma CIVL ACSL
|
|---|
| 33 | $input int n, x, y;
|
|---|
| 34 | $assume (0 <= x && x < n && 0 <= y && y < n && 0 < n);
|
|---|
| 35 | $input int X1[n];
|
|---|
| 36 |
|
|---|
| 37 | int lcp(int *arr, int n, int x, int y){
|
|---|
| 38 | int l = 0;
|
|---|
| 39 |
|
|---|
| 40 | /*@ loop invariant 0 <= l && l <= n;
|
|---|
| 41 | @ loop invariant 0 <= x + l && x + l <= n;
|
|---|
| 42 | @ loop invariant 0 <= y + l && y + l <= n;
|
|---|
| 43 | @ loop invariant \forall int i; 0 <= i && i < l ==> arr[x+i]==arr[y+i];
|
|---|
| 44 | @*/
|
|---|
| 45 | while (x+l<n && y+l<n && arr[x+l]==arr[y+l])
|
|---|
| 46 | l++;
|
|---|
| 47 | return l;
|
|---|
| 48 | }
|
|---|
| 49 |
|
|---|
| 50 | void main(){
|
|---|
| 51 | int result = lcp(X1, n, x, y);
|
|---|
| 52 |
|
|---|
| 53 | $assert($forall (int i: 0 .. result-1) X1[x+i] == X1[y+i]);
|
|---|
| 54 | $assert(
|
|---|
| 55 | (x + result < n && y + result < n) => X1[x+result] != X1[y+result]
|
|---|
| 56 | );
|
|---|
| 57 | }
|
|---|