Sorting Shell排序算法循环不变量的验证?

Sorting Shell排序算法循环不变量的验证?,sorting,frama-c,shellsort,Sorting,Frama C,Shellsort,大家好!我写了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,

大家好!我写了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);
    }
/*@谓词排序{L}(int*a,整数m,整数n)=

@\对于所有整数i,j;首先,您提供的代码在语法上不正确:

  • 缺少关闭函数主体的大括号
  • gap1
    ghost
    声明不能与循环注释混合。这应该是两个不同的注释。无论如何,我看不到使用
    gap1
    (特别是因为它在循环中没有更新),任何东西都可以用
    gap
    表示。如果您试图实现的是为整个循环注释使用一个局部变量,那么这在ACSL中是不可能的:您有
    \let gap1=构造,但其范围仅为一个术语/谓词:不能跨两个
    循环不变量
    s(或
    循环不变量
    s和
    循环变量
    )共享它

现在,最紧迫的问题是循环注释中缺少
循环赋值。您必须为所有循环提供这样的子句,否则WP将无法在循环之后对程序的状态进行太多假设(有关更多详细信息,请参见示例)。你也可能想加强你的不变量在代码< > <代码>中间的循环作为代码>差距如何构造不变量和要考虑什么?我不明白,请帮忙。关于如何构造不变量,没有一般的规则,当然也没有什么可以符合SO注释的格式。非常广泛地说,您必须回答这样的问题:“循环的每个步骤如何有助于朝最终目标(即函数的后条件)前进?”对于外部循环,这确实是GapSorted(arr,0,n,gap+1)。对于中间的循环,所有到 >  <代码> GAP - GAPSORID似乎也是合理的。但是,对于内部循环,这是不正确的,因为您正在将旧的
arr[i]
移动到其适当的位置。。。。。。因此,除了GapSorted谓词本身之外,您还需要一个不变量来指示
tmp
小于
arr[j]
,这可能比以前稍微复杂一些,因为当进入循环时,您没有
GapSorted(arr,0,i,gap)
,但只有
GapSorted(arr,0,i-1,gap)
(在循环一步后,前一步变为现实)。请注意,这些解释是基于对您的代码的广泛概述,并且我没有尝试任何进一步的证明。如果您仍然有一些问题,请随时提出新的问题。