祝大家有美好的一天!我写了Shell排序验证码,但是我无法构建正确的循环不变量。无法正确组合不变量并证明程序的正确性...请帮助我!
/*@ predicate Sorted{L}(int* a, integer m, integer n) =
@ \forall integer i, j; m <= i <= j < n ==> a[i] <= a[j];
*/
/*@ predicate GapSorted(int* a, integer m, integer n, integer gap) =
@ \forall integer i, j; (m <= i <= j < n && j % gap == i % gap) ==> a[i] <=a[j];
*/
/*@
@ requires \valid(arr + (0..n-1));
@ requires n > 1;
@ ensures GapSorted(arr, 0, n, 1);
*/
void shell_lr(int *arr, int n) {
int i, j, tmp, gap;
/*@ ghost int gap1 = n
@ loop invariant 0 <= gap1 <= n/2;
@ loop invariant gap1 < n/2 ==> GapSorted(arr, 0, n, gap+1);
@ //loop invariant \forall integer k; gap < k <= n/2 ==> GapSorted(arr, 0, n, k);
@ loop variant gap1;
*/
for (gap = n / 2; gap > 0; gap--) {
/*@ loop invariant 0 <= i <= n;
@ //loop invariant \forall integer m; gap < m <= n/2 ==> GapSorted(arr, 0, i, m);
@ loop invariant GapSorted(arr, 0, i, gap);
@ loop variant n - i; */
for (i = gap; i < n; i++) {
tmp = arr[i];
/*@
@ loop invariant 0 <= j <= i;
@ //loop invariant arr[j] >= tmp;
@ loop invariant \forall integer k; (j < k <= i) ==> GapSorted(arr, 0, i, k);
@// loop invariant \forall integer k; j <= k <= gap ==> GapSorted(arr, k, i, gap);
@ loop variant j;
@*/
for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
arr[j] = arr[j - gap];
//@ assert arr[j] >= arr[j - gap];
//@ assert tmp < arr[j - gap];
}
//@ assert j>=0;
arr[j] = tmp;
}
//@ assert i == n;
//@ assert GapSorted(arr, 0, i, gap);
//@ assert gap > 0;
// assert GapSorted(arr, 0, n, gap);
}