| 1 | #include<string.h>
|
|---|
| 2 |
|
|---|
| 3 | #pragma CIVL ACSL
|
|---|
| 4 |
|
|---|
| 5 | $input int n;
|
|---|
| 6 | $assume(n > 0);
|
|---|
| 7 | int t[n];
|
|---|
| 8 | int pre_t[n];
|
|---|
| 9 |
|
|---|
| 10 | /*@ predicate Sorted(int *a, integer l, integer h) =
|
|---|
| 11 | @ \forall int i,j; l <= i <= j < h ==> a[i] <= a[j];
|
|---|
| 12 | @
|
|---|
| 13 | @ predicate permut(int * a, int * b, int l, int h);
|
|---|
| 14 | @
|
|---|
| 15 | @*/
|
|---|
| 16 |
|
|---|
| 17 | void swap(int t[], int i, int j) {
|
|---|
| 18 | int tmp = t[i];
|
|---|
| 19 | t[i] = t[j];
|
|---|
| 20 | t[j] = tmp;
|
|---|
| 21 | }
|
|---|
| 22 |
|
|---|
| 23 | void min_sort() {
|
|---|
| 24 | int i,j;
|
|---|
| 25 | int mi,mv;
|
|---|
| 26 |
|
|---|
| 27 | if (n <= 0)
|
|---|
| 28 | return;
|
|---|
| 29 | /*@ loop invariant 0 <= i < n;
|
|---|
| 30 | @ loop invariant
|
|---|
| 31 | @ Sorted(t,0,i) &&
|
|---|
| 32 | @ (\forall int k1, k2 ;
|
|---|
| 33 | @ 0 <= k1 < i <= k2 < n ==> t[k1] <= t[k2]) ;
|
|---|
| 34 | @ loop invariant permut(t, pre_t, 0, n);
|
|---|
| 35 | @ loop assigns i, mi, mv, j, t[0 .. n-1];
|
|---|
| 36 | @*/
|
|---|
| 37 | for (i=0; i<n-1; i++) {
|
|---|
| 38 | // look for minimum value among t[i..n-1]
|
|---|
| 39 | mv = t[i]; mi = i;
|
|---|
| 40 | /*@ loop invariant i < j && i <= mi < n;
|
|---|
| 41 | @ loop invariant
|
|---|
| 42 | @ mv == t[mi] &&
|
|---|
| 43 | @ (\forall int k; i <= k < j ==> t[k] >= mv);
|
|---|
| 44 | @ loop invariant
|
|---|
| 45 | @ permut(t, pre_t, 0, n);
|
|---|
| 46 | @ loop assigns mi, mv, j;
|
|---|
| 47 | @*/
|
|---|
| 48 | for (j=i+1; j < n; j++) {
|
|---|
| 49 | if (t[j] < mv) {
|
|---|
| 50 | mi = j ; mv = t[j];
|
|---|
| 51 | }
|
|---|
| 52 | }
|
|---|
| 53 | swap(t,i,mi);
|
|---|
| 54 | }
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | int main() {
|
|---|
| 58 | $havoc(&t);
|
|---|
| 59 | memcpy(pre_t, t, sizeof(int) * n);
|
|---|
| 60 | min_sort();
|
|---|
| 61 | //@ assert permut(t, pre_t, 0, n) && Sorted(t, 0, n);
|
|---|
| 62 | }
|
|---|